How to send Slack notification after Jenkins pipeline build failed?

80,478

Solution 1

Just in case if in Declarative Syntax,

Now, Jenkins provides post. You can check result at the end of pipeline.

https://jenkins.io/doc/book/pipeline/syntax/#post-example

Using like:

pipeline {
    stages { ... }
    post {
       // only triggered when blue or green sign
       success {
           slackSend ...
       }
       // triggered when red sign
       failure {
           slackSend ...
       }
       // trigger every-works
       always {
           slackSend ...
       }
    }
}

It would be used in every stage also. See the document link please.

Solution 2

You could do something like this and use a try catch block.

Here is some example Code:

node {
    try {
        notifyBuild('STARTED')

        stage('Prepare code') {
            echo 'do checkout stuff'
        }

        stage('Testing') {
            echo 'Testing'
            echo 'Testing - publish coverage results'
        }

        stage('Staging') {
            echo 'Deploy Stage'
        }

        stage('Deploy') {
            echo 'Deploy - Backend'
            echo 'Deploy - Frontend'
        }

  } catch (e) {
    // If there was an exception thrown, the build failed
    currentBuild.result = "FAILED"
    throw e
  } finally {
    // Success or failure, always send notifications
    notifyBuild(currentBuild.result)
  }
}

def notifyBuild(String buildStatus = 'STARTED') {
  // build status of null means successful
  buildStatus =  buildStatus ?: 'SUCCESSFUL'

  // Default values
  def colorName = 'RED'
  def colorCode = '#FF0000'
  def subject = "${buildStatus}: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'"
  def summary = "${subject} (${env.BUILD_URL})"

  // Override default values based on build status
  if (buildStatus == 'STARTED') {
    color = 'YELLOW'
    colorCode = '#FFFF00'
  } else if (buildStatus == 'SUCCESSFUL') {
    color = 'GREEN'
    colorCode = '#00FF00'
  } else {
    color = 'RED'
    colorCode = '#FF0000'
  }

  // Send notifications
  slackSend (color: colorCode, message: summary)
}

Complete snippet can be found here Jenkinsfile Template

Solution 3

Based on Liam Newman's blog post, have a look at this cleaned up snippet for Slack only in scripted pipelines (declarative pipeline users scroll down). It uses original Jenkins results, message formatting, better colors (based on EclEmma), and some Groovy features like default arguments:

def notifySlack(String buildStatus = 'STARTED') {
    // Build status of null means success.
    buildStatus = buildStatus ?: 'SUCCESS'

    def color

    if (buildStatus == 'STARTED') {
        color = '#D4DADF'
    } else if (buildStatus == 'SUCCESS') {
        color = '#BDFFC3'
    } else if (buildStatus == 'UNSTABLE') {
        color = '#FFFE89'
    } else {
        color = '#FF9FA1'
    }

    def msg = "${buildStatus}: `${env.JOB_NAME}` #${env.BUILD_NUMBER}:\n${env.BUILD_URL}"

    slackSend(color: color, message: msg)
}

node {
    try {
        notifySlack()

        // Existing build steps.
    } catch (e) {
        currentBuild.result = 'FAILURE'
        throw e
    } finally {
        notifySlack(currentBuild.result)
    }
}

The output will be something like this (play around with different formatting styles here):

enter image description here

Maybe env.JOB_NAME contains encoded slashes (%2F) which can be fixed with replaceAll("%2F", "/"). Check out this Gist to see how to notify HipChat as well.

If you have a declarative pipeline, have a look at the Jenkins documentation on "Cleaning up and notifications" or Liam Newman's follow-up post "Declarative Pipeline: Notifications and Shared Libraries".

Share:
80,478
kivagant
Author by

kivagant

Updated on June 22, 2020

Comments

  • kivagant
    kivagant almost 4 years

    I have a pipeline groovy script in Jenkins v2.19. Also I have a
    "Slack Notification Plugin" v2.0.1 and "Groovy Postbuild Plugin".

    I have successfully send a message "build started" and "build finished" (if it had).

    When some build step failed – how I can send a message "Build failed" to the Slack channel?

  • kivagant
    kivagant over 7 years
    Thank you, @Fahl-Design, I'll try this a bit later and will write result to you.
  • JamalMcCrackin
    JamalMcCrackin over 7 years
    Great! enjoy ;) As you can see in that snippet you can add any other notification service after slackSend
  • Kev
    Kev over 6 years
    The article by Liam seems to not be available anymore.
  • beatngu13
    beatngu13 almost 6 years
    It is important to note that the OP uses a Groovy (AKA scripted) pipeline, whereas post can only be used in a declarative pipeline. You cannot mix both.
  • Rakk
    Rakk almost 6 years
    @beatngu13 Oh, yes, That is what I missed. Thank you
  • agoldev
    agoldev over 4 years
    I used your example. When I produce an exception the value buildStatus will be "FAILURE" instead of "FAILED". Why though?
  • agoldev
    agoldev over 4 years
    Found out why. The assigned value is matched against possible values and if no match is possible "FAILURE" will be returned. See github.com/jenkinsci/jenkins/blob/master/core/src/main/java/‌​… and github.com/jenkinsci/jenkins/blob/master/core/src/main/java/‌​…. For consistency I would then assign "FAILURE" in the catch block.
  • Psdet
    Psdet over 4 years
    @Rakk - When I use success or failure I get an error Error when executing failure post condition: groovy.lang.MissingPropertyException: No such property: build for class: groovy.lang.Binding . I'm using this in declarative pipeline
  • Rakk
    Rakk over 4 years
    @Prr I'm not sure but guessing you are using in build object. It is only be in pipeline object.
  • glerYbo
    glerYbo over 3 years
    The build status should be called SUCCESS, not SUCCESSFUL (at least in the recent Jenkins, when put in always/post block).
  • Dmitry
    Dmitry over 2 years
    that is half backed as post usually has some clean up routine that may fail and you will not get to the slack call as it should be done after all activities.