Jenkins is an automation tool widely used for Continuous Integration (CI) and Continuous Delivery (CD). It helps
automate various stages of the software development process, including building, testing and deploying.
Pipeline
In Jenkins, to automate the stages of the software development process, we can define a pipeline. A pipeline is a set of
stages that are linked together to form a processing system, executed sequentially.
A Jenkins pipeline can be in two formats.
- Declarative format
- Scripted format
Both formats are written in Groovy. The Scripted pipeline provides more flexibility than the Declarative format but is more verbose.
We will discuss Declarative format.
Basic Structure
Basic structure of a pipeline consists of
P — pipeline
A — agent
S — stages
S — stage
S — steps
Pipeline — all stages, steps, post actions etc. will be defined in this block.
pipeline {
// Pipeline configuration written here
}
Agent — is a node or container that connects to a Jenkins controller and executes tasks as directed by the Jenkins
controller. To use any available node or agent, we can use the any keyword.
pipeline {
agent any
}
Stages — define the sequence of stages that will be executed in a pipeline. We can have only one stages block.
pipeline {
agent any
stages {
// Consists of different stage executions
}
}
Stage — is used to define the steps to execute a process.
pipeline {
agent any
stages {
stage ("Stage name"){
// Consists of steps to execute a stage
}
}
}
Steps — used to define set of instructions to perform in a stage. Only one steps block is allowed in a stage.
pipeline {
agent any
stages {
stage ("Stage name"){
steps {
// Set of instructions of the stage
}
}
}
}
Basic Structure
pipeline {
agent any
stages {
stage ("Build"){
steps {
sh "echo Build stage"
}
}
stage ("Test"){
steps {
sh "echo Test stage"
}
}
stage ("Quality"){
steps {
sh "echo Quality stage"
}
}
stage ("Deploy"){
steps {
sh "echo Deploy stage"
}
}
}
}
Timeout & Retry
Timeout
Sometimes build can hang, due to unresponsive process, in that case we can wrap the step using timeout, when a step takes long time then expected, timeout will abort the pipeline.
pipeline {
agent any
stages {
stage("Deploy"){
steps {
timeout(time: 3, unit: 'MINUTES') {
sh "./deploy.sh"
}
}
}
}
}
In this pipeline, if deploy.sh script takes more than 3 minutes, timeout will abort the pipeline.
Retry
When there is an exception while executing a stage sometimes retrying would solve the case. In Jenkins we can retry block.
pipeline {
agent any
stages {
stage("Deploy"){
steps {
retry {
sh "./deploy.sh"
}
}
}
}
}
Here, deploy.sh script will be executed at max 3 times, if there is an exception.
We can use timeout inside retry block and vice versa. If we want to retry the steps for n times but don't want to spend more than m minutes, we can nest retry block inside timeout block.
pipeline {
agent any
stages {
stage("Deploy"){
steps {
timeout(time: 3, unit: 'SECONDS') {
retry(3){
sh "./deploy.sh"
}
}
}
}
}
}
Here, pipeline will fail if total time exceeds 3 minutes, or script throws exception even after 3 times.
If we want to retry for n times with m minutes for each retry, we can next timeout in a retry block.
pipeline {
agent any
stages {
stage("Deploy"){
steps {
retry(3){
timeout(time: 3, unit: 'MINUTES'){
sh './deploy.sh'
}
}
}
}
}
}
Post Actions
Post block in Jenkins pipeline is used to handle tasks not limited to, sending notifications, cleanup, and archiving artifacts, at the end of pipeline based on the outcome of pipeline.
Post block is a sibling block to stages.
Some of the post actions are:
always
Used to execute set of actions irrespective of pipeline outcome. It has high priority and runs first.
pipeline {
agent any
post {
always {
sh "echo Always block will get executed irrespective of pipeline status"
}
}
}
changed
Executes if pipeline's current state differs from previous state and will be executed just after always block.
pipeline {
agent any
post {
changed {
sh "echo Pipeline state defers from previous state"
}
}
}
success
Executes only if pipeline completes successfully.
pipeline {
agent any
post {
success {
sh "echo Executes if pipeline completes successfully"
}
}
}
failure
Executes only if pipeline fails.
pipeline {
agent any
post {
failure {
sh "echo Executes if pipeline fails"
}
}
}
aborted
Executes if pipeline is aborted.
pipeline {
agent any
post {
aborted {
sh "echo Pipeline is aborted"
}
}
}
unstable
Executes when pipeline is marked as unstable.
pipeline {
agent any
post {
unstable {
sh "echo Pipeline is unstable"
}
}
}
unsuccessful
Executes when the pipeline is aborted, failed, or unstable.
pipeline {
agent any
post {
unsuccessful {
sh "echo Pipeline did not complete successfully"
}
}
}
fixed
Executed when the pipeline’s current state is successful and the previous state was failed or unstable.
When post block has both success and fixed blocks, the fixed block will be executed before success block.
pipeline {
agent any
post {
fixed {
sh "echo Pipeline fixed"
}
}
}
regression
In general regression refers to a situation where there is a decline or deterioration in quality or performance.
In the context of Jenkins, regression block get executed, when the pipeline’s current state deteriorates from a previous successful or unstable state to a failed, aborted, or unstable state, but both the previous and current states cannot be unstable at the same time.
pipeline {
agent any
post {
regression {
sh "echo Pipeline deteriorated to ${currentBuild.currentResult}"
}
}
}
cleanup
Used for removing or managing resources and files that are not needed after a build has completed. This ensures workspace remains clean and helps avoid potential issues from leftover files from previous builds.
It will be executed after all post blocks.
pipeline {
agent any
post {
cleanup {
sh "./clean-up.sh"
}
}
}
Top comments (0)