/** * 整体 / 单服务 / 多选:仅晋升 Harbor 镜像 + 可选 ACK。 * Script Path:docs/jenkins/produ/whole/Jenkinsfile */ def sparseCheckoutProduShared() { checkout scm: [ $class: 'GitSCM', branches: scm.branches, extensions: [ [$class: 'CloneOption', depth: 1, shallow: true, noTags: true], [$class: 'SparseCheckoutPaths', sparseCheckoutPaths: [ [path: 'docs/jenkins/produ/_shared/'], ]], ], userRemoteConfigs: scm.userRemoteConfigs, ] } def getProduLibs() { sparseCheckoutProduShared() def k8s = load 'docs/jenkins/produ/_shared/k8s-produ-lib.groovy' def reg = load 'docs/jenkins/produ/_shared/service-registry.groovy' return [k8s, reg] } pipeline { agent any options { buildDiscarder(logRotator(numToKeepStr: '15')) disableConcurrentBuilds() skipDefaultCheckout(true) timestamps() timeout(time: 120, unit: 'MINUTES') } parameters { choice(name: 'DEPLOY_MODE', choices: ['whole', 'single', 'multi'], description: 'whole=7个服务;single=选一个;multi=勾选 MULTI_*') choice(name: 'SINGLE_SERVICE', choices: [ 'gateway', 'store', 'second', 'store-platform', 'lawyer', 'job', 'dining', ], description: '仅 DEPLOY_MODE=single 时生效') booleanParam(name: 'MULTI_gateway', defaultValue: false) booleanParam(name: 'MULTI_store', defaultValue: false) booleanParam(name: 'MULTI_second', defaultValue: false) booleanParam(name: 'MULTI_store_platform', defaultValue: false) booleanParam(name: 'MULTI_lawyer', defaultValue: false) booleanParam(name: 'MULTI_job', defaultValue: false) booleanParam(name: 'MULTI_dining', defaultValue: false) string(name: 'SOURCE_TAG', defaultValue: 'uat-latest', trim: true, description: 'Harbor UAT tag,默认 uat-latest;回滚填 uat-build-') string(name: 'TARGET_TAG', defaultValue: '', trim: true, description: '留空则 produ-${BUILD_NUMBER}') choice(name: 'PROMOTE_METHOD', choices: ['harbor-api', 'docker-pull'], description: 'harbor-api=服务端打 tag(快);docker-pull=拉取再 push(慢,兼容)') booleanParam(name: 'PARALLEL_ACK_DEPLOY', defaultValue: true, description: 'whole/multi 时并行 kubectl rollout(显著缩短 ACK 阶段)') string(name: 'HARBOR_REGISTRY', defaultValue: '39.105.153.68', trim: true) string(name: 'HARBOR_PROJECT', defaultValue: 'alien_cloud', trim: true) choice(name: 'DEPLOY_STRATEGY', choices: ['rolling', 'canary', 'skip'], description: '''rolling=更新 stable Deployment,kubectl 滚动替换 Pod(全量发版) canary=仅更新 *-canary Deployment,并按 CANARY_WEIGHT 设置 Ingress 灰度流量 skip=只晋升 Harbor 镜像,不执行 kubectl''') string(name: 'CANARY_WEIGHT', defaultValue: '10', trim: true) string(name: 'K8S_NAMESPACE', defaultValue: 'alien-produ', trim: true) booleanParam(name: 'DRY_RUN', defaultValue: false) } environment { HARBOR_CREDENTIALS = 'harbor-robot-alien' KUBECONFIG_CREDENTIALS = 'ack-kubeconfig-alien' } stages { stage('Promote & Deploy') { steps { script { def (k8s, reg) = getProduLibs() def services = reg.filterServices(reg.getServiceRegistry(), params) env.SOURCE_TAG_RESOLVED = k8s.requireSourceTag(this, params.SOURCE_TAG) env.TARGET_TAG_RESOLVED = k8s.resolveTargetTag(this, params.TARGET_TAG) env.PROMOTE_LIST = services*.prodDir.join(',') echo ">>> DEPLOY_MODE=${params.DEPLOY_MODE} 服务=${env.PROMOTE_LIST}" echo ">>> ${env.SOURCE_TAG_RESOLVED} → ${env.TARGET_TAG_RESOLVED} promote=${params.PROMOTE_METHOD}" k8s.promoteHarborImages(this, services, [ harborRegistry: params.HARBOR_REGISTRY, harborProject: params.HARBOR_PROJECT, sourceTag: env.SOURCE_TAG_RESOLVED, targetTag: env.TARGET_TAG_RESOLVED, harborCredentialsId: env.HARBOR_CREDENTIALS, promoteMethod: params.PROMOTE_METHOD, dryRun: params.DRY_RUN == true, ]) if (params.DEPLOY_STRATEGY != 'skip' && !params.DRY_RUN) { k8s.deployServicesToAck(this, services, [ harborRegistry: params.HARBOR_REGISTRY, harborProject: params.HARBOR_PROJECT, targetTag: env.TARGET_TAG_RESOLVED, deployStrategy: params.DEPLOY_STRATEGY, k8sNamespace: params.K8S_NAMESPACE, canaryWeight: params.CANARY_WEIGHT, kubeCredentialsId: env.KUBECONFIG_CREDENTIALS, parallelDeploy: params.PARALLEL_ACK_DEPLOY == true, ]) } } } } } post { success { echo ">>> 完成: ${env.PROMOTE_LIST} tag=${env.TARGET_TAG_RESOLVED}" } } }