184 lines
8.0 KiB
Plaintext
184 lines
8.0 KiB
Plaintext
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'
|
||
GIT_REMOTE_FALLBACK_URL = 'https://git.genarrative.world/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 {
|
||
script {
|
||
def checkoutFromRemote = { String remoteUrl ->
|
||
checkout([
|
||
$class: 'GitSCM',
|
||
branches: [[name: "*/${params.SOURCE_BRANCH}"]],
|
||
doGenerateSubmoduleConfigurations: false,
|
||
extensions: [[$class: 'CleanBeforeCheckout']],
|
||
userRemoteConfigs: [[url: remoteUrl]],
|
||
])
|
||
}
|
||
try {
|
||
checkoutFromRemote(env.GIT_REMOTE_URL)
|
||
env.EFFECTIVE_GIT_REMOTE_URL = env.GIT_REMOTE_URL
|
||
} catch (error) {
|
||
echo "Git 主地址拉取失败: ${env.GIT_REMOTE_URL},改用备用地址: ${env.GIT_REMOTE_FALLBACK_URL}"
|
||
checkoutFromRemote(env.GIT_REMOTE_FALLBACK_URL)
|
||
env.EFFECTIVE_GIT_REMOTE_URL = env.GIT_REMOTE_FALLBACK_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="${EFFECTIVE_GIT_REMOTE_URL:-${GIT_REMOTE_URL}}" \
|
||
GIT_REMOTE_FALLBACK_URL="${GIT_REMOTE_FALLBACK_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}"
|
||
}
|
||
}
|
||
}
|