Jenkins多测试阶段执行状态汇总邮件发送问题
Jenkins Pipeline 问题与解决方案
问题描述
- 配置了三个测试阶段,希望第二个测试失败时,第三个阶段仍能继续执行
- 无法正确获取三个测试阶段的执行状态,需要发送包含各阶段结果的汇总邮件,格式示例:
Test 1 - success Test2 - failure Test3- success
当前Pipeline代码
pipeline { agent none parameters { ... } environment { ... def Test1Status def Test2Status def Test3Status } options { ansiColor('xterm') } stages { stage('Refresh Jenkins Settings only') { when { expression { return params.RefreshJenkinsSettings == true } } steps { echo "This is Update Only run to refresh parameters and steps" echo "System: \${SYSTEM_NAME}" } } stage('Run Test1') { agent { label '...' } when { expression { return params.RefreshJenkinsSettings == false } } steps { catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { sh 'python3 scripts/Test1.py -version "\${Version}" ' } } } stage('Test2') { agent { label '...' } when { expression { return params.RefreshJenkinsSettings == false } } steps { catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { sh 'python Scripts\\\\Test2.py -env "\${Env}" -s "\${Schema}"' } } } stage('Test3') { agent { label '...' } when { expression { return params.RefreshJenkinsSettings == false } } steps { bat 'D:\\Pentaho\\Kitchen.bat /rep:git1 /dir:TestCase/Test3 /job:Job "/param:ENV=%Env%" ...' } } } post { always { script { def emailBody = "Test Email\n\n" // Check the status of each stage and update the email body accordingly if (Test1Status == 'SUCCESS') { emailBody += "Test1: SUCCESS\n" } else { emailBody += "Test1: FAILED\n" } if (Test2Status == 'SUCCESS') { emailBody += "Test2: SUCCESS\n" } else { emailBody += "Test2: FAILED\n" } if (Test3Status == 'SUCCESS') { emailBody += "Test3: SUCCESS\n" } else { emailBody += "Test3: FAILED\n" } // Send the email with the updated content emailext to: "xxx@yyy.com", subject: "Test Email", body: emailBody, mimeType: 'text/html' } } } }
解决方案
1. 实现失败阶段不阻断后续执行
你已经在Test1和Test2阶段用了catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE')来标记阶段失败但不终止构建,但Test3阶段没加这个逻辑。给Test3也套上相同的catchError,就能保证不管前面阶段是否失败,Test3都会执行。
如果需要最终构建结果能反映失败情况,可把buildResult: 'SUCCESS'改成buildResult: null,这样只有阶段标记为失败,整体构建结果会根据所有阶段状态自动判断,同时不影响后续阶段执行。
修改后的Test3阶段示例:
stage('Test3') { agent { label '...' } when { expression { return params.RefreshJenkinsSettings == false } } steps { catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { bat 'D:\\Pentaho\\Kitchen.bat /rep:git1 /dir:TestCase/Test3 /job:Job "/param:ENV=%Env%" ...' } } }
2. 正确捕获阶段状态并生成指定格式邮件
当前代码的问题在于:environment块里不能用def声明变量,而且没有在阶段执行后更新状态值。按以下步骤修正:
步骤1:用环境变量存储状态
把状态变量放到env里,这样在整个pipeline中都能访问到,不需要额外声明。
步骤2:在每个阶段中捕获执行结果
用try-catch包裹测试步骤,执行成功就把对应环境变量设为SUCCESS,失败则设为FAILURE,同时用catchError标记阶段失败。
步骤3:修正邮件格式
因为用了mimeType: 'text/html',要把换行内容放到<pre>标签里,才能保持示例中的格式;同时增加“未执行”的兜底判断,避免参数RefreshJenkinsSettings为true时状态为空。
完整修正后的Pipeline代码
pipeline { agent none parameters { booleanParam(name: 'RefreshJenkinsSettings', defaultValue: false, description: '仅刷新Jenkins设置') // 补充你实际的参数,比如Version、Env、Schema等 } options { ansiColor('xterm') } stages { stage('Refresh Jenkins Settings only') { when { expression { return params.RefreshJenkinsSettings == true } } steps { echo "This is Update Only run to refresh parameters and steps" echo "System: ${SYSTEM_NAME}" } } stage('Run Test1') { agent { label '...' } when { expression { return params.RefreshJenkinsSettings == false } } steps { script { try { sh 'python3 scripts/Test1.py -version "${Version}" ' env.Test1Status = 'SUCCESS' } catch (Exception e) { env.Test1Status = 'FAILURE' catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { throw e } } } } } stage('Test2') { agent { label '...' } when { expression { return params.RefreshJenkinsSettings == false } } steps { script { try { sh 'python Scripts\\\\Test2.py -env "${Env}" -s "${Schema}"' env.Test2Status = 'SUCCESS' } catch (Exception e) { env.Test2Status = 'FAILURE' catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { throw e } } } } } stage('Test3') { agent { label '...' } when { expression { return params.RefreshJenkinsSettings == false } } steps { script { try { bat 'D:\\Pentaho\\Kitchen.bat /rep:git1 /dir:TestCase/Test3 /job:Job "/param:ENV=%Env%" ...' env.Test3Status = 'SUCCESS' } catch (Exception e) { env.Test3Status = 'FAILURE' catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { throw e } } } } } } post { always { script { def emailBody = "<h3>测试结果汇总</h3><pre>" emailBody += "Test1 - ${env.Test1Status ?: '未执行'}\n" emailBody += "Test2 - ${env.Test2Status ?: '未执行'}\n" emailBody += "Test3 - ${env.Test3Status ?: '未执行'}\n" emailBody += "</pre>" emailext to: "xxx@yyy.com", subject: "测试执行结果汇总 - ${currentBuild.result ?: 'SUCCESS'}", body: emailBody, mimeType: 'text/html' } } } }
内容的提问来源于stack exchange,提问作者Jan Pietruszka
相关产品推荐
相关产品推荐

