Jenkins Pipelines - All at one Place!

·

5 min read

Introduction

In software engineering, CI/CD or CICD is the combined practice of continuous integration (CI) and (more often) continuous delivery or (less often) continuous deployment (CD).

CI and CD stand for continuous integration and continuous delivery/continuous deployment. In very simple terms, CI is a modern software development practice in which incremental code changes are made frequently and reliably.

CI/CD allows organizations to ship software quickly and efficiently. CI/CD facilitates an effective process for getting products to market faster than ever before, continuously delivering code into production, and ensuring an ongoing flow of new features and bug fixes via the most efficient delivery method.

CI/CD is a DevOps tactic, which makes use of the right automated testing tools to implement agile development.

This results in the need for proper continuous integration and continuous delivery (CI/CD) tools

One of the most widely used tools is JENKINS

JENKINS

Jenkins is an open-source continuous integration/continuous delivery and deployment (CI/CD) automation software DevOps tool written in the Java programming language. It is used to implement CI/CD workflows, called pipelines.

Jenkins Pipeline

Jenkins provides

Scripted Pipeline

Declarative Pipeline

Few points to be noted on Jenkins scripted and declarative pipelines

Scripted Pipeline provides more flexibility and control over the pipeline workflow, while Declarative Pipeline provides a simpler and more structured syntax.

Jenkins declarative pipelines provide a simplified and more friendly syntax with specific statements for defining them, without needing to learn Groovy

Unlike Declarative, Scripted Pipeline is effectively a general-purpose DSL built with Groovy

Declarative pipelines break down stages into individual stages that can contain multiple steps. Scripted pipelines use Groovy code and references to the Jenkins pipeline DSL within the stage elements without the need for steps.

We, in our organization, are using Declarative pipelines with stages and steps defined

Docker as an agent in the Jenkins pipeline

The pipelines will be executed on a node. A node is a machine that is part of the Jenkins environment and is capable of executing a pipeline

A node can be an ec2 instance with any OS on which we can execute our pipeline. It's better to use Docker as our node for various reasons, one among which is Docker gets deleted immediately after executing the pipeline.

Please refer below links for a complete understanding

https://www.youtube.com/watch?v=zZfhAXfBvVA

https://www.jenkins.io/blog/2021/12/08/containers-as-build-agents/

and can be used as below (Referred from Abhishek veeramalla's Youtube videos)

Required fields of Jenkins pipeline

Post-actions in the Jenkins pipeline

post {
success {
mail to: team@example.com, subject: ‘The Pipeline success :(‘
}
}

post {
always {
echo ‘I will always execute this!’
}
}

post {
failure {
mail to: team@example.com, subject: ‘The Pipeline failed :(‘
}
}

Timeout in the stage of Pipeline

The declarative Jenkins Pipeline allows us to define timeout either at the pipeline level or the specific stage. This feature prevents Jenkins's job from getting stuck. However, in some cases, we want to accept that one stage may timeout, but we want to keep the remaining stages running.

pipeline {
    agent any
    stages {
        stage('Input') {
            steps {
                timeout(time: 10, unit: 'SECONDS') {
                    script {
                         def userInput = input message: 'Please enter a value:', parameters: [string(defaultValue: 'default value', description: 'Enter a value', name: 'inputValue')]
                         echo "User input: ${userInput}"
                         }
                 }
              }
     }
 }

}

The “timeout” step will allow the “input” step to run for 10 seconds before timing out. If the user does not provide input within the time specified, they terminate the build or move to the next step.

In this way, we can specify the maximum amount of time for a build to run.

Jenkins timeout feature is a valuable tool for preventing long-running builds from getting stuck or freezing and ensuring that builds do not consume excessive resources. This can help ensure that your Jenkins instance runs smoothly and efficiently.

Skip a stage in the Jenkins pipeline using the When Directive

pipeline {
    agent any
    parameters {
        booleanParam(name: 'skip_test', defaultValue: false, description: 'Set to true to skip the test stage')
    }
    stages {
        stage('Build') {
            steps {
                sh 'echo "Building application"'
                // Add build steps here
            }
        }
        stage('Test') {
            when { expression { params.skip_test != true } }
            steps {
                sh 'echo "Testing application"'
                // Add test steps here
            }
        }
        stage('Deploy') {
            steps {
                sh 'echo "Deploying application"'
                // Add deployment steps here
            }
        }
    }
}

Using Functions in Jenkins Pipeline to control workflow pipeline

pipeline {
    agent any
    parameters {
        booleanParam(name: 'skip_test', defaultValue: false, description: 'Set to true to skip the test stage')
    }
    stages {
        stage('Build') {
            steps {
                sh 'echo "Building the application"'
            }
        }
        stage('Test') {
            steps {
                execute_stage('Test', params.skip_test)
            }
        }
        stage('Deploy') {
            steps {
                sh 'echo "Deploying the application"'
            }
        }
    }
}

def execute_stage(stage_name, skip) {
    stage(stage_name) {
        if(skip) {
            echo "Skipping ${stage_name} stage"
            return
        }
        // Add steps to test the application
    }
}

Listing default Jenkins env variables

localhost:8080/env-vars.html

Using env variables in the Jenkins pipeline

Capturing sh command output in the env variable and passing the output to another step

pipeline {
    agent any

    stages {
        stage("Env Variables") {
            environment {
                COUNT_FILES =sh(script: "ls -la /tmp |wc -l", returnStdout: true).trim()
            }

            steps {
                script {
                    env.LS = sh(script:'ls -lah', returnStdout: true).trim()
                    echo "LS = ${env.LS}"
                    // or if you access env variable in the shell command
                    sh 'echo $LS'

                }
            }
            steps {
                echo "there are ${env.COUNT_FILES} files in /tmp folder"
            }
        }
    }
}

Reset the build Number to 1

Dashboard --> Manage Jenkins --> Script Console

Configure Upstream and downstream jobs in Jenkins

In many cases, we want to trigger another job, when one job completes successfully, instead of doing manually we will automate it via Jenkins pipeline

Job1 is successfully completed and triggers job2 and job2 successfully completes and triggers job3

for the same, we have to use the declarative directive generator to generate syntax

From the screenshots below job3 configuration has the below step which watches for the job2 build

triggers {

upstream 'job2, '

}

similarly, job2 has the configuration and watches out for job1

NOTE:- Comma is mandatory for jobname 'job1, '