The post Section
The post section runs cleanup or notification steps after a stage or the whole pipeline, based on the result.
Syntax
post {
success { echo 'Passed!' }
failure { echo 'Failed!' }
always { cleanWs() }
}The post section defines steps that run after a pipeline or stage finishes, depending on the outcome. It is perfect for cleanup and notifications.
Post conditions
always— runs no matter what.success— only if everything passed.failure— only if something failed.unstable— if the build is unstable (e.g. test failures).changed— if the result differs from the previous run.aborted— if the build was manually stopped.
Where it goes
A post block can sit at the end of the whole pipeline or at the end of an individual stage.
Example
pipeline {
agent any
stages {
stage('Test') {
steps {
sh 'npm test'
}
}
}
post {
always {
echo 'This runs after every build.'
cleanWs()
}
success {
echo 'All good! Notifying the team.'
}
failure {
echo 'Build failed — sending an alert.'
}
}
}When to use it
- A post always block cleans the workspace and removes temporary Docker containers regardless of whether the build passed.
- A post failure block sends a Slack message with the build URL so the team knows immediately when a build breaks.
- A post success block tags and pushes the Docker image to a registry only after the entire pipeline passes.
More examples
Post with always and failure
Always cleans the workspace and emails the ops team when the pipeline fails.
pipeline {
agent any
stages {
stage('Build') { steps { sh 'make all' } }
}
post {
always { cleanWs() }
failure { mail to: '[email protected]',
subject: "FAILED: ${JOB_NAME} #${BUILD_NUMBER}",
body: env.BUILD_URL }
}
}Post success: push Docker image
Pushes a Docker image to a registry only when the pipeline succeeds.
post {
success {
sh """
docker tag myapp:build-${BUILD_NUMBER} registry/myapp:latest
docker push registry/myapp:latest
"""
echo "Image pushed to registry"
}
}Stage-level post block
Publishes JUnit results after every test run and archives the full reports on failure at the stage level.
stage('Test') {
steps { sh 'mvn test' }
post {
always { junit 'target/surefire-reports/*.xml' }
failure { archiveArtifacts 'target/surefire-reports/**' }
}
}
Discussion