This commit is contained in:
2026-09-18 18:50:40 +08:00
parent 1fb02db516
commit 28d3d6b8b6
10 changed files with 960 additions and 18 deletions
Vendored
+46 -15
View File
@@ -58,17 +58,22 @@ def commonPathServices = [
def databaseMigrationPaths = ['deploy/sql/']
def downstreamResults = [:]
def downstreamBuildUrls = [:]
def downstreamBuildNumbers = [:]
def sendProductionWeComNotification(String status, String color, String detail) {
def sendProductionWeComNotification(String title, String status, String color, String detail) {
node('java-builder') {
withCredentials([string(credentialsId: 'wecom-prod-webhook', variable: 'WECOM_WEBHOOK')]) {
String sourceVersion = env.IMAGE_TAG ?: env.SOURCE_COMMIT ?: env.GIT_COMMIT ?: '—'
String content = """## 生产部署通知
> 项目:${env.JOB_NAME}
String sourceVersion = env.IMAGE_TAG ?: env.SOURCE_COMMIT ?: env.GIT_COMMIT ?: '未解析'
String duration = currentBuild.durationString?.replace(' and counting', '') ?: '—'
String content = """## ${title}
> 应用:后端服务
> Job:${env.JOB_NAME}
> 构建:[#${env.BUILD_NUMBER}](${env.BUILD_URL})
> 提交:${sourceVersion}
> 状态:<font color="${color}">${status}</font>
> 详情:${detail}
${detail}
> 耗时:${duration}
> 时间:${new Date().format('yyyy-MM-dd HH:mm:ss', TimeZone.getTimeZone('Asia/Shanghai'))}
"""
String payloadFile = 'wecom-production-notification.json'
@@ -228,6 +233,10 @@ pipeline {
env.RESOLVED_ENVIRONMENT = resolvedEnvironment
echo "Job ${env.JOB_BASE_NAME} 使用部署环境: ${env.RESOLVED_ENVIRONMENT}"
// 先记录当前提交,使后续生产校验失败时通知仍能定位版本。
env.SOURCE_COMMIT = sh(script: 'git rev-parse HEAD', returnStdout: true).trim()
env.IMAGE_TAG = sh(script: 'git rev-parse --short=12 HEAD', returnStdout: true).trim()
if (env.RESOLVED_ENVIRONMENT == 'production') {
sh '''
set -eu
@@ -255,8 +264,6 @@ pipeline {
error('生产环境禁止跳过测试')
}
env.SOURCE_COMMIT = sh(script: 'git rev-parse HEAD', returnStdout: true).trim()
env.IMAGE_TAG = sh(script: 'git rev-parse --short=12 HEAD', returnStdout: true).trim()
List selected = []
if (params.BUILD_MODE == 'ALL') {
selected = serviceModules
@@ -427,6 +434,8 @@ pipeline {
]
)
downstreamResults[service] = downstreamBuild.result ?: 'UNKNOWN'
downstreamBuildUrls[service] = downstreamBuild.absoluteUrl ?: ''
downstreamBuildNumbers[service] = downstreamBuild.number?.toString() ?: ''
echo "${service} 执行结果: ${downstreamResults[service]} (${downstreamBuild.absoluteUrl})"
}
}
@@ -459,10 +468,18 @@ pipeline {
script {
if (env.JOB_BASE_NAME == 'backend-java-prod' && params.DEPLOY && env.NO_SERVICE_CHANGE != 'true') {
try {
List deployedServices = env.SELECTED_SERVICES?.split(',')
?.collect { it.trim() }
?.findAll { it } ?: []
String serviceSummary = deployedServices.size() <= 3
? deployedServices.join('、')
: "${deployedServices.size()} 个服务"
sendProductionWeComNotification(
'部署成功',
'✅ 生产部署成功',
'成功',
'info',
"服务:${env.SELECTED_SERVICES ?: '—'}"
"> 结果:${deployedServices.size()} 个服务全部成功\n" +
"> 部署服务:${serviceSummary ?: '—'}"
)
} catch (Exception error) {
echo "企业微信通知失败,不影响原构建结果:${error.message}"
@@ -474,10 +491,22 @@ pipeline {
script {
if (env.JOB_BASE_NAME == 'backend-java-prod' && params.DEPLOY) {
try {
List failedServices = downstreamResults.findAll { service, result -> result != 'SUCCESS' }
.collect { service, result -> service }
int successCount = downstreamResults.findAll { service, result -> result == 'SUCCESS' }.size()
String failedLinks = failedServices.collect { service ->
String url = downstreamBuildUrls[service]
String number = downstreamBuildNumbers[service]
String label = number ? "${service} #${number}" : service
url ? "[${label}](${url})" : label
}.join('、')
sendProductionWeComNotification(
'部署部分失败',
'⚠️ 生产部署部分失败',
'部分失败',
'warning',
currentBuild.description ?: '部分服务部署未成功,请查看 Jenkins 日志'
"> 结果:成功 ${successCount} / 失败 ${failedServices.size()}\n" +
"> 失败服务:${failedLinks ?: '未解析'}\n" +
'> 说明:点击失败服务可直接查看下游构建日志'
)
} catch (Exception error) {
echo "企业微信通知失败,不影响原构建结果:${error.message}"
@@ -490,9 +519,10 @@ pipeline {
if (env.JOB_BASE_NAME == 'backend-java-prod' && params.DEPLOY) {
try {
sendProductionWeComNotification(
'部署失败',
'❌ 生产发布失败',
'失败',
'warning',
'生产发布流程失败,请打开 Jenkins 构建日志查看失败阶段'
'> 说明:生产发布流程失败,请打开父构建日志查看失败阶段'
)
} catch (Exception error) {
echo "企业微信通知失败,不影响原构建结果:${error.message}"
@@ -505,9 +535,10 @@ pipeline {
if (env.JOB_BASE_NAME == 'backend-java-prod' && params.DEPLOY) {
try {
sendProductionWeComNotification(
'部署已取消',
'⏹ 生产部署已取消',
'已取消',
'comment',
'生产部署流程被人工取消或中止'
'> 说明:生产部署流程被人工取消或中止'
)
} catch (Exception error) {
echo "企业微信通知失败,不影响原构建结果:${error.message}"