|
@@ -1,13 +1,11 @@
|
|
|
// 商户端 PC Web — 参数化流水线(预生产 / 生产)
|
|
// 商户端 PC Web — 参数化流水线(预生产 / 生产)
|
|
|
// 仓库: http://8.152.195.41:3000/alien/group_web_merchant.git
|
|
// 仓库: http://8.152.195.41:3000/alien/group_web_merchant.git
|
|
|
// NPM 构建在 Docker node:20-alpine 中执行,无需本机安装 Node
|
|
// NPM 构建在 Docker node:20-alpine 中执行,无需本机安装 Node
|
|
|
-// 部署:构建完成后通过 SCP 传到目标 ECS 静态目录(非 Jenkins 容器内 cp)
|
|
|
|
|
|
|
+// 部署方式(默认 local):
|
|
|
|
|
+// local — Jenkins 容器内已挂载 /web_deploy_* 时,直接 cp(无需 SSH 凭据)
|
|
|
|
|
+// scp — Jenkins 与目标机分离时,需配置 SSH Username with private key 凭据
|
|
|
//
|
|
//
|
|
|
-// 构建前选择 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。
|
|
|
|
|
|
|
+// Jenkins 需预先配置「SSH Username with private key」凭据,ID 见参数 SSH_CREDENTIALS_ID(仅 scp 模式)。
|
|
|
|
|
|
|
|
pipeline {
|
|
pipeline {
|
|
|
agent any
|
|
agent any
|
|
@@ -18,6 +16,17 @@ pipeline {
|
|
|
choices: ['uat', 'pro'],
|
|
choices: ['uat', 'pro'],
|
|
|
description: '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 {
|
|
options {
|
|
@@ -27,8 +36,6 @@ pipeline {
|
|
|
|
|
|
|
|
environment {
|
|
environment {
|
|
|
PATH = "${env.PATH}"
|
|
PATH = "${env.PATH}"
|
|
|
- // Jenkins 中 SSH 部署凭据 ID(类型:SSH Username with private key)
|
|
|
|
|
- SSH_CREDENTIALS_ID = 'ssh-deploy'
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
stages {
|
|
stages {
|
|
@@ -51,7 +58,8 @@ pipeline {
|
|
|
echo '========================================'
|
|
echo '========================================'
|
|
|
echo ">>> 【流水线开始】本次构建环境: ${env.DEPLOY_ENV_LABEL}"
|
|
echo ">>> 【流水线开始】本次构建环境: ${env.DEPLOY_ENV_LABEL}"
|
|
|
echo ">>> BUILD_SCRIPT=${env.BUILD_SCRIPT}"
|
|
echo ">>> BUILD_SCRIPT=${env.BUILD_SCRIPT}"
|
|
|
- echo ">>> SCP 目标: ${env.DEPLOY_HOST}:${env.DEPLOY_DEST}"
|
|
|
|
|
|
|
+ echo ">>> 部署方式: ${params.DEPLOY_MODE}"
|
|
|
|
|
+ echo ">>> 目标: ${env.DEPLOY_DEST}"
|
|
|
echo '========================================'
|
|
echo '========================================'
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -98,7 +106,7 @@ pipeline {
|
|
|
|
|
|
|
|
stage('Deploy') {
|
|
stage('Deploy') {
|
|
|
steps {
|
|
steps {
|
|
|
- echo ">>> SCP 部署到 ${env.DEPLOY_ENV_LABEL}: \${SSH_USER}@${env.DEPLOY_HOST}:${env.DEPLOY_DEST}"
|
|
|
|
|
|
|
+ echo ">>> 部署到 ${env.DEPLOY_ENV_LABEL}(${params.DEPLOY_MODE}): ${env.DEPLOY_DEST}"
|
|
|
script {
|
|
script {
|
|
|
def allowedDest = [
|
|
def allowedDest = [
|
|
|
'/web_deploy_uat/group_web_merchant',
|
|
'/web_deploy_uat/group_web_merchant',
|
|
@@ -107,32 +115,60 @@ pipeline {
|
|
|
if (!allowedDest.contains(env.DEPLOY_DEST)) {
|
|
if (!allowedDest.contains(env.DEPLOY_DEST)) {
|
|
|
error("拒绝部署:DEPLOY_DEST 不在白名单内: ${env.DEPLOY_DEST}")
|
|
error("拒绝部署:DEPLOY_DEST 不在白名单内: ${env.DEPLOY_DEST}")
|
|
|
}
|
|
}
|
|
|
- if (!env.DEPLOY_HOST?.trim()) {
|
|
|
|
|
- error('拒绝部署:DEPLOY_HOST 未设置')
|
|
|
|
|
|
|
+ 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 凭据)'
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- 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}"
|
|
|
|
|
- """
|
|
|
|
|
|
|
+ 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}"
|
|
|
|
|
+ """
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -144,7 +180,7 @@ pipeline {
|
|
|
echo ">>> 【流水线结束】构建任务结束"
|
|
echo ">>> 【流水线结束】构建任务结束"
|
|
|
echo ">>> 环境: ${env.DEPLOY_ENV_LABEL ?: '(未执行确认阶段或变量未设置)'}"
|
|
echo ">>> 环境: ${env.DEPLOY_ENV_LABEL ?: '(未执行确认阶段或变量未设置)'}"
|
|
|
echo ">>> BUILD_SCRIPT=${env.BUILD_SCRIPT ?: '(无)'}"
|
|
echo ">>> BUILD_SCRIPT=${env.BUILD_SCRIPT ?: '(无)'}"
|
|
|
- echo ">>> SCP 目标: ${env.DEPLOY_HOST ?: '(无)'}:${env.DEPLOY_DEST ?: '(无)'}"
|
|
|
|
|
|
|
+ echo ">>> 目标: ${env.DEPLOY_DEST ?: '(无)'}"
|
|
|
echo '========================================'
|
|
echo '========================================'
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|