CI/CD: The Jenkins Way

First, There was Waterfall model, software builds took a long time to develop and then deployment alone was time-consuming. Now, Agile, revolutionizing the way we follow the development cycle making it faster, deliverables have the same quality and they are delivered much faster.

Bang! and Now we have Dev Ops.. Where the Agile methodology releases build annually, quarterly or monthly, Dev Ops speed up the delivery to weeks, days or daily. It is obvious that speed is dangerous but then what’s the point of making a Lamborghini and then selling it at such a high price.

So the steps are simple. You write code. You push the code to Version Control System like git. The build is tested. The build is deployed. The application is Live. Easy to write, both, the previous lines and the upcoming ones.

Jenkins is that software which allows you to configure your Continous Integration/ Continous Deployment. The ease, it provides is, can only be felt when done. Jenkins allows us to specify a CD pipeline which we discussed in my last post. Before you read further, feel free to go back.

Deployment part will be done through Docker. Now before you bite your fingers just bear with me and witness the ease.

Pre-Requisites

  1. A Java-based Project because We’ll use maven.(Fork the git repo)
  2. Basics of pipeline syntax.
  3. CI/CD
  4. Docker

Process

The summary of CI/CD lifecycle is this

plan -> code -> build -> test -> release -> deploy -> operate -> monitor

Considering that our project is ready and has test suite ready to run we can then do the CI/CD stages with the help of Jenkins. We are now aware of the Jenkins pipelines and the basic syntax.

Here we are going to create a Jenkins file and commit it to our project. It is recommended that you cut a branch of your project to do this step. To learn how to do that, here you go.

Step 1: Creating a jenkinsfile.

CI is:

  • blend works of different developers into one repo.
  • used to detect early bugs.
  • increases dev collaboration, gives tight cohesion.

Standing in your project directory hit the following command from your command prompt.
>gedit jenkinsfile

we will specify the agent where the build is to be deployed

agent {
 docker{
  image 'maven:3-alpine'
  args '-v /root/.m2:/root/.m2'
  }
 }

here we specify docker as the agent, usually, we put the name of any remote node or for starters we just specified any with agent i.e agent any
the idea is to run the build with the help of maven image as specified in image option of docker

One more important point to note is args option provided in the docker option. args allows us to specify external arguments we will use it cache the ~/.m2 directory, this is advantageous because then dependencies will not be download for every build.

Step 2: Add maven-jar-plugin to pom.xml

We need the jar plugin in order to develop the jar file of the project we are working on. This jar file will then be executed on the docker container.

You have to add the following dependency in the section of the pom.xml :

<dependency>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>>
    <version>3.0.2</version>
</dependency>

and add the following content in the section in the pom.xml of your project to specify the file containing the main method of the project:

<plugin>
    <!-- Build an executable JAR -->
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.0.2</version>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>edu.knoldus.model.Application</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

Step 4: Adding steps to complete the CD steps

CD is:

  • extends CI
  • allows easy and confident deployments at any time
  • centered around CD pipeline.

Now we will define the stages section of the Jenkins file to define all the steps build must go through before it gets deployed.
We will put the maven commands using sh of jenkinsfile as we do on the local terminal or IDE terminals.

Let’s initialize the project with maven environment which will help in deployment and building the jar file:

stage('build'){
    steps{
      sh 'mvn -B -DskipTests clean package'
     }  
 }

Now we will look for checkstyle warnings:

stage('checkstyle'){
steps{
sh 'mvn checkstyle:checkstyle'
}
}

let’s execute some test cases and store the reports also:

stage('test'){
        steps{
            sh 'mvn test'
             }
        post{
          always{
            junit 'target/surefire-reports/*.xml'
            }
          }
   }

Jenkins provides the junit step for the putting the test results in a file under the specified directory. post signifies the steps in this section will be executed after the steps of the stage are executed. always section executes whatever steps you will write there no matter what.

Step 5: Let’s deliver the project

We are going to create a script file for this because:

  1. More manageability
  2. Clean and concise jenkinsfile.

to deliver the project we will execute the jar file. We will create deliver.sh script file and add the following content.

set -x
mvn jar:jar install:install help:evaluate -Dexpression=project.name
set +x

set -x
NAME=`mvn help:evaluate -Dexpression=project.name | grep "^[^\[]"`
set +x

set -x
VERSION=`mvn help:evaluate -Dexpression=project.version | grep "^[^\[]"`
set +x

set -x
java -jar target/${NAME}-${VERSION}.jar

set -x & set +x are used to turn off the redundant info to be printed on the console, they are related to the Jenkins environment. You can remove them to convince yourself.

The first thing which we are doing is creating the jar and then installing the jar in the container for execution later. NAME variable contains the project name. VERSION contains the version of your build.

The last statement is executing the jar.

Now we will just have to put the reference to this script in the deliver section of jenkinsfile as follows:

stage('Deliver') {
   steps {
   sh './scripts/deliver.sh'
     }
   }

Cheers.
GitHub:Fork This Repo

knoldus-advt-sticker

Written by 

Vinay is a software consultant having more than 0.5 years of experience. He likes to keep up with the trending technologies. Vinay is familiar with languages such as C++, Java, Scala and is currently working on DevOps technologies /tools like DC/OS, Jenkins, Ansible, Docker. His hobbies includes writing, gaming, and sketching.

Leave a Reply

%d bloggers like this: