A Simple Pipeline in Jenkins

In the previous two articles A Simple Freestyle Job in Jenkins and Build a Docker Image with a Jenkins Freestyle Job in this Jenkins series, we created freestyle jobs. Now it’s time to look into Pipeline jobs.

What is a Pipeline in Jenkins?

A pipeline is a sequence of steps that needs to be followed in order to a deliver a new version of software. It includes steps from checking in the latest code into SCM to delivering and deploying the final application to production system.

A Jenkins Pipeline is a set of plugins that supports implementing and integrating continuous delivery pipelines.

Jenkinsfile

All the stages and steps that define the pipeline are written in a file called the Jenkinsfile. This file is usually committed to the source code repository of the project so that it can be maintained and versioned along with the project.

Some benefits of keeping the Jenkins file in SCM could be listed as follows.

  • Creates a build pipeline for all the branches of the project automatically.
  • Reviewing the build pipeline code and making necessary changes is easier as it is maintained with the project.
  • Single source of truth for the pipeline as anyone involved in the project has access to the Jenkinsfile.

Jenkinsfile can be written in two syntax types.

  • Declarative – richer syntactical features, hence easier to write.
  • Scripted – advanced and complex compared to declarative syntax.

In this article, we will be focusing on the declarative syntax.

Declarative Pipeline Syntax

Skeleton of a Jenkinsfile written with declarative pipeline syntax would look like below.

pipeline{
    agent any 
    stages{
        stage('Build'){ 
            steps{
                echo "Building..."
            }
        }
        stage('Test'){ 
            steps{
                echo "Testing..."
            }
        }
        stage('Deploy'){ 
            steps{
                echo "Deploying..."
            }
        }
    }
}

Let me explain each block in above skeleton code.

  • pipeline – everything that happens throughout the pipeline is defined inside the pipeline block.
  • agent – specifies where to execute the pipeline. Instructs Jenkins to allocate an executor and a workspace for the pipeline. Mostly relevant when you have a Jenkins cluster with master and slave nodes.
  • stages – a distinct collection of tasks that happen during the pipeline are defined in a particular stage in the pipeline. There are many stages in a pipeline such as build stage, test stage and deployment stage.
  • steps – tasks within a stage, such as executing shell commands.

Now let’s look at how to convert the freestyle job we configured in the previous article into a pipeline job.

Jenkinsfile for Our Application

Now this is the same Spring Boot project we used in the previous articles. We are going to build the project with maven in the first stage. Then we will build the Docker image and push it to Docker Hub. You can find the GitHub repository for this project here.

Jenkinsfile for this pipeline would look like below.

pipeline{
    agent any
    tools{
        maven "maven-3.8"
    }
    stages{
        stage('Build and package war file') {
            steps{
                script{
                    echo "Packaging war file..."
                    sh "mvn clean package -Dmaven.test.skip=true"
                }
            }
        }
        stage('Build Docker image'){
            steps{
                script{
                    echo "Building Docker image..."
                    withCredentials([usernamePassword(credentialsId: "dockerhub-credentials", usernameVariable: "username", passwordVariable: "password")]){
                        sh "docker build -t dcharith/mobile-app-ws:2.0 ."
                        sh "echo $password | docker login -u $username --password-stdin"
                        sh "docker push dcharith/mobile-app-ws:2.0"
                    }
                }
            }
        }
        stage('test'){
            steps{
                echo 'This is the test step!'
            }
        }
        stage('deploy'){
            steps{
                echo 'This is the deploy step!'
            }
        }
    }
}
Important parts of this Jenkinsfile
  • Line 3 – tools section specifies maven-3.8. This is because we are using Maven 3.8 to build this project. Note that you must have maven-3.8 already added as a build tool from Jenkins UI and you should give the correct ID here. You can find more details here.
  • Line 7 – denotes the start of the first stage of our pipeline. In this stage, we are building the project using Maven. Notice that the mvn -Dmaven.test.skip=true clean package command is inside another block called script, which inside the steps block. sh here is a step in the pipeline that will execute the shell command given inside the quotes.
  • Line 15 – denotes the start of the second stage. In this stage, we are building the Docker image.
  • Line 19 – all our docker commands go inside this withCredentials block. credentialsId here refers to the ID we gave for Docker Hub credentials in Jenkins credentials configuration. Make sure to look this up from Jenkins UI and give the correct value here. You can read more about how to add credentials here. To find the credentials ID, from Jenkins home page, navigate to Manage Jenkins -> Manage Credentials and copy the correct ID as shown in below picture.

    usernameVariable and passwordVariable are used to pass username and password as variables when logging into docker in line 21.
Jenkins credentials

I hope the other lines are self explanatory. (If not, feel free to drop a comment 🙂 )

Once the file is written, we can check it into the source code repository of our project. This file should usually be in the root directory of the project.

Configure the Pipeline Job

To configure the pipeline, in Jenkins dashboard, click on “New Item”.

Create new item in Jenkins

Give an appropriate name and create a Pipeline job.

Create Pipeline job

Scroll down to the Pipeline section and fill in the details as below.

Pipeline script from SCM
  • Select “Pipeline script from SCM” from the drop down. What this will do is fetch the Jenkinsfile from the source code repository. Therefore it should be in our GitHub repository as I mentioned previously.
  • Select Git as the SCM.
  • Give the correct URL to the Git repository.
  • Select correct credentials for the repository.

Scroll further down and fill in following details as well.

Branches to build
  • Specify the branch you want to build in “Branch Specifier” field. To build multiple branches, there is another pipeline type called multi-branch pipelines, which we will discuss in the next article.
  • Repository browser can be “Auto”.
  • Script path should be Jenkinsfile. It is the convention to name the Jenkinsfile as such, so better to follow it as a good practice.

Once done, click save and we are ready to build!

Run the Pipeline in Jenkins

To run the pipeline, simply click on “Build Now” as highlighted.

Pipeline job in progress

You can see that the build is in progress from the Build History section. In above example, it has finished checking out code from SCM and installing build tools successfully and in the progress of packaging the war file using Maven as shown in stage view.

Once all stages are completed, you can see the completed pipeline build as below.

Successfully completed pipeline

We can see the console output of our pipeline by clicking on the date under build history highlighted above.

Share this article if it was helpful!

Leave a Reply

Your email address will not be published. Required fields are marked *