Jenkins: Multibranch Pipelines & Parallel Stages
Level up Jenkins by running builds for every branch automatically, parallelising slow stages, and controlling flow with post conditions and input gates.
After you understand basic Jenkins pipelines, the next step is scaling them: automating per-branch builds, running slow test suites in parallel, and adding promotion gates for production deploys.
Learning outcomes
By the end you can:
- configure a Multibranch Pipeline project
- run stages in parallel
- use
postconditions for notifications and cleanup - add manual
inputgates before production releases
1) Multibranch Pipeline
A Multibranch Pipeline automatically discovers branches and PRs in your repo.
Each branch’s Jenkinsfile defines its own pipeline.
How to set it up
- In Jenkins, click New Item → Multibranch Pipeline
- Under Branch Sources, add your Git repo URL and credentials
- Set scan interval (e.g., every 5 minutes) or use a webhook
- Jenkins creates and runs a job for each branch with a
Jenkinsfile
Branch-aware Jenkinsfile
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'npm ci'
sh 'npm run build'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
stage('Deploy to Staging') {
// Only run on the main branch
when {
branch 'main'
}
steps {
sh './scripts/deploy.sh staging'
}
}
stage('Deploy to Production') {
when {
branch 'main'
}
input {
message "Deploy to production?"
ok "Deploy Now"
submitter "team-lead,devops-team"
}
steps {
sh './scripts/deploy.sh production'
}
}
}
}
2) Parallel stages
Run independent stages at the same time to reduce pipeline duration.
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'npm ci'
sh 'npm run build'
}
}
stage('Test Suite') {
parallel {
stage('Unit Tests') {
steps {
sh 'npm run test:unit'
}
}
stage('Integration Tests') {
agent { label 'integration-runner' }
steps {
sh 'npm run test:integration'
}
}
stage('Lint') {
steps {
sh 'npm run lint'
}
}
}
}
stage('Security Scan') {
steps {
sh 'npm audit --audit-level=high'
}
}
}
}
failFast: true inside parallel {} aborts siblings as soon as one fails—useful when you want fast feedback:
stage('Tests') {
parallel {
failFast true
stage('Unit') { steps { sh 'npm run test:unit' } }
stage('E2E') { steps { sh 'npm run test:e2e' } }
}
}
3) Post conditions
post blocks run after stages complete, regardless of result.
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'npm ci && npm run build'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
}
post {
always {
// Always clean up workspace
cleanWs()
}
success {
// Notify on success
echo "Build ${env.BUILD_NUMBER} succeeded on branch ${env.BRANCH_NAME}"
}
failure {
// Alert the team on failure
emailext(
to: 'team@example.com',
subject: "Build Failed: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
body: "Check ${env.BUILD_URL} for details."
)
}
unstable {
// Tests ran but some failed (non-fatal)
echo "Build is unstable—check test results"
}
}
}
4) Environment variables and build parameters
pipeline {
agent any
parameters {
string(name: 'APP_VERSION', defaultValue: '1.0.0', description: 'Version to deploy')
choice(name: 'TARGET_ENV', choices: ['staging', 'production'], description: 'Target environment')
booleanParam(name: 'SKIP_TESTS', defaultValue: false, description: 'Skip test stage')
}
environment {
// Static values
REGISTRY = 'registry.example.com'
IMAGE_TAG = "${params.APP_VERSION}-${env.BUILD_NUMBER}"
}
stages {
stage('Test') {
when {
expression { !params.SKIP_TESTS }
}
steps {
sh 'npm test'
}
}
stage('Build Docker Image') {
steps {
sh "docker build -t ${REGISTRY}/myapp:${IMAGE_TAG} ."
sh "docker push ${REGISTRY}/myapp:${IMAGE_TAG}"
}
}
stage('Deploy') {
steps {
sh "./scripts/deploy.sh ${params.TARGET_ENV} ${IMAGE_TAG}"
}
}
}
}
5) Stashing files between stages on different agents
If your stages run on different agents, use stash/unstash to pass files:
stage('Build') {
agent { label 'build-server' }
steps {
sh 'npm ci && npm run build'
stash name: 'dist', includes: 'dist/**'
}
}
stage('Test') {
agent { label 'test-server' }
steps {
unstash 'dist'
sh 'npm test'
}
}
Next steps
- Jenkins Shared Libraries: reusable pipeline code across teams
- Jenkins + Docker: containerised build agents
- Integrate with Terraform and Ansible for infrastructure deployments