Pipelines as Code
A Jenkinsfile turns your build into versioned, reviewable code.
Freestyle jobs live in the UI, invisible to version control. The modern way is pipeline as code: a Jenkinsfile committed alongside your source. Now your build process is versioned, reviewed in pull requests, and reproducible β just like your application.
π― Learning Objectives
By the end of this lesson you will:
- Understand declarative pipeline structure
- Write a
Jenkinsfilewith stages and steps - Use
postactions for success/failure handling - Know where credentials and environment variables fit
The Declarative Pipeline
Jenkins has two pipeline syntaxes: declarative (structured, recommended) and scripted (full Groovy, advanced). Weβll use declarative β itβs cleaner and covers the vast majority of needs.
The skeleton:
pipeline {
agent any // where to run
stages {
stage('Build') {
steps {
echo 'Building...'
}
}
}
}Every declarative pipeline has an agent (where it runs) and stages (the ordered phases of work).
A Real Jenkinsfile
Hereβs a complete build-test pipeline:
pipeline {
agent any
environment {
CI = 'true'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Install') {
steps {
sh 'npm ci'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
stage('Build') {
steps {
sh 'npm run build'
}
}
}
post {
success { echo 'Pipeline succeeded β
' }
failure { echo 'Pipeline failed β' }
always { echo 'Cleaning up...' }
}
}Jenkins visualises each stage as a column, so you instantly see where a build passed or failed.
Post Actions
The post block runs after the stages, based on the outcome:
| Condition | Runs when |
|---|---|
success |
The pipeline succeeded |
failure |
The pipeline failed |
unstable |
Tests passed but flagged issues |
always |
Regardless of outcome (cleanup, notifications) |
π‘ Use post for notifications
post { failure { ... } } is the natural place to send a Slack/email alert when a build breaks, and always is where you clean up workspaces or archive logs.
Credentials in a Pipeline
Never hard-code secrets. Store them in Jenkinsβ Credentials store and inject them safely:
environment {
AWS_TOKEN = credentials('aws-deploy-token')
}
stages {
stage('Deploy') {
steps {
sh './deploy.sh' // AWS_TOKEN is available, masked in logs
}
}
}β Credentials are masked, not invisible
The credentials() helper masks the value in logs, but you must still avoid printing or exporting it carelessly. Reference it only where needed, and prefer scoped credentials over global ones.
Multibranch Pipelines
Point Jenkins at a repo as a multibranch pipeline and it automatically discovers every branch (and pull request) with a Jenkinsfile, creating a pipeline for each. Push a new branch β Jenkins builds it, no manual job setup.
π‘ Jenkinsfile in the repo = automatic pipelines
Because the pipeline definition travels with the code, each branch can even evolve its own build steps. This is the Jenkins equivalent of GitHub Actions discovering workflows in .github/workflows/.
π§ͺ Hands-on Lab
Write a Jenkinsfile
- Create a
Jenkinsfilewith Checkout, Install, Test, and Build stages - Add a
postblock that reports success and failure - Explain why committing this to the repo is better than a freestyle job
π§ Knowledge Check
What is the main benefit of defining a pipeline in a Jenkinsfile committed to the repository?
Which post condition is the right place to send an alert when a build breaks?
πΌ Interview Preparation
Compare declarative and scripted pipelines, and explain stages and steps.
Summary
You can now write a declarative Jenkinsfile with stages, steps, post actions, and credentials β and understand multibranch pipelines. Next, youβll extend this into a full CI/CD pipeline that deploys.