12

I'm trying to convert an existing Jenkins Pipeline to the new Declarative Pipeline and I was wondering how to handle correctly mail notifications ?

I'm currently using this code:

node {
   try {

      ...

      currentBuild.result = 'SUCCESS'
   } catch (any) {
       currentBuild.result = 'FAILURE'
       throw any
   } finally {
       step([$class: 'Mailer',
           notifyEveryUnstableBuild: true,
           recipients: "baptiste.wicht@gmail.com",
           sendToIndividuals: true])
   }
}

It works well, but I don't see how to use the new declarative syntax for this. I think something could be done by using post() and the different notifications, but I don't know exactly how. I've tried this:

post {
    always {
        step([$class: 'Mailer',
            notifyEveryUnstableBuild: true,
            recipients: "baptiste.wicht@gmail.com",
            sendToIndividuals: true])
    }
}

But the problem is that it does not send any "Back to normal" mail.

How can I used the Mailer plugin in a Jenkins declarative pipeline in order to send "Back to normal" mails ?

Should use again a try/catch around all declarative syntax ?

Baptiste Wicht
  • 7,472
  • 7
  • 45
  • 110

4 Answers4

13

This can be done a lot simpler now by using the fixed post-condition (Documentation).

Here's a quick example I wrote up in my sandbox pipeline project.

pipeline{
    agent {
        label 'Build'
    }
    stages{
        stage('Build'){
            steps{
                script{
                    echo "Building..."
                }
            }
        }
    }
    post{
        success {
            echo "Success"
        }
        failure {
            echo "Failure"
        }
        fixed {
            echo "Back to normal"
        }
    }
}
German
  • 270
  • 2
  • 9
10

Send mail when build fails. When a build succeeds you're going to check if the previous build was successful. If it wasn't, you'll send a mail to tell the user it's working again.

    post {

        failure {
            mail to: 'user@mail.com',
            subject: "Failed Pipeline: ${currentBuild.fullDisplayName}",
            body: "Build failed: ${env.BUILD_URL}"
        }

        success {
            if (currentBuild.previousBuild != null && currentBuild.previousBuild.result != 'SUCCESS') {
                mail to: 'user@mail.com',
                subject: "Pipeline Success: ${currentBuild.fullDisplayName}",
                body: "Build is back to normal (success): ${env.BUILD_URL}"     
            }           
        }
    }
lvthillo
  • 28,263
  • 13
  • 94
  • 127
8

you can check the previous build like an all-star:

pipeline {
  agent { label 'docker' }
  stages {
    stage ('build') {
      steps {
        sh 'ls'
      }
    }
  }
  post {
    always {
      script {
        if (currentBuild.result == null || currentBuild.result == 'SUCCESS') {
          if (currentBuild.previousBuild != null && currentBuild.previousBuild.result != 'SUCCESS') {
            echo 'send your back to normal email here, maybe something like this, your mileage may vary'
            emailext (
              subject: "Back to normal: ${currentBuild.fullDisplayName}",
              body: "Project is back to <blink>normal</blink>",
              mimeType: 'text/html',
              recipientProviders: [[$class: 'RequesterRecipientProvider'], [$class: 'DevelopersRecipientProvider']]
            )
          }
        }
      }
    }
  }
}
burnettk
  • 13,557
  • 4
  • 51
  • 52
7

Problem is that in the post section of declarative the currentBuild.result is not set to SUCCESS. FAILURE and ABORTED is set though. So the behaviour here seems to be inconsistent at the moment.

I've improved my answer from How to get same Mailer behaviour for Jenkins pipeline to handle this case better:

pipeline {
  agent any
  stages {
      stage('test') {
        steps {
            echo 'some steps'        
            // error("Throw exception for testing purpose..")
        }
      }
  }
  post {
      always {
          script {
              if (currentBuild.result == null) {
                  currentBuild.result = 'SUCCESS'    
              }
          }    
          step([$class: 'Mailer',
            notifyEveryUnstableBuild: true,
            recipients: "test@test.com",
            sendToIndividuals: true])
      }
  }
}
Philip
  • 2,959
  • 1
  • 17
  • 22
  • I wouldn't say that the behaviour is inconsistent. In fact, Jenkins will only set the result after the build. Everything we do in our pipelines is during the build. Therefore the result will be always `null`, if there isn't any kind of error during the build. It would have been much better not to have a result, but status. So during the build, the status could be `RUNNING`. – Oliver Oct 17 '21 at 18:42