Structure of a Scripted Pipeline in Jenkins with sample code

Scripted Pipeline


There are two ways of writing pipeline code in jenkins, scripted and declarative. Here we will discuss how to start with writing a scripted pipeline in Jenkins. We will write pipeline code for a java web app project using maven, however high level structure will hold true for any project type.

First let us discuss the high level structure. The pipeline code is structured here as a try catch block for error handling though it is not mandatory to enclose the script within try catch block.

node {
  try{
    stage('') {
    } 
     ... 
  }
  catch(err)
  {
    currentBuild.result ="FAILURE"
    step([$class: 'Mailer', notifyUnstableEveryBuild:true, recipients:'', sendToIndividuals: true])
    throw err
  }
}

node

node is a scripted pipeline-specific syntax that instructs Jenkins to execute this pipeline on any available agent if not specified. If you want the pipeline code or the code for any particular stage to be run on a specific agent, you can provide the agent in a bracket against the node keyword or the stage keyword resp.

node(label:'master') {

stages

Git Checkout Stage

The first step is usually to download the latest code into the Jenkins workspace. This step is not mandatory and you can also work from your project folder in a different location than Jenkins workspace, however this is the most common scenario.

For checking out the code, we will simply use the following code for the stage Git Checkout.

stage("Git Checkout"){    
  git credentialsId: 'githubcredentials',  url: 'https://github.com/githubusername /githubreponame.git'                 
  echo 'Git Checkout Completed'            
} 

Make sure to replace githubusername with your GitHub username and githubreponame with the name of your repository in GitHub.

Compile and Unit Test Stage

Our next stage is a Compile and Unit Test stage. Maven should be configured in Jenkins to run the code mentioned below

stage('Compile and Unit Test') {
  sh 'mvn clean test'
  echo 'Compile and Unit Test Completed'
} 

To run the above code on windows, all you need is to replace the sh command with bat command as follows

bat ‘mvn clean test’

This stage uses two maven goals clean and test. This will first clean all the files and directories generated inside target directory during previous builds. 
Maven has a lifecycle. If you call a specific phase, all previous phases are also called automatically. So if you call mvn test, it will compile your classes and your test classes and run the tests.

We could have also mentioned compile and test goals separately if required as follows and run them as a batch or shell script in two separate stages

mvn clean compile

mvn test

Do not forget to replace sh command with bat for windows.

Lastly, the following echo command will print this statement in the logs.

echo 'Compile and Unit Test Completed'​​
SonarQube Analysis and Quality Gate

Let us see the pipeline stages for SonarQube Analysis and Quality Gate for a java and maven project. Replace sh with bat on Windows OS

stage('Static Analysis') 
{  
  withSonarQubeEnv('SonarQube1') 
    {
     sh 'mvn sonar:sonar
     echo 'Static Analysis Completed' 
     }
   
stage("Quality Gate"){
  timeout(time: 1, unit: 'HOURS') 
  {
    waitForQualityGate abortPipeline: true
    def qg= waitForQualityGate()
    if (qg.status!= 'OK'){
      error "Pipeline aborted due to quality gate failure: ${qg.status}"
    }
  }         
      echo 'Quality Gate Passed' 
}

To understand all the steps required to integrate SonarQube with Jenkins, refer the post SonarQube integration with Jenkins

Package and Deploy stages

Next we will add stages Package and Deploy to the pipeline as shown below.

stage('Package') {
  sh 'mvn -U -DskipTests package'
  echo 'Package Completed'
}
stage('Deploy') {
  sh 'mvn -U -DskipTests tomcat7:deploy -Dtomcat.username=<tomcatserverusername> -Dtomcat.password=<tomcatserverpassword>'
  echo 'Deploy Completed'
}

Maven goal for package and deploy will execute all previous goals in the maven life cycle which also includes unit tests. As we have already passed the unit tests in the previous stage of this pipeline, we can skip them by using – U switch. 

In the deploy stage, we deploy the code to tomcat server. You need to provide the username a password for your tomcat server.

try catch block

The code in the catch block will mark the pipeline result as failed in case of an error. It will then send the failure notification with log details to the specified recipient email id. It will be able to send email only if the sender email address is pre-configured in Jenkins. As a last step, it will throw the error. You can refer to the code for the catch block and the complete pipeline from the below pipeline script.

Pipeline code

node(label:'master') {
  try{
    stage('Compile and Unit Testing') {
      sh 'mvn clean test'
      echo 'Compile and Unit Test Completed'
    } 
    stage('Static Analysis') 
    {  
     withSonarQubeEnv('SonarQube1') 
      {
       sh 'mvn sonar:sonar
       echo 'Static Analysis Completed' 
       }   
    stage("Quality Gate"){
      timeout(time: 1, unit: 'HOURS') 
    {
      waitForQualityGate abortPipeline: true
      def qg= waitForQualityGate()
      if (qg.status!= 'OK'){
        error "Pipeline aborted due to quality gate failure: ${qg.status}"
      }
    }         
      echo 'Quality Gate Passed' 
  }
    stage('Package') {
      sh 'mvn -U -DskipTests package'
      echo 'Package Completed'
    }
    stage('Deploy') {
      sh 'mvn -U -DskipTests tomcat7:deploy                  -Dtomcat.username= -Dtomcat.password='
      echo 'Deploy Completed'
    }
  } 
  catch(err){
    currentBuild.result = "FAILURE"
    step([$class: 'Mailer', notifyUnstableEveryBuild:  
 true,recipients:'', sendToIndividuals: true])
throw err
  }
} 

Once you have created the pipeline, you will need to build the code using “Build Now” from project dashboard and then check the console output for the detailed logs.

Let us know if you found this post helpful.

You may also like...

Leave a Reply

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