Notifications That People Actually Read
Send targeted build alerts to Slack or email from the post section, notify only on state changes, and include the context needed to act fast.
A notification nobody reads is worse than none — it trains the team to ignore the channel. Good pipeline notifications are rare, targeted, and actionable.
Notify from post, keyed by result
Put alerts in the post block so they reflect the real outcome. Use failure and unstable for the noisy channel, and consider fixed (via post { fixed { ... } }) to celebrate a return to green. Avoid pinging on every single success — that is pure noise.
Notify on change, not every build
The senior move is alerting only when the build status changes — green to red, or red back to green. A job that has been failing for an hour does not need a fresh ping every five minutes. The changed and fixed post conditions express exactly this.
Make it actionable
Include the branch, the commit author, a one-line failure reason, and a direct link to the console (env.BUILD_URL). The person reading it should be able to decide what to do without opening Jenkins first.
Example
pipeline {
agent any
stages {
stage('Build') { steps { sh 'make build' } }
stage('Test') { steps { sh 'make test' } }
}
post {
failure {
// fires the moment a passing job goes red
slackSend(
channel: '#ci-alerts',
color: 'danger',
message: "FAILED ${env.JOB_NAME} #${env.BUILD_NUMBER}\n" +
"Branch: ${env.BRANCH_NAME} by ${env.CHANGE_AUTHOR ?: 'unknown'}\n" +
"Logs: ${env.BUILD_URL}console"
)
}
fixed {
// fires once when a red job returns to green
slackSend(
channel: '#ci-alerts',
color: 'good',
message: "RECOVERED ${env.JOB_NAME} #${env.BUILD_NUMBER} is green again."
)
}
}
}When to use it
- A team configures Slack alerts to fire only on fixed and failure transitions so engineers are not spammed on every successful run.
- An on-call engineer receives a pager alert via PagerDuty webhook when a production deploy pipeline fails.
- Build notifications include the committer name and branch so the right person acts on a failure without digging through logs.
More examples
State-change Slack notifications
Notifies Slack only on failure and recovery transitions, including the committer name and build URL.
post {
failure {
slackSend channel: '#ci-alerts',
color: 'danger',
message: "FAILED: ${JOB_NAME} #${BUILD_NUMBER} by ${env.GIT_COMMITTER_NAME}\n${BUILD_URL}"
}
fixed {
slackSend channel: '#ci-alerts',
color: 'good',
message: "RECOVERED: ${JOB_NAME} #${BUILD_NUMBER}"
}
}Email on failure with log attachment
Sends a failure email with the last 50 lines of the build log and the full log as an attachment.
post {
failure {
emailext(
subject: "FAILED: ${JOB_NAME} #${BUILD_NUMBER}",
body: '${BUILD_LOG, maxLines=50}',
to: '${DEFAULT_RECIPIENTS}',
attachLog: true
)
}
}PagerDuty webhook on prod failure
Triggers a critical PagerDuty incident when the main branch pipeline fails using the Events API v2.
post {
failure {
when { branch 'main' }
withCredentials([string(credentialsId: 'pd-routing-key',
variable: 'PD_KEY')]) {
sh """
curl -X POST https://events.pagerduty.com/v2/enqueue \\
-H 'Content-Type: application/json' \\
-d '{"routing_key":"$PD_KEY","event_action":"trigger",
"payload":{"summary":"${JOB_NAME} failed","severity":"critical"}}'
"""
}
}
}
Discussion