| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- // 商户端 PC Web — 参数化流水线(预生产 / 生产)
- // 仓库: http://8.152.195.41:3000/alien/group_web_merchant.git
- // NPM 构建在 Docker node:20-alpine 中执行,无需本机安装 Node
- // 部署方式(默认 local):
- // local — Jenkins 容器内已挂载 /web_deploy_* 时,直接 cp(无需 SSH 凭据)
- // scp — Jenkins 与目标机分离时,需配置 SSH Username with private key 凭据
- //
- // Jenkins 需预先配置「SSH Username with private key」凭据,ID 见参数 SSH_CREDENTIALS_ID(仅 scp 模式)。
- pipeline {
- agent any
- parameters {
- choice(
- name: 'DEPLOY_ENV',
- choices: ['uat', 'pro'],
- description: 'uat=预生产,pro=生产'
- )
- choice(
- name: 'DEPLOY_MODE',
- choices: ['local', 'scp'],
- description: 'local=容器内 cp 到 /web_deploy_*(同机挂载,推荐);scp=SSH 传到远程 ECS'
- )
- // 仅 DEPLOY_MODE=scp 时需要;Jenkins → 凭据 → SSH Username with private key
- string(
- name: 'SSH_CREDENTIALS_ID',
- defaultValue: 'ssh-deploy',
- description: 'SCP/SSH 部署凭据 ID(类型须为 SSH Username with private key)'
- )
- }
- options {
- buildDiscarder(logRotator(numToKeepStr: '2', artifactNumToKeepStr: '2'))
- timestamps()
- }
- environment {
- PATH = "${env.PATH}"
- }
- 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 ">>> 部署方式: ${params.DEPLOY_MODE}"
- echo ">>> 目标: ${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 ">>> 部署到 ${env.DEPLOY_ENV_LABEL}(${params.DEPLOY_MODE}): ${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 (params.DEPLOY_MODE == 'scp') {
- if (!env.DEPLOY_HOST?.trim()) {
- error('拒绝部署:scp 模式需要 DEPLOY_HOST')
- }
- def credId = params.SSH_CREDENTIALS_ID?.trim()
- if (!credId) {
- error('拒绝部署:scp 模式请在构建参数中填写 SSH_CREDENTIALS_ID')
- }
- echo ">>> scp 模式,凭据: ${credId},目标: ${env.DEPLOY_HOST}:${env.DEPLOY_DEST}"
- } else {
- echo '>>> local 模式:容器内 cp 到挂载目录(无需 SSH 凭据)'
- }
- }
- script {
- if (params.DEPLOY_MODE == 'local') {
- sh """
- set -e
- DEST="${env.DEPLOY_DEST}"
- case "\${DEST}" in
- /web_deploy_uat/group_web_merchant|/web_deploy_produ/group_web_merchant) ;;
- *) echo "拒绝部署:非法 DEST=[\${DEST}]"; exit 1 ;;
- esac
- test -d dist && test -f dist/index.html
- mkdir -p "\${DEST}"
- rm -rf "\${DEST}"/*
- cp -r dist/* "\${DEST}/"
- test -f "\${DEST}/index.html"
- echo ">>> group_web_merchant 部署完成: \${DEST}"
- """
- } else {
- withCredentials([
- sshUserPrivateKey(
- credentialsId: "${params.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 ">>> 目标: ${env.DEPLOY_DEST ?: '(无)'}"
- echo '========================================'
- }
- }
- }
|