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

149 lines
6.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'
}
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 全局环境变量 GENARRATIVE_NOTIFICATION_EMAILS 合并发送')
string(name: 'BUILD_VERSION', defaultValue: '', description: '待发布版本号')
string(name: 'BUILD_JOB_NAME', defaultValue: 'Genarrative-Api-Build', description: 'API 构建流水线作业名')
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: 'SERVICE_NAME', defaultValue: 'genarrative-api.service', description: 'systemd 服务名')
string(name: 'HEALTH_URL', defaultValue: 'http://127.0.0.1:8082/healthz', description: '本机健康检查地址')
}
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}/api-server,build/${params.BUILD_VERSION}/api-server.sha256,build/${params.BUILD_VERSION}/release-manifest.json",
target: '.',
fingerprintArtifacts: true
)
}
}
stage('Deploy Api') {
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-api-deploy.sh scripts/deploy/maintenance-on.sh scripts/deploy/maintenance-off.sh
scripts/deploy/production-api-deploy.sh \
--source-dir "build/${BUILD_VERSION}" \
--version "${BUILD_VERSION}" \
--release-root "${RELEASE_ROOT}" \
--current-link "${CURRENT_LINK}" \
--service "${SERVICE_NAME}" \
--health-url "${HEALTH_URL}"
'
'''
}
}
}
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: 'API 发布流水线结束'),
]
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 "API 发布完成: version=${params.BUILD_VERSION}"
}
}
}