Files
Genarrative/jenkins/Jenkinsfile.production-web-deploy

170 lines
7.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
pipeline {
agent none
options {
disableConcurrentBuilds()
skipDefaultCheckout(true)
buildDiscarder(logRotator(numToKeepStr: '20', artifactNumToKeepStr: '20'))
}
environment {
GIT_REMOTE_URL = 'http://127.0.0.1:3000/GenarrativeAI/Genarrative.git'
WEB_ARTIFACT_ROOT = '/var/cache/genarrative-build/web-artifacts'
}
parameters {
choice(name: 'DEPLOY_TARGET', choices: ['development', 'release'], description: '逻辑部署目标development 使用当前 Linux 开发/构建/开发部署 agent')
booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', defaultValue: false, description: '确认 release 目标已有独立 release 部署 agent当前 Linux 开发/构建/开发部署 agent 不可冒充 release 部署机')
string(name: 'SOURCE_BRANCH', defaultValue: 'master', description: '部署脚本来源分支')
string(name: 'COMMIT_HASH', defaultValue: '', description: '部署脚本来源 commit上游触发时传实际构建 commit')
string(name: 'NOTIFICATION_EMAILS', defaultValue: '', description: '本次运行追加通知邮箱;会与 Jenkins Secret Text 凭据 genarrative-notification-emails 合并发送')
string(name: 'BUILD_VERSION', defaultValue: '', description: '待发布版本号')
string(name: 'BUILD_JOB_NAME', defaultValue: 'Genarrative-Web-Build', description: 'Web 构建流水线作业名')
string(name: 'BUILD_NUMBER_TO_DEPLOY', defaultValue: '', description: '要复制归档产物的上游构建号')
string(name: 'RELEASE_ROOT', defaultValue: '/opt/genarrative/releases', description: '生产 release 根目录')
string(name: 'CURRENT_LINK', defaultValue: '/opt/genarrative/current', description: '当前版本软链接')
string(name: 'WEB_LINK', defaultValue: '/srv/genarrative/web', description: 'Nginx 静态站点软链接')
}
stages {
stage('Prepare') {
agent {
label 'linux && genarrative-build'
}
steps {
script {
if (params.DEPLOY_TARGET == 'release' && !params.CONFIRM_RELEASE_DEPLOY_AGENT) {
error('release 部署需要先配置独立 release 部署 agent并勾选 CONFIRM_RELEASE_DEPLOY_AGENT。当前 Linux 开发/构建/开发部署 agent 不能执行 release 部署。')
}
if (!params.BUILD_VERSION?.trim()) {
error('BUILD_VERSION 不能为空。')
}
if (!params.BUILD_JOB_NAME?.trim()) {
error('BUILD_JOB_NAME 不能为空。')
}
if (!params.BUILD_NUMBER_TO_DEPLOY?.trim()) {
error('BUILD_NUMBER_TO_DEPLOY 不能为空。')
}
}
}
}
stage('Checkout Deploy Scripts') {
agent {
label "${params.DEPLOY_TARGET == 'development' ? 'linux && genarrative-build' : 'linux && genarrative-release-deploy'}"
}
steps {
checkout([
$class: 'GitSCM',
branches: [[name: "*/${params.SOURCE_BRANCH}"]],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'CleanBeforeCheckout']],
userRemoteConfigs: [[url: "${GIT_REMOTE_URL}"]],
])
sh '''
bash -lc '
set -euo pipefail
chmod +x scripts/jenkins-checkout-source.sh
SOURCE_BRANCH="${SOURCE_BRANCH:-master}" \
COMMIT_HASH="${COMMIT_HASH:-}" \
GIT_REMOTE_URL="${GIT_REMOTE_URL}" \
SOURCE_COMMIT_FILE=".jenkins-source-commit" \
scripts/jenkins-checkout-source.sh
'
'''
}
}
stage('Fetch Artifact') {
agent {
label "${params.DEPLOY_TARGET == 'development' ? 'linux && genarrative-build' : 'linux && genarrative-release-deploy'}"
}
steps {
copyArtifacts(
projectName: params.BUILD_JOB_NAME,
selector: specific(params.BUILD_NUMBER_TO_DEPLOY),
filter: "build/${params.BUILD_VERSION}/web.tar.gz.sha256,build/${params.BUILD_VERSION}/release-manifest.json,build/${params.BUILD_VERSION}/web-artifact-pointer.txt",
target: '.',
fingerprintArtifacts: true
)
sh '''
bash -lc '
set -euo pipefail
artifact_dir="${WEB_ARTIFACT_ROOT}/${BUILD_JOB_NAME}/${BUILD_NUMBER_TO_DEPLOY}/${BUILD_VERSION}"
if [[ ! -f "${artifact_dir}/web.tar.gz" ]]; then
echo "[web-deploy] 未找到构建机本地 Web 大包: ${artifact_dir}/web.tar.gz" >&2
echo "[web-deploy] development 目标要求 Web 构建与发布共享同一 Linux 构建/开发部署机release 目标需要预先同步或挂载 ${WEB_ARTIFACT_ROOT}。" >&2
exit 1
fi
mkdir -p "build/${BUILD_VERSION}"
cp -f "${artifact_dir}/web.tar.gz" "build/${BUILD_VERSION}/web.tar.gz"
if [[ -f "${artifact_dir}/web.tar.gz.sha256" ]]; then
cp -f "${artifact_dir}/web.tar.gz.sha256" "build/${BUILD_VERSION}/web.tar.gz.sha256"
fi
if [[ -f "${artifact_dir}/release-manifest.json" ]]; then
cp -f "${artifact_dir}/release-manifest.json" "build/${BUILD_VERSION}/release-manifest.json"
fi
echo "[web-deploy] 已从构建机本地目录获取 Web 大包: ${artifact_dir}"
'
'''
}
}
stage('Deploy Web') {
agent {
label "${params.DEPLOY_TARGET == 'development' ? 'linux && genarrative-build' : 'linux && genarrative-release-deploy'}"
}
steps {
sh '''
bash -lc '
set -euo pipefail
chmod +x scripts/deploy/production-web-deploy.sh
scripts/deploy/production-web-deploy.sh \
--source-dir "build/${BUILD_VERSION}" \
--version "${BUILD_VERSION}" \
--release-root "${RELEASE_ROOT}" \
--current-link "${CURRENT_LINK}" \
--web-link "${WEB_LINK}"
'
'''
}
}
}
post {
always {
script {
def notificationParameters = [
string(name: 'SOURCE_JOB_NAME', value: env.JOB_NAME),
string(name: 'SOURCE_BUILD_NUMBER', value: env.BUILD_NUMBER),
string(name: 'SOURCE_BUILD_URL', value: env.BUILD_URL ?: ''),
string(name: 'SOURCE_RESULT', value: currentBuild.currentResult ?: 'UNKNOWN'),
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH ?: ''),
string(name: 'SOURCE_COMMIT', value: env.SOURCE_COMMIT ?: (params.COMMIT_HASH ?: '')),
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION ?: (params.BUILD_VERSION ?: '')),
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET ?: ''),
string(name: 'DATABASE', value: params.DATABASE ?: ''),
string(name: 'SUMMARY', value: 'Web 发布流水线结束'),
]
def notificationRecipients = params.NOTIFICATION_EMAILS?.trim()
if (notificationRecipients) {
notificationParameters.add(string(name: 'EMAIL_RECIPIENTS', value: notificationRecipients))
}
try {
build job: 'Genarrative-Notify-Email',
wait: false,
propagate: false,
parameters: notificationParameters
} catch (error) {
echo "邮件通知触发失败: ${error.message}"
}
}
}
success {
echo "Web 发布完成: version=${params.BUILD_VERSION}"
}
}
}