feat(ci): deploy both event bridge regions by default

This commit is contained in:
2026-08-24 17:19:36 +08:00
parent 3d8a1fac20
commit 5a4bcf130a
5 changed files with 69 additions and 19 deletions
Vendored
+14 -5
View File
@@ -68,8 +68,8 @@ pipeline {
booleanParam(name: 'SERVICE_INTEGRATION', defaultValue: false, description: '第三方集成服务(integration-service)') booleanParam(name: 'SERVICE_INTEGRATION', defaultValue: false, description: '第三方集成服务(integration-service)')
booleanParam(name: 'SERVICE_LASTLEG', defaultValue: false, description: '海外尾程与入仓服务(lastleg-service)') booleanParam(name: 'SERVICE_LASTLEG', defaultValue: false, description: '海外尾程与入仓服务(lastleg-service)')
booleanParam(name: 'SERVICE_WAREHOUSE_OVERSEAS', defaultValue: false, description: '海外仓资源服务(warehouse-overseas-service)') booleanParam(name: 'SERVICE_WAREHOUSE_OVERSEAS', defaultValue: false, description: '海外仓资源服务(warehouse-overseas-service)')
booleanParam(name: 'SERVICE_EVENT_BRIDGE', defaultValue: false, description: '跨区域事件桥(event-bridge-service;由 EVENT_BRIDGE_REGION 选择实例)') booleanParam(name: 'SERVICE_EVENT_BRIDGE', defaultValue: false, description: '跨区域事件桥(event-bridge-service;默认同时部署国内和海外实例)')
choice(name: 'EVENT_BRIDGE_REGION', choices: ['SELECT', 'CN', 'OVERSEAS'], description: '部署 event-bridge-service 时必须明确选择实例;SELECT 会阻止部署') choice(name: 'EVENT_BRIDGE_REGION', choices: ['BOTH', 'CN', 'OVERSEAS'], description: 'BOTH 同时部署国内和海外实例;CN/OVERSEAS 用于单区故障重跑')
booleanParam(name: 'SERVICE_AUDIT', defaultValue: false, description: '审计服务(audit-service)') booleanParam(name: 'SERVICE_AUDIT', defaultValue: false, description: '审计服务(audit-service)')
choice(name: 'ENVIRONMENT', choices: environmentChoicesForJob(env.JOB_BASE_NAME), description: '部署环境') choice(name: 'ENVIRONMENT', choices: environmentChoicesForJob(env.JOB_BASE_NAME), description: '部署环境')
booleanParam(name: 'DEPLOY', defaultValue: false, description: '各服务构建成功后是否独立部署') booleanParam(name: 'DEPLOY', defaultValue: false, description: '各服务构建成功后是否独立部署')
@@ -149,9 +149,18 @@ pipeline {
} }
selected = selected.unique() selected = selected.unique()
if (params.DEPLOY && selected.contains('event-bridge-service') if (params.DEPLOY && selected.contains('event-bridge-service')) {
&& !['CN', 'OVERSEAS'].contains(params.EVENT_BRIDGE_REGION)) { String bridgeRegion = params.EVENT_BRIDGE_REGION?.trim()
error('部署 event-bridge-service 必须明确选择 EVENT_BRIDGE_REGION=CN 或 OVERSEAS') if (!['BOTH', 'SELECT', 'CN', 'OVERSEAS'].contains(bridgeRegion)) {
error('EVENT_BRIDGE_REGION 只能为 BOTH、CN 或 OVERSEAS')
}
if (['BOTH', 'SELECT'].contains(bridgeRegion)
&& !['development', 'test'].contains(env.RESOLVED_ENVIRONMENT)) {
error('事件桥 BOTH 仅支持开发或测试环境;预发布和生产必须明确选择 CN 或 OVERSEAS')
}
if (bridgeRegion == 'SELECT') {
echo '兼容旧 Jenkins 参数 SELECT:本次按 BOTH 同时部署国内和海外事件桥'
}
} }
env.SELECTED_SERVICES = selected.join(',') env.SELECTED_SERVICES = selected.join(',')
env.NO_SERVICE_CHANGE = selected ? 'false' : 'true' env.NO_SERVICE_CHANGE = selected ? 'false' : 'true'
+30 -10
View File
@@ -38,7 +38,7 @@ pipeline {
choice(name: 'ENVIRONMENT', choices: ['test', 'development', 'staging', 'production'], description: '部署环境') choice(name: 'ENVIRONMENT', choices: ['test', 'development', 'staging', 'production'], description: '部署环境')
booleanParam(name: 'DEPLOY', defaultValue: false, description: '构建成功后是否部署本服务') booleanParam(name: 'DEPLOY', defaultValue: false, description: '构建成功后是否部署本服务')
booleanParam(name: 'SKIP_TESTS', defaultValue: false, description: '是否跳过测试') booleanParam(name: 'SKIP_TESTS', defaultValue: false, description: '是否跳过测试')
choice(name: 'EVENT_BRIDGE_REGION', choices: ['SELECT', 'CN', 'OVERSEAS'], description: '仅 event-bridge-service 部署使用;必须由总控明确传入 CN 或 OVERSEAS') choice(name: 'EVENT_BRIDGE_REGION', choices: ['BOTH', 'CN', 'OVERSEAS'], description: '仅 event-bridge-service 使用;BOTH 在开发/测试环境同时部署国内和海外实例')
string(name: 'IMAGE_REPOSITORY', defaultValue: '172.31.198.7:10082/java-project/baiyue-firstleg', description: '内网共享镜像仓库基础路径,不包含服务名和标签') string(name: 'IMAGE_REPOSITORY', defaultValue: '172.31.198.7:10082/java-project/baiyue-firstleg', description: '内网共享镜像仓库基础路径,不包含服务名和标签')
string(name: 'DOCKER_BASE_IMAGE', defaultValue: '172.31.198.7:10082/java-project/eclipse-temurin:17-jre-alpine', description: '内网 Java 17 基础镜像') string(name: 'DOCKER_BASE_IMAGE', defaultValue: '172.31.198.7:10082/java-project/eclipse-temurin:17-jre-alpine', description: '内网 Java 17 基础镜像')
} }
@@ -93,6 +93,17 @@ pipeline {
env.RESOLVED_SOURCE_COMMIT = sourceCommit env.RESOLVED_SOURCE_COMMIT = sourceCommit
env.RESOLVED_IMAGE_TAG = imageTag env.RESOLVED_IMAGE_TAG = imageTag
env.RESOLVED_IMAGE_REPOSITORY = imageRepository env.RESOLVED_IMAGE_REPOSITORY = imageRepository
if (service == 'event-bridge-service' && params.DEPLOY) {
String bridgeRegion = params.EVENT_BRIDGE_REGION?.trim()
if (!['BOTH', 'SELECT', 'CN', 'OVERSEAS'].contains(bridgeRegion)) {
error('EVENT_BRIDGE_REGION 只能为 BOTH、CN 或 OVERSEAS')
}
if (['BOTH', 'SELECT'].contains(bridgeRegion)
&& !['development', 'test'].contains(params.ENVIRONMENT)) {
error('事件桥 BOTH 仅支持开发或测试环境;预发布和生产必须明确选择 CN 或 OVERSEAS')
}
}
} }
sh ''' sh '''
@@ -185,16 +196,25 @@ pipeline {
try { try {
unstash 'deployment-files' unstash 'deployment-files'
echo "在目标节点 ${env.NODE_NAME} 本机部署到 ${params.ENVIRONMENT}" echo "在目标节点 ${env.NODE_NAME} 本机部署到 ${params.ENVIRONMENT}"
withEnv([ List bridgeRegions = env.RESOLVED_SERVICE == 'event-bridge-service'
'TARGET_IS_LOCAL=true', && ['BOTH', 'SELECT'].contains(params.EVENT_BRIDGE_REGION)
"EVENT_BRIDGE_REGION_OVERRIDE=${params.EVENT_BRIDGE_REGION}" ? ['CN', 'OVERSEAS']
: [params.EVENT_BRIDGE_REGION]
withCredentials([
file(credentialsId: credentialId, variable: 'DEPLOY_ENV_FILE'),
usernamePassword(credentialsId: env.REGISTRY_CREDENTIALS,
usernameVariable: 'REGISTRY_USER', passwordVariable: 'REGISTRY_PASSWORD')
]) { ]) {
withCredentials([ bridgeRegions.each { bridgeRegion ->
file(credentialsId: credentialId, variable: 'DEPLOY_ENV_FILE'), if (env.RESOLVED_SERVICE == 'event-bridge-service') {
usernamePassword(credentialsId: env.REGISTRY_CREDENTIALS, echo "部署事件桥实例: ${bridgeRegion}"
usernameVariable: 'REGISTRY_USER', passwordVariable: 'REGISTRY_PASSWORD') }
]) { withEnv([
sh "sh deploy/scripts/deploy-built-service.sh '${params.ENVIRONMENT}' '${env.RESOLVED_IMAGE_REPOSITORY}' '${env.RESOLVED_IMAGE_TAG}' '${env.RESOLVED_SERVICE}' \"\$DEPLOY_ENV_FILE\"" 'TARGET_IS_LOCAL=true',
"EVENT_BRIDGE_REGION_OVERRIDE=${bridgeRegion}"
]) {
sh "sh deploy/scripts/deploy-built-service.sh '${params.ENVIRONMENT}' '${env.RESOLVED_IMAGE_REPOSITORY}' '${env.RESOLVED_IMAGE_TAG}' '${env.RESOLVED_SERVICE}' \"\$DEPLOY_ENV_FILE\""
}
} }
} }
} finally { } finally {
@@ -40,3 +40,10 @@ test('coordinator cannot initialize test databases', () => {
assert.doesNotMatch(pipeline, /initialize-test-databases\.sh/) assert.doesNotMatch(pipeline, /initialize-test-databases\.sh/)
assert.doesNotMatch(pipeline, /测试数据库初始化/) assert.doesNotMatch(pipeline, /测试数据库初始化/)
}) })
test('coordinator defaults event bridge deployments to both non-production regions', () => {
assert.match(pipeline, /choice\(name: 'EVENT_BRIDGE_REGION', choices: \['BOTH', 'CN', 'OVERSEAS'\]/)
assert.match(pipeline, /\['BOTH', 'SELECT', 'CN', 'OVERSEAS'\]\.contains\(bridgeRegion\)/)
assert.match(pipeline, /兼容旧 Jenkins 参数 SELECT:本次按 BOTH/)
assert.match(pipeline, /事件桥 BOTH 仅支持开发或测试环境/)
})
@@ -19,10 +19,10 @@ test('Jenkins pipelines recognize all overseas deployable modules', async () =>
assert.match(service, /lastleg-service\/target\/lastleg-service-1\.0\.0-SNAPSHOT\.jar/) assert.match(service, /lastleg-service\/target\/lastleg-service-1\.0\.0-SNAPSHOT\.jar/)
assert.match(service, /warehouse-overseas-service\/target\/warehouse-overseas-service-1\.0\.0-SNAPSHOT\.jar/) assert.match(service, /warehouse-overseas-service\/target\/warehouse-overseas-service-1\.0\.0-SNAPSHOT\.jar/)
assert.match(controller, /EVENT_BRIDGE_REGION/) assert.match(controller, /EVENT_BRIDGE_REGION/)
assert.match(service, /EVENT_BRIDGE_REGION_OVERRIDE=\$\{params\.EVENT_BRIDGE_REGION\}/) assert.match(service, /EVENT_BRIDGE_REGION_OVERRIDE=\$\{bridgeRegion\}/)
assert.match(controller, /choices: \['SELECT', 'CN', 'OVERSEAS'\]/) assert.match(controller, /choices: \['BOTH', 'CN', 'OVERSEAS'\]/)
assert.match(service, /choices: \['SELECT', 'CN', 'OVERSEAS'\]/) assert.match(service, /choices: \['BOTH', 'CN', 'OVERSEAS'\]/)
assert.match(controller, /部署 event-bridge-service 必须明确选择 EVENT_BRIDGE_REGION=CN 或 OVERSEAS/) assert.match(controller, /事件桥 BOTH 仅支持开发或测试环境/)
}) })
test('service map freezes unique internal ports and moves event bridge away from 9300', async () => { test('service map freezes unique internal ports and moves event bridge away from 9300', async () => {
@@ -48,6 +48,11 @@ test('overseas compose is isolated from CN defaults and disables implicit schema
assert.match(compose, /^ warehouse-overseas-service:\s*$/m) assert.match(compose, /^ warehouse-overseas-service:\s*$/m)
assert.match(compose, /^ event-bridge-service:\s*$/m) assert.match(compose, /^ event-bridge-service:\s*$/m)
assert.match(compose, /EVENT_BRIDGE_OVERSEAS_PORT:-9313}:9312/) assert.match(compose, /EVENT_BRIDGE_OVERSEAS_PORT:-9313}:9312/)
assert.match(compose, /INTERNAL_SERVICE_TOKEN: \$\{INTERNAL_SERVICE_TOKEN\}/)
assert.match(compose, /LASTLEG_DB_URL: \$\{LASTLEG_DB_URL\}/)
assert.match(compose, /EVENT_BRIDGE_DB_URL: \$\{EVENT_BRIDGE_OVERSEAS_DB_URL\}/)
assert.match(compose, /EVENT_BRIDGE_DB_USERNAME: \$\{EVENT_BRIDGE_OVERSEAS_DB_USERNAME\}/)
assert.match(compose, /EVENT_BRIDGE_DB_PASSWORD: \$\{EVENT_BRIDGE_OVERSEAS_DB_PASSWORD\}/)
}) })
test('CN and overseas event bridges have explicit opposite-region consumers', async () => { test('CN and overseas event bridges have explicit opposite-region consumers', async () => {
@@ -155,3 +155,12 @@ test('direct deployments wait for health and automatically restore the previous
assert.match(directDeployScript, /自动回滚失败/) assert.match(directDeployScript, /自动回滚失败/)
assert.match(directDeployScript, /return 1/) assert.match(directDeployScript, /return 1/)
}) })
test('one event bridge build deploys both regional instances in development and test', () => {
assert.match(pipeline, /choice\(name: 'EVENT_BRIDGE_REGION', choices: \['BOTH', 'CN', 'OVERSEAS'\]/)
assert.match(pipeline, /\['BOTH', 'SELECT'\]\.contains\(params\.EVENT_BRIDGE_REGION\)/)
assert.match(pipeline, /\? \['CN', 'OVERSEAS'\]/)
assert.match(pipeline, /bridgeRegions\.each \{ bridgeRegion ->/)
assert.match(pipeline, /EVENT_BRIDGE_REGION_OVERRIDE=\$\{bridgeRegion\}/)
assert.match(pipeline, /部署事件桥实例:/)
})