Introduction to the Jenkinsfile

Reading Time: 5 minutes

What is Jenkinsfile?

 

In Jenkins most of the time we create pipelines from the Jenkins UI (User Interface) or Dashboard, this requires additional effort to create and manage work to test and build multiple projects, it also keeps the configuration of a job to build, test or deploy separately from the actual code being built, tested or deployed., but the interesting thing is that we can achieve the same using a file. Jenkinsfile helps you to create the pipelines as a code. You can implement pipeline as code, you just need to write a script (scripted pipeline) and this can be defined by using a domain-specific language (DSL). Jenkinsfile is added with the source code that means you can add Jenkinsfile in your remote repository with your source code.

It is generally considered a best practice to create a Jenkinsfile and check the file into the source control repository.

Why to use Jenkinsfile?

  • You can create pipelines automatically for all branches and execute pull requests with just one JenkinsFile.
  • Review for your Jenkins code on the pipeline is possible.
  • You can audit trail your Jenkins pipeline
  • This is the singular source of truth for your pipeline and multiple users can modify it .
  • It is reusable and one can use it in several different project with few changes only.

Pipeline Syntaxes Declarative v/s Scripted

Jenkins pipeline supports two different syntaxes

  1. Declarative Syntax
  2. Scripted Syntax
Declarative Syntax

Declarative pipeline syntax offers an easy way to create pipelines. It contains a predefined structure to create Jenkins pipelines. It gives you the ability to control all aspects of a pipeline execution in a simple, straightforward manner.

Scripted Syntax

The scripted pipeline was the first syntax of the Jenkins pipeline. We use groovy script inside node scope to define scripted pipeline, so it becomes a little bit difficult to start with for someone who doesn’t have an idea about groovy. Scripted Jenkins pipeline runs on the Jenkins master with the help of a lightweight executor. It uses very few resources to translate the pipeline into atomic commands. Both declarative and scripted syntax are different from each other and we define them differently.

Jenkinsfile (Declarative Pipeline)

pipeline {

    agent any
    tools {
        maven 'maven_3_5_0' 
    }
    stages {

         stage('Checkout Code from Git') {
               steps {
        git 'https://github.com/SaumyaBhushan/Selenium_Test_Automation.git'
    }
   }

    stage('compile stage') {
             steps {
                bat "mvn clean compile"
        }
    }

         stage('testing stage') {
             steps {
                bat "mvn test"
        }
    }

  }

}
Jenkinsfile (Scripted Pipeline)

node {

    tools{
        maven 'maven_3_5_0'
      }
    stage('Checkout Code from Git') {
        git 'https://github.com/SaumyaBhushan/Selenium_Test_Automation.git'
    }
    stage('Compile') {
        bat "mvn clean compile"
    }
    stage('Test') {
        bat "mvn test"
    }
}

Required field in syntax

In scripted pipeline everything, we write everything inside node{} so the node is the required field which is equivalent to pipeline and agent field in declarative syntax. Node is a crucial first step in a scripted pipeline as it allocates an executor and workspace for the Pipeline, without a node, a Pipeline cannot do any work.

In declarative syntax, the pipeline must be top-level. After that, we write the agent field which suggests which agent the pipeline should execute. Agent any means it will execute on any available agent. The agent directive, instructs Jenkins to allocate an executor and workspace for the Pipeline. Without an agent directive, not only is the Declarative Pipeline not valid, it would not be capable of doing any work!

The next one is stages where we define all the jobs or tasks that are going to be done. Inside the stages field, we can define various stages and steps. Inside steps, we write an actual script that will execute like mvn test, mvn install, etc.

Post Attribute in Jenkinsfile

It executes the mentioned logic after the execution of all the stages. Inside post there are different conditions that you can execute. These conditions are

  • always (example can be sending an email to the team after the bields run)
  • success
  • failure
post{

  always{
    // this condition always gets executed no matter if the field has been failed or succeeded
   }
  
  success{
    // execute script that are only relevant when the beilds succeed
   }
  
  failure{
    // execute script that are only relevant when the beilds failed
   }

}

Environmental Variable in Jenkinsfile

Jenkins Pipeline exposes environment variables via the global variable env, which is available from anywhere within a Jenkinsfile.

The full list of environment variables accessible from within Jenkins Pipeline is documented at localhost:8080/pipeline-syntax/globals#env, or http://localhost:8080/env-vars.html/ assuming a Jenkins master is running on localhost:8080, and includes:

BUILD_NUMBERThe current build number, such as “153”.

BUILD_IDThe current build ID, identical to BUILD_NUMBER for builds created in 1.597+, but a YYYY-MM-DD_hh-mm-ss timestamp for older builds.

BUILD_DISPLAY_NAMEThe displays name of the current build, which is something like “#153” by default.

JOB_NAMEName of the project of this build, such as “foo” or “foo/bar”.

BUILD_TAGString of “jenkins-${JOB_NAME}${BUILD_NUMBER}“. Replace all the forward slashes (“/”) in the JOB_NAME with dashes (“-“). Convenient to put into a resource file, a jar file, etc for easier identification.

EXECUTOR_NUMBER The unique number that identifies the current executor (among executors of the same machine) that’s carrying out this build. This is the number you see in the “build executor status”, except that the number starts from 0, not 1.

NODE_NAME Name of the agent if the build is on an agent, or “master” if run on master.

NODE_LABELS are the labels separated by white-space for the nodes

WORKSPACE The absolute path of the directory assigned to the build as a workspace.

There is a long list so you can check it from the above link.

Setting up an Environmental Variable

You can set environment variables on the basis of what syntax you are following, it is different for Declarative and Scripted Pipeline.

Declarative Pipeline supports an environment directive, whereas users of Scripted Pipeline must use the withEnv step.

Conditionals in Jensfile / when statement

Suppose you only want to run the tests on the development branch build you don’t want to run tests for other builds what you can do here is inside the stage block you can define when expressions which say when should this stage execute.

stage('compile stage') {

       when{
           expression{
                 BRANCH_NAME == 'dev' || BRANCH_NAME == 'master' && CODE_CHANGES == true // environment variable
               }
        }
             steps {
                bat "mvn clean compile"
        }
    }

This part of the stage will only execute if the current branch is dev if not it’s just gonna skip. You can also apply boolean expression in case you only want to run that step when some condition is true like CODE_CHANGES == true.

That’s all for this blog. Hope you enjoyed it. For more such blogs visit https://blog.knoldus.com/.

Written by 

Saumya is a Software Consultant at Knoldus Software LLP. She has done B.Tech from Quantum School of Technology, Roorkee. She has good knowledge of Devops technologies like Ansible, Terraform, Docker, Concourse, Jenkins, Kubernetes. She is very enthusiastic and energetic. Apart from technology, she is interested in various sports.