Modern technology continues to accelerate the speed of delivering software, which directly increases the importance of quality awareness as early as possible within your delivery pipeline.  If you don’t know of a problem, you can’t act on it. The Email-ext plugin in Jenkins (https://wiki.jenkins.io/display/JENKINS/Email-ext+plugin) is a great way to notify relevant parties as soon as a problem occurs within a pipeline. This gives individuals the opportunity to respond immediately to issues. Additionally, the plugin can ensure that the correct individuals are addressing the issue by targeting only the developers whose changes caused the problem.

The following examples were tested using a maven project with a scripted pipeline and shared Jenkins library.   

Basic Email Trigger

The example below permits Jenkins to email the individuals who broke the build (CulpritsRecipientProvider), as well as the person who triggered the build (RequesterRecipientProvider), if triggered manually. Jenkins zips up the console log and emails it to all the configured individuals. While the email is somewhat generic, it still provides actionable feedback.

emailext attachLog: true, 
body: """EXECUTED: Something happened with Jenkins. View console output at  ${env.BUILD_URL}. Build log is attached.""",     
compressLog: true,     
recipientProviders: [[$class: 'CulpritsRecipientProvider'],   
[$class: 'RequesterRecipientProvider']],     
subject: "Jenkins Status: A job just failed”

Customizing generated email

While the email generated is a good start, lets jazz it up a bit making it  more descriptive. The next example adds the artifactID and artifactVersion from the pom file.  For this particular use case, the artifactID and artifactVersion are the main identifiers we use to track the specific services.  This way it is obvious to the recipients which service is having an issue. This is customizable though for whatever use case is most relevant to your environment. For more information on how to read a maven project file click here

def pom = readMavenPom()
emailext attachLog: true,
    body: """EXECUTED: Job:\'${pom.getArtifactId()}-${pom.getVersion()}\'. View console output at ${env.BUILD_URL}. Build log is attached.""",
    compressLog: true,
    recipientProviders: [[$class: 'CulpritsRecipientProvider'], [$class: 'RequesterRecipientProvider']],
    subject: "Jenkins Status: ${currentBuild.result} - Job \'${pom.getArtifactId()}-${pom.getVersion()}\'",

That’s a bit more informative, and will at least address the people most likely to be able to rectify the problem with the pipeline.  But what happens if they’re not great at checking their email, or have rules that route the sometimes voluminous volume of pipeline messages to their junk folder?  Well, we can set up a list to email when stuff breaks as well so the appropriate people can enable others to also be aware of the issue:

 import com.example.Config_file_where_we_specify_email_list
     def pom = readMavenPom()
     emailext attachLog: true,
     body: """EXECUTED: Job:\'${pom.getArtifactId()}-${pom.getVersion()}\'. View console output at ${env.BUILD_URL}. Build log is attached.""",
     compressLog: true,
     recipientProviders: [[$class: 'CulpritsRecipientProvider'], [$class: 'RequesterRecipientProvider']],
     subject: "Jenkins Status: ${currentBuild.result} - Job \'${pom.getArtifactId()}-${pom.getVersion()}\'",
     to: Config_file_where_we_specify_email_list.Tier2

Adding other users to notification

In this case, useEmailList is defined elsewhere as a string of emails separated by whitespace: 

static final string Tier2 = ‘foo@bar.com bar@foo.com’

This in conjunction with our script so far will email the person who likely contributed to the break, the person who ran the job that found the break, and the supplied list (foo@bar.com and bar@foo.com in this case).  

However, it seems needless to notify the larger group of a problem if it’s in a minor branch that may not have any real impact. So let’s see if we can’t cut down on their emails.

At this point, some of our variables are getting a little long albeit descriptive, so we’re going to shorten them.  

Config = Config_file_where_we_specify_email_list

We’ll also create a variable called useEmailList.  If the branch we are building is either develop or Master, then we’ll email the list, otherwise we’ll just leave the “to” field blank, so only the developers who can most easily address the problem receive an email.

import com.example.Config
    def pom = readMavenPom()
    def useEmailList = ''
    if (BRANCH_NAME == 'develop' || BRANCH_NAME == 'master') {
        useEmailList = Config.TIER2
    }
    emailext attachLog: true,
    body: """EXECUTED: Job:\'${pom.getArtifactId()}-${pom.getVersion()}\'. View console output at ${env.BUILD_URL}. Build log is attached.""",
    compressLog: true,
    recipientProviders: [[$class: 'CulpritsRecipientProvider'], [$class: 'RequesterRecipientProvider']],
    subject: "Jenkins Status: ${currentBuild.result} - Job \'${pom.getArtifactId()}-${pom.getVersion()}\'",
    to: useEmailList

A method to the madness

Well, that’s great, and we could even break it out into its own method.  And if we do so, we can even make it a little more useful by adding a potential toggle for this feature to the Jenkinsfile.  We can have the Jenkinsfile specify a variable (emailOnFailure in this case), which can then get passed to the method by doing the following:

import com.example.Config
def call(Map config = [:]) {
    def pom = readMavenPom()
    def useEmailList = ''
    if (config?.to) {
        useEmailList = config.to
    } else if (BRANCH_NAME == 'develop' || BRANCH_NAME == 'master') {
        useEmailList = Config.FAIL_EMAIL_LIST
    }
    emailext attachLog: true,
    body: """EXECUTED: Job:\'${pom.getArtifactId()}-${pom.getVersion()}\'. View console output at ${env.BUILD_URL}. Build log is attached.""",
    compressLog: true,
    recipientProviders: [[$class: 'CulpritsRecipientProvider'], [$class: 'RequesterRecipientProvider']],
    subject: "Jenkins Status: ${currentBuild.result} - Job \'${pom.getArtifactId()}-${pom.getVersion()}\'",
    to: useEmailList
}

The above assumes that you’ve executed the call using something like 

emailOnFailure config?.emailOnFailure, 

and have passed the email address you want to use in the Jenkinsfile by setting it to emailOnFailure.

So now, when a build is executed  (automatically or manually), if the build has a problem, the relevant parties get notified.  If it’s an important branch, then even more people get notified so the problem can be quickly addressed.

Leave a comment

Your email address will not be published. Required fields are marked *

X