pipeline { agent { label 'linux && genarrative-build' } options { disableConcurrentBuilds() skipDefaultCheckout(true) buildDiscarder(logRotator(numToKeepStr: '20', artifactNumToKeepStr: '20')) } environment { GIT_REMOTE_URL = 'http://82.157.175.59:3000/GenarrativeAI/Genarrative.git' WEB_ARTIFACT_ROOT = '/var/cache/genarrative-build/web-artifacts' } parameters { string(name: 'SOURCE_BRANCH', defaultValue: 'master', description: '源码分支,默认 master 最新提交') string(name: 'COMMIT_HASH', defaultValue: '', description: '可选,指定属于 SOURCE_BRANCH 的 Git commit') string(name: 'BUILD_VERSION', defaultValue: '', description: '发布版本号,留空则使用 Jenkins BUILD_NUMBER') string(name: 'NOTIFICATION_EMAILS', defaultValue: '', description: '本次运行追加通知邮箱;会与 Jenkins Secret Text 凭据 genarrative-notification-emails 合并发送') booleanParam(name: 'RUN_NPM_CI', defaultValue: true, description: '构建前是否执行 npm ci') booleanParam(name: 'PUBLISH_AFTER_BUILD', defaultValue: false, description: '构建成功后是否触发 Web 发布') string(name: 'DEPLOY_JOB_NAME', defaultValue: 'Genarrative-Web-Deploy', description: 'Web 发布流水线作业名') choice(name: 'DEPLOY_TARGET', choices: ['development', 'release'], description: 'PUBLISH_AFTER_BUILD=true 时的逻辑部署目标;development 使用当前 Linux 开发/构建/开发部署 agent') booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', defaultValue: false, description: 'PUBLISH_AFTER_BUILD=true 且目标为 release 时必须确认已有独立 release 部署 agent') } stages { stage('Checkout') { steps { checkout([ $class: 'GitSCM', branches: [[name: "*/${params.SOURCE_BRANCH}"]], doGenerateSubmoduleConfigurations: false, extensions: [ [$class: 'CleanBeforeCheckout'], [$class: 'CloneOption', shallow: true, depth: 1, noTags: true, timeout: 30], ], 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 ' ''' script { env.SOURCE_COMMIT = readFile('.jenkins-source-commit').trim() env.EFFECTIVE_BUILD_VERSION = params.BUILD_VERSION?.trim() ? params.BUILD_VERSION.trim() : env.BUILD_NUMBER } } } stage('Build Web') { steps { script { if (params.RUN_NPM_CI) { sh 'bash -lc "npm ci"' } } sh ''' bash -lc ' set -euo pipefail SOURCE_BRANCH="${SOURCE_BRANCH}" SOURCE_COMMIT="${SOURCE_COMMIT}" \ npm run build:production-release -- --component web --name "${EFFECTIVE_BUILD_VERSION}" ' ''' } } stage('Archive') { steps { sh ''' bash -lc ' set -euo pipefail artifact_dir="${WEB_ARTIFACT_ROOT}/${JOB_NAME}/${BUILD_NUMBER}/${EFFECTIVE_BUILD_VERSION}" mkdir -p "${artifact_dir}" rm -f "${artifact_dir}/web.tar.gz" "${artifact_dir}/web.tar.gz.sha256" "${artifact_dir}/release-manifest.json" install -m 0644 "build/${EFFECTIVE_BUILD_VERSION}/web.tar.gz" "${artifact_dir}/web.tar.gz" install -m 0644 "build/${EFFECTIVE_BUILD_VERSION}/web.tar.gz.sha256" "${artifact_dir}/web.tar.gz.sha256" install -m 0644 "build/${EFFECTIVE_BUILD_VERSION}/release-manifest.json" "${artifact_dir}/release-manifest.json" cat >"build/${EFFECTIVE_BUILD_VERSION}/web-artifact-pointer.txt" <