Stages, parallelism & post
Structure a pipeline that reports clearly.
Stages are how a pipeline tells its story. Each stage is a named phase — Build, Test, Package, Deploy — and Jenkins renders them as a row of boxes so anyone can see at a glance where a build is and where it failed. Good stage names turn a wall of log output into a readable status board, so name them for what they accomplish, not how.
stages {stage('Build') { steps { sh 'make build' } }stage('Test') { steps { sh 'make test' } }stage('Package') { steps { sh 'make package' } }}
Run independent work in parallel
When stages do not depend on each other — linting, unit tests, and a security scan, say — run them at the same time with a parallel block. The pipeline is only as slow as its longest branch instead of the sum of all of them, which keeps feedback fast and developers using CI rather than routing around it.
stage('Checks') {parallel {stage('Lint') { steps { sh 'make lint' } }stage('Unit') { steps { sh 'make test-unit' } }stage('Scan') { steps { sh 'make scan' } }}}
The post block: always report
The post block runs after the stages, with conditions — always, success, failure, unstable — so you can publish test results whatever happens, notify a channel on failure, and clean up the workspace unconditionally. This is how a pipeline stays informative even when it breaks: results and alerts are wired to run regardless of the outcome.
post {always { junit '**/test-results/*.xml' } // publish results no matter whatsuccess { echo 'all green' }failure { mail to: 'team@acme.internal', subject: "Build ${env.BUILD_NUMBER} failed" }cleanup { cleanWs() } // always tidy the workspace}