Jenkinsfile 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // 商户端 PC Web — 参数化流水线(预生产 / 生产)
  2. // 仓库: http://8.152.195.41:3000/alien/group_web_merchant.git
  3. // NPM 构建在 Docker node:20-alpine 中执行,无需本机安装 Node
  4. // 部署:构建完成后通过 SCP 传到目标 ECS 静态目录(非 Jenkins 容器内 cp)
  5. //
  6. // 构建前选择 DEPLOY_ENV:
  7. // uat -> build:uat -> ${DEPLOY_HOST}:/web_deploy_uat/group_web_merchant
  8. // pro -> build:pro -> ${DEPLOY_HOST}:/web_deploy_produ/group_web_merchant
  9. //
  10. // Jenkins 需预先配置「SSH Username with private key」凭据,ID 见下方 SSH_CREDENTIALS_ID。
  11. pipeline {
  12. agent any
  13. parameters {
  14. choice(
  15. name: 'DEPLOY_ENV',
  16. choices: ['uat', 'pro'],
  17. description: 'uat=预生产,pro=生产'
  18. )
  19. }
  20. options {
  21. buildDiscarder(logRotator(numToKeepStr: '2', artifactNumToKeepStr: '2'))
  22. timestamps()
  23. }
  24. environment {
  25. PATH = "${env.PATH}"
  26. // Jenkins 中 SSH 部署凭据 ID(类型:SSH Username with private key)
  27. SSH_CREDENTIALS_ID = 'ssh-deploy'
  28. }
  29. stages {
  30. stage('确认构建环境') {
  31. steps {
  32. script {
  33. if (params.DEPLOY_ENV == 'uat') {
  34. env.BUILD_SCRIPT = 'build:uat'
  35. env.DEPLOY_DEST = '/web_deploy_uat/group_web_merchant'
  36. env.DEPLOY_HOST = '39.106.135.88'
  37. env.DEPLOY_ENV_LABEL = '预生产(UAT)'
  38. } else if (params.DEPLOY_ENV == 'pro') {
  39. env.BUILD_SCRIPT = 'build:pro'
  40. env.DEPLOY_DEST = '/web_deploy_produ/group_web_merchant'
  41. env.DEPLOY_HOST = '39.106.135.88'
  42. env.DEPLOY_ENV_LABEL = '生产(PRO)'
  43. } else {
  44. error("未知 DEPLOY_ENV: ${params.DEPLOY_ENV}")
  45. }
  46. echo '========================================'
  47. echo ">>> 【流水线开始】本次构建环境: ${env.DEPLOY_ENV_LABEL}"
  48. echo ">>> BUILD_SCRIPT=${env.BUILD_SCRIPT}"
  49. echo ">>> SCP 目标: ${env.DEPLOY_HOST}:${env.DEPLOY_DEST}"
  50. echo '========================================'
  51. }
  52. }
  53. }
  54. stage('Checkout') {
  55. steps {
  56. echo ">>> 正在拉取 group_web_merchant 代码..."
  57. git branch: 'uat',
  58. credentialsId: 'zhanghaomimapingzheng',
  59. url: 'http://8.152.195.41:3000/alien/group_web_merchant.git'
  60. }
  61. }
  62. stage('NPM Build') {
  63. agent {
  64. docker {
  65. image 'node:20-alpine'
  66. reuseNode true
  67. // 若 workspace 属主与容器内用户不一致导致写权限问题,可临时用 root(按你们安全策略决定)
  68. // args '-u root:root'
  69. }
  70. }
  71. options {
  72. timeout(time: 20, unit: 'MINUTES')
  73. }
  74. steps {
  75. echo ">>> 安装依赖并构建(BUILD_SCRIPT=${env.BUILD_SCRIPT})..."
  76. sh """
  77. set -e
  78. node -v
  79. npm -v
  80. npm config set registry https://registry.npmmirror.com
  81. export CI=true
  82. export HUSKY=0
  83. export NODE_OPTIONS="--max-old-space-size=2048"
  84. npm install --no-audit
  85. npm run ${env.BUILD_SCRIPT}
  86. test -d dist && test -f dist/index.html
  87. echo ">>> 构建产物: \${WORKSPACE}/dist"
  88. """
  89. }
  90. }
  91. stage('Deploy') {
  92. steps {
  93. echo ">>> SCP 部署到 ${env.DEPLOY_ENV_LABEL}: \${SSH_USER}@${env.DEPLOY_HOST}:${env.DEPLOY_DEST}"
  94. script {
  95. def allowedDest = [
  96. '/web_deploy_uat/group_web_merchant',
  97. '/web_deploy_produ/group_web_merchant'
  98. ]
  99. if (!allowedDest.contains(env.DEPLOY_DEST)) {
  100. error("拒绝部署:DEPLOY_DEST 不在白名单内: ${env.DEPLOY_DEST}")
  101. }
  102. if (!env.DEPLOY_HOST?.trim()) {
  103. error('拒绝部署:DEPLOY_HOST 未设置')
  104. }
  105. }
  106. withCredentials([
  107. sshUserPrivateKey(
  108. credentialsId: "${env.SSH_CREDENTIALS_ID}",
  109. keyFileVariable: 'SSH_KEY',
  110. usernameVariable: 'SSH_USER'
  111. )
  112. ]) {
  113. sh """
  114. set -e
  115. DEST="${env.DEPLOY_DEST}"
  116. HOST="${env.DEPLOY_HOST}"
  117. case "\${DEST}" in
  118. /web_deploy_uat/group_web_merchant|/web_deploy_produ/group_web_merchant) ;;
  119. *) echo "拒绝部署:非法 DEST=[\${DEST}]"; exit 1 ;;
  120. esac
  121. SSH_OPTS="-i \${SSH_KEY} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes"
  122. echo ">>> 远程清空目录: \${SSH_USER}@\${HOST}:\${DEST}"
  123. ssh \${SSH_OPTS} "\${SSH_USER}@\${HOST}" "mkdir -p \${DEST} && rm -rf \${DEST}/*"
  124. echo ">>> 上传 dist/* ..."
  125. scp \${SSH_OPTS} -r dist/* "\${SSH_USER}@\${HOST}:\${DEST}/"
  126. echo ">>> group_web_merchant 部署完成: \${SSH_USER}@\${HOST}:\${DEST}"
  127. """
  128. }
  129. }
  130. }
  131. }
  132. post {
  133. always {
  134. echo '========================================'
  135. echo ">>> 【流水线结束】构建任务结束"
  136. echo ">>> 环境: ${env.DEPLOY_ENV_LABEL ?: '(未执行确认阶段或变量未设置)'}"
  137. echo ">>> BUILD_SCRIPT=${env.BUILD_SCRIPT ?: '(无)'}"
  138. echo ">>> SCP 目标: ${env.DEPLOY_HOST ?: '(无)'}:${env.DEPLOY_DEST ?: '(无)'}"
  139. echo '========================================'
  140. }
  141. }
  142. }