|
@@ -0,0 +1,151 @@
|
|
|
|
|
+// 商户端 PC Web — 参数化流水线(预生产 / 生产)
|
|
|
|
|
+// 仓库: http://8.152.195.41:3000/alien/group_web_merchant.git
|
|
|
|
|
+// NPM 构建在 Docker node:20-alpine 中执行,无需本机安装 Node
|
|
|
|
|
+// 部署:构建完成后通过 SCP 传到目标 ECS 静态目录(非 Jenkins 容器内 cp)
|
|
|
|
|
+//
|
|
|
|
|
+// 构建前选择 DEPLOY_ENV:
|
|
|
|
|
+// uat -> build:uat -> ${DEPLOY_HOST}:/web_deploy_uat/group_web_merchant
|
|
|
|
|
+// pro -> build:pro -> ${DEPLOY_HOST}:/web_deploy_produ/group_web_merchant
|
|
|
|
|
+//
|
|
|
|
|
+// Jenkins 需预先配置「SSH Username with private key」凭据,ID 见下方 SSH_CREDENTIALS_ID。
|
|
|
|
|
+
|
|
|
|
|
+pipeline {
|
|
|
|
|
+ agent any
|
|
|
|
|
+
|
|
|
|
|
+ parameters {
|
|
|
|
|
+ choice(
|
|
|
|
|
+ name: 'DEPLOY_ENV',
|
|
|
|
|
+ choices: ['uat', 'pro'],
|
|
|
|
|
+ description: 'uat=预生产,pro=生产'
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ options {
|
|
|
|
|
+ buildDiscarder(logRotator(numToKeepStr: '2', artifactNumToKeepStr: '2'))
|
|
|
|
|
+ timestamps()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ environment {
|
|
|
|
|
+ PATH = "${env.PATH}"
|
|
|
|
|
+ // Jenkins 中 SSH 部署凭据 ID(类型:SSH Username with private key)
|
|
|
|
|
+ SSH_CREDENTIALS_ID = 'ssh-deploy'
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ stages {
|
|
|
|
|
+ stage('确认构建环境') {
|
|
|
|
|
+ steps {
|
|
|
|
|
+ script {
|
|
|
|
|
+ if (params.DEPLOY_ENV == 'uat') {
|
|
|
|
|
+ env.BUILD_SCRIPT = 'build:uat'
|
|
|
|
|
+ env.DEPLOY_DEST = '/web_deploy_uat/group_web_merchant'
|
|
|
|
|
+ env.DEPLOY_HOST = '39.106.135.88'
|
|
|
|
|
+ env.DEPLOY_ENV_LABEL = '预生产(UAT)'
|
|
|
|
|
+ } else if (params.DEPLOY_ENV == 'pro') {
|
|
|
|
|
+ env.BUILD_SCRIPT = 'build:pro'
|
|
|
|
|
+ env.DEPLOY_DEST = '/web_deploy_produ/group_web_merchant'
|
|
|
|
|
+ env.DEPLOY_HOST = '39.106.135.88'
|
|
|
|
|
+ env.DEPLOY_ENV_LABEL = '生产(PRO)'
|
|
|
|
|
+ } else {
|
|
|
|
|
+ error("未知 DEPLOY_ENV: ${params.DEPLOY_ENV}")
|
|
|
|
|
+ }
|
|
|
|
|
+ echo '========================================'
|
|
|
|
|
+ echo ">>> 【流水线开始】本次构建环境: ${env.DEPLOY_ENV_LABEL}"
|
|
|
|
|
+ echo ">>> BUILD_SCRIPT=${env.BUILD_SCRIPT}"
|
|
|
|
|
+ echo ">>> SCP 目标: ${env.DEPLOY_HOST}:${env.DEPLOY_DEST}"
|
|
|
|
|
+ echo '========================================'
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ stage('Checkout') {
|
|
|
|
|
+ steps {
|
|
|
|
|
+ echo ">>> 正在拉取 group_web_merchant 代码..."
|
|
|
|
|
+ git branch: 'uat',
|
|
|
|
|
+ credentialsId: 'zhanghaomimapingzheng',
|
|
|
|
|
+ url: 'http://8.152.195.41:3000/alien/group_web_merchant.git'
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ stage('NPM Build') {
|
|
|
|
|
+ agent {
|
|
|
|
|
+ docker {
|
|
|
|
|
+ image 'node:20-alpine'
|
|
|
|
|
+ reuseNode true
|
|
|
|
|
+ // 若 workspace 属主与容器内用户不一致导致写权限问题,可临时用 root(按你们安全策略决定)
|
|
|
|
|
+ // args '-u root:root'
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ options {
|
|
|
|
|
+ timeout(time: 20, unit: 'MINUTES')
|
|
|
|
|
+ }
|
|
|
|
|
+ steps {
|
|
|
|
|
+ echo ">>> 安装依赖并构建(BUILD_SCRIPT=${env.BUILD_SCRIPT})..."
|
|
|
|
|
+ sh """
|
|
|
|
|
+ set -e
|
|
|
|
|
+ node -v
|
|
|
|
|
+ npm -v
|
|
|
|
|
+ npm config set registry https://registry.npmmirror.com
|
|
|
|
|
+ export CI=true
|
|
|
|
|
+ export HUSKY=0
|
|
|
|
|
+ export NODE_OPTIONS="--max-old-space-size=2048"
|
|
|
|
|
+ npm install --no-audit
|
|
|
|
|
+ npm run ${env.BUILD_SCRIPT}
|
|
|
|
|
+ test -d dist && test -f dist/index.html
|
|
|
|
|
+ echo ">>> 构建产物: \${WORKSPACE}/dist"
|
|
|
|
|
+ """
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ stage('Deploy') {
|
|
|
|
|
+ steps {
|
|
|
|
|
+ echo ">>> SCP 部署到 ${env.DEPLOY_ENV_LABEL}: \${SSH_USER}@${env.DEPLOY_HOST}:${env.DEPLOY_DEST}"
|
|
|
|
|
+ script {
|
|
|
|
|
+ def allowedDest = [
|
|
|
|
|
+ '/web_deploy_uat/group_web_merchant',
|
|
|
|
|
+ '/web_deploy_produ/group_web_merchant'
|
|
|
|
|
+ ]
|
|
|
|
|
+ if (!allowedDest.contains(env.DEPLOY_DEST)) {
|
|
|
|
|
+ error("拒绝部署:DEPLOY_DEST 不在白名单内: ${env.DEPLOY_DEST}")
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!env.DEPLOY_HOST?.trim()) {
|
|
|
|
|
+ error('拒绝部署:DEPLOY_HOST 未设置')
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ withCredentials([
|
|
|
|
|
+ sshUserPrivateKey(
|
|
|
|
|
+ credentialsId: "${env.SSH_CREDENTIALS_ID}",
|
|
|
|
|
+ keyFileVariable: 'SSH_KEY',
|
|
|
|
|
+ usernameVariable: 'SSH_USER'
|
|
|
|
|
+ )
|
|
|
|
|
+ ]) {
|
|
|
|
|
+ sh """
|
|
|
|
|
+ set -e
|
|
|
|
|
+ DEST="${env.DEPLOY_DEST}"
|
|
|
|
|
+ HOST="${env.DEPLOY_HOST}"
|
|
|
|
|
+ case "\${DEST}" in
|
|
|
|
|
+ /web_deploy_uat/group_web_merchant|/web_deploy_produ/group_web_merchant) ;;
|
|
|
|
|
+ *) echo "拒绝部署:非法 DEST=[\${DEST}]"; exit 1 ;;
|
|
|
|
|
+ esac
|
|
|
|
|
+ SSH_OPTS="-i \${SSH_KEY} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes"
|
|
|
|
|
+ echo ">>> 远程清空目录: \${SSH_USER}@\${HOST}:\${DEST}"
|
|
|
|
|
+ ssh \${SSH_OPTS} "\${SSH_USER}@\${HOST}" "mkdir -p \${DEST} && rm -rf \${DEST}/*"
|
|
|
|
|
+ echo ">>> 上传 dist/* ..."
|
|
|
|
|
+ scp \${SSH_OPTS} -r dist/* "\${SSH_USER}@\${HOST}:\${DEST}/"
|
|
|
|
|
+ echo ">>> group_web_merchant 部署完成: \${SSH_USER}@\${HOST}:\${DEST}"
|
|
|
|
|
+ """
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ post {
|
|
|
|
|
+ always {
|
|
|
|
|
+ echo '========================================'
|
|
|
|
|
+ echo ">>> 【流水线结束】构建任务结束"
|
|
|
|
|
+ echo ">>> 环境: ${env.DEPLOY_ENV_LABEL ?: '(未执行确认阶段或变量未设置)'}"
|
|
|
|
|
+ echo ">>> BUILD_SCRIPT=${env.BUILD_SCRIPT ?: '(无)'}"
|
|
|
|
|
+ echo ">>> SCP 目标: ${env.DEPLOY_HOST ?: '(无)'}:${env.DEPLOY_DEST ?: '(无)'}"
|
|
|
|
|
+ echo '========================================'
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|