I built something a bit simpler for my own needs, although it still requires the snippet in each stage.
I came here looking for a way to not repeat the error-getting in the post
section of every stage, and I love the above solutions. I may incorporate bits from the other answers into my library at some point.
I have an env.informationalMessages
var that is sent along with the notification emails at the end of every run.
In each stage you do an Unsuccessful post
section. This should capture failed
, aborted
, unstable
results. Cleanup runs after any other post conditions.
stage ('some stage name') {
steps { ... }
post {
unsuccessful {
addStageResultToInfoMessages()
}
cleanup {
// whatever else you want to do
}
}
}
vars/addStageResultToInfoMessages.groovy
:
// Adds a message with the stage result into the informationalMessages env var.
def call() {
addToInfoMessages("${currentBuild.result} in stage '${STAGE_NAME}'.")
}
vars/addToInfoMessages.groovy
// Adds the passed-in string to the informationalMessages env var
// that gets sent with notification emails.
// env.informationalMessages is initialized to '' at the start of each run.
def call(String message) {
env.informationalMessages += "${message}\n"
}
Then at the end of the pipe, another post
section:
post {
unsuccessful {
addToInfoMessages(getErrorMessage())
}
cleanup {
notifyEmail()
}
}
vars/getErrorMessage.groovy
grabs the raw console text from the Jenkins API and looks for the text 'ERROR:
'. The outdated Groovy in Jenkins doesn't support null-safe navigation on lists, so you have to do it old-school.
// gets the Error message from the run's console text
// uses the jenkins api
def call() {
// get the raw text of the build's console output
response = httpRequest ignoreSslErrors: true, url: "${BUILD_URL}consoleText"
// find lines with 'ERROR:'
err = response.getContent().findAll(/.*ERROR:.*/)
// if null-safe, split off the time code
if (err) { return err[-1].split('Z] ')[1] }
else { return 'Error not found' }
}
Just another way to do this.