0

I would like to send an email in the following situations:

  • every time a run is failing, and
  • every time a run is not failing nor aborted, and the last not-aborted run was not failing (ie. ignoring aborted runs, status changed from failing to something else).

So far I know I can write a post section with a failure condition, like:

pipeline {
    […]
    post {
        failure {
            emailext(
                to: 'email@company.com',  // testing
                subject: "Status: ${currentBuild.result?:'SUCCESS'} - Job \'${env.JOB_NAME}:${env.BUILD_NUMBER}\'",
                body: """
                    <p>EXECUTED: Job <b>\'${env.JOB_NAME}:${env.BUILD_NUMBER}\'</b></p>
                    <p>View console output at "<a href="${env.BUILD_URL}"> ${env.JOB_NAME}:${env.BUILD_NUMBER}</a>"</p>"""
            )
        }
    }
}

and this handles the first part. But none of the other conditions available in the post section seem to match my intents: the only conditions that consider the past are changed, fixed and regression, but the first is too generic, fixed requires the run to be successful (and I also want unstable), and regression obviously goes in the wrong direction.

How can I do that?

liori
  • 40,917
  • 13
  • 78
  • 105

2 Answers2

1

I think you would need to switch from declarative pipeline to scripted pipeline to do what you want.

Interesting reference: Jenkins scripted pipeline or declarative pipeline

Don't forget that you don't need to switch the whole file. You can have a script block in a declarative pipeline.

See example 35 there: https://jenkins.io/doc/book/pipeline/syntax/

  • Thank you, that's very helpful. I was convinced that I would have to choose either declarative or scripted — I've read the page you linked before, but somehow missed that specific example. Now I only need to figure out how to find build statuses for the current and previous jobs, but I think I've seen examples doing that in the scripted pipeline version. – liori Jan 14 '20 at 14:43
0

A full solution I coded based on @Simon Martineau's answer, reading Groovy's tutorial, an answer on devops.SE, an answer on SO and documentation on currentBuild is as follows:

post {
    always {
        script {
            // see https://stackoverflow.com/a/59739297/42610 for details
            if (currentBuild.currentResult == 'ABORTED') {
                return
            }

            def previousBuild = currentBuild.previousBuild
            while(previousBuild != null && previousBuild.result == 'ABORTED') {
                echo "Skipping over an aborted build ${previousBuild.fullDisplayName}"
                previousBuild = previousBuild.previousBuild;
            }
            def isFailure = currentBuild.currentResult == 'FAILURE'
            def wasFailure = previousBuild.result == 'FAILURE'
            echo "Is: ${currentBuild.currentResult} (${isFailure})"
            echo "Was: ${previousBuild.result} (${wasFailure})"

            def status = null
            if (isFailure && !wasFailure) {
                status = 'New failure'
            } else if (isFailure) {
                status = 'Still failure'
            } else if (wasFailure) {
                status = 'Failure fixed'
            }

            if (status != null) {
                emailext(
                    to: 'email@company.com',
                    subject: "${status}: Job \'${env.JOB_NAME}:${env.BUILD_NUMBER}\'",
                    body: """
                        <p>EXECUTED: Job <b>\'${env.JOB_NAME}:${env.BUILD_NUMBER}\'</b></p>
                        <p>Status: <b>${status}</b> (currently: ${currentBuild.currentResult}, previously: ${previousBuild.result})</p>
                        <p>View console output at "<a href="${env.BUILD_URL}">${env.JOB_NAME}:${env.BUILD_NUMBER}</a>"</p>"""
                )
            }
        }
    }
}
liori
  • 40,917
  • 13
  • 78
  • 105