在Jenkins流水线失败时发送电子邮件

46

我该如何在Jenkins流水线中添加旧式的构建后任务,以便在构建失败时发送电子邮件?我无法在管道的GUI中找到“后构建操作”。我知道可以将整个构建脚本包装在try/catch中,但是当构建脚本很大并且即使手动中止作业也会继续发送电子邮件时,这似乎很丑陋。我希望实现与先前基于email-ext的构建后操作相同的功能。

try {
    // Do sth
} catch(e) {
    emailext body: '$DEFAULT_CONTENT', 
        recipientProviders: [
            [$class: 'CulpritsRecipientProvider'],
            [$class: 'DevelopersRecipientProvider'],
            [$class: 'RequesterRecipientProvider']
        ], 
        replyTo: '$DEFAULT_REPLYTO', 
        subject: '$DEFAULT_SUBJECT',
        to: '$DEFAULT_RECIPIENTS'
    throw err
}

2
你最终做了什么?我有一个类似的需求,但当涉及到Jenkins设计时,我总是感到惊讶。电子邮件警报如何成为我们希望在管道中复制的内容?我们真的被建议将代码版本与电子邮件通知设置混合吗-这对我来说毫无意义。 - NicolasW
@NicolasW 我还在使用上面的 emailext body... 方法。没有找到更好的方法,已经浪费了足够多的时间 :) - Mariusz Jamro
1
好的,谢谢。我真的对Jenkins不感冒! - NicolasW
2
@NicolasW 在Jenkins中的管道是对“伙计们,现在是20**年了,人们正在将他们的配置作为代码进行维护,让我们做些什么,以便他们不会抛弃我们”的匆忙回应。 - Abhijit Sarkar
6个回答

61

这个答案在我的Jenkins版本2.96上有效。

Jenkins流水线在构建失败时未发送电子邮件 - Stack Overflow

 pipeline {  
     agent any  
     stages {  
         stage('Test') {  
             steps {  
                 sh 'echo "Fail!"; exit 1'  
             }  
         }  
     }  
     post {  
         always {  
             echo 'This will always run'  
         }  
         success {  
             echo 'This will run only if successful'  
         }  
         failure {  
             mail bcc: '', body: "<b>Example</b><br>Project: ${env.JOB_NAME} <br>Build Number: ${env.BUILD_NUMBER} <br> URL de build: ${env.BUILD_URL}", cc: '', charset: 'UTF-8', from: '', mimeType: 'text/html', replyTo: '', subject: "ERROR CI: Project name -> ${env.JOB_NAME}", to: "foo@foomail.com";  
         }  
         unstable {  
             echo 'This will run only if the run was marked as unstable'  
         }  
         changed {  
             echo 'This will run only if the state of the Pipeline has changed'  
             echo 'For example, if the Pipeline was previously failing but is now successful'  
         }  
     }  
 }

邮件步骤的官方文档


1
我必须删除 \n\ 中的第二个反斜杠才能使其正常工作。 - Christopher Markieta
7
什么是“mail”?它来自于插件吗?它和“emailext”有什么不同? - cowlinator
1
mailemailext 是不同的 - 我还在努力寻找文档 O_o - JGlass
我假设在设置了SMTP凭据之后这个可以工作?我已经这样做并且能够发送测试邮件,但是它不能从我的管道中发送。 - Michael
1
@JGlass 这是我能找到的全部内容 -> https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/#mail-mail - Snailedlt
显示剩余2条评论

29

若要仅在构建状态已更改时采取操作,可以使用post > changed block

而要检查状态更改的状态,您可以结合使用脚本块来检查currentBuild.currentResult属性的值。

像这样:

pipeline {
    ...

    post {
        changed {
            script {
                if (currentBuild.currentResult == 'FAILURE') { // Other values: SUCCESS, UNSTABLE
                    // Send an email only if the build status has changed from green/unstable to red
                    emailext subject: '$DEFAULT_SUBJECT',
                        body: '$DEFAULT_CONTENT',
                        recipientProviders: [
                            [$class: 'CulpritsRecipientProvider'],
                            [$class: 'DevelopersRecipientProvider'],
                            [$class: 'RequesterRecipientProvider']
                        ], 
                        replyTo: '$DEFAULT_REPLYTO',
                        to: '$DEFAULT_RECIPIENTS'
                }
            }
        }
    }

}

19

目前您需要使用try-catch步骤获取构建后操作。

但是在未来,这一步骤计划完善(实际上正在审核中)。您可以阅读博客文章以获取更多信息(请参见声明性管道部分)。也可以查看 Jenkins Jira问题单拉取请求

更新:

Jenkins声明式管道现在有了post部分,将在每次构建结束时有条件地运行步骤。有关更多信息,请参见文档

post {
 always {
   sh 'echo "This will always run"'
 }
 success {
  sh 'echo "This will run only if successful"'
 }
 failure {
  sh 'echo "This will run only if failed"'
 }
 unstable {
  sh 'echo "This will run only if the run was marked as unstable"'
 }
 changed {
  sh 'echo "This will run only if the state of the Pipeline has changed"'
  sh 'echo "For example, the Pipeline was previously failing but is now successful"'
  sh 'echo "... or the other way around :)"'
 }
}

@MariuszJamro 他们应该这样做。他们可以将现有的脚本代码包装在“script”块中。 - Abhijit Sarkar
@AbhijitSarkar 不一定 - 仍然有一些用例无法使用声明式 - 例如在此处讨论:https://issues.jenkins-ci.org/browse/JENKINS-41335 - sonicwave

12

这在我的Jenkins(当前版本2.164.2和emailext)上使用声明性流水线运作良好:

pipeline {
...

environment {
        EMAIL_TO = 'someone@host.com'
    }
post {
        failure {
            emailext body: 'Check console output at $BUILD_URL to view the results. \n\n ${CHANGES} \n\n -------------------------------------------------- \n${BUILD_LOG, maxLines=100, escapeHtml=false}', 
                    to: "${EMAIL_TO}", 
                    subject: 'Build failed in Jenkins: $PROJECT_NAME - #$BUILD_NUMBER'
        }
        unstable {
            emailext body: 'Check console output at $BUILD_URL to view the results. \n\n ${CHANGES} \n\n -------------------------------------------------- \n${BUILD_LOG, maxLines=100, escapeHtml=false}', 
                    to: "${EMAIL_TO}", 
                    subject: 'Unstable build in Jenkins: $PROJECT_NAME - #$BUILD_NUMBER'
        }
        changed {
            emailext body: 'Check console output at $BUILD_URL to view the results.', 
                    to: "${EMAIL_TO}", 
                    subject: 'Jenkins build is back to normal: $PROJECT_NAME - #$BUILD_NUMBER'
        }
    }
}

您可以控制发送邮件来通知构建失败或状态变更。此外,我已将构建日志放入电子邮件正文中。


2
要使您的脚本化流程更加干净简洁,您可以轻松地通过创建vars/emailOnError.groovy来扩展Jenkins并定义一个自定义步骤emailOnError。通过这种方式,您可以使用DRYextend Jenkins with your own shared library来实现。
def call(Closure action) {
    try {
        action()
    } catch(e){
        emailext    body: '$DEFAULT_CONTENT', 
                    recipientProviders: [
                        [$class: 'DevelopersRecipientProvider'],
                        [$class: 'RequesterRecipientProvider']
                    ], 
                    replyTo: '$DEFAULT_REPLYTO', 
                    subject: '$PROJECT_NAME - Build # $BUILD_NUMBER - ERROR!',
                    to: '$DEFAULT_RECIPIENTS'
        throw err
    }   
}

请注意,这个共享方法emailOnError来自vars/emailOnError.groovy,可以像这样使用:
emailOnError() {
    // Do sth   
}

2
几乎所有上面的答案都是正确的,但是当构建失败时,我在帖子部分使用了这个答案。也许这会有用。
post {
always {
  script {
    if (currentBuild.currentResult == 'FAILURE') {
      step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: "abc.xyz@blabl.com", sendToIndividuals: true])
    }
  }
}

收件人值缺少双引号闭合。 - karfau
完成。谢谢 @karfau - Dashrath Mundkar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接