DevOps

Getting Started with Jenkins Pipeline

1. Introduction

Jenkins is an open-source automation server that enables developers to build, test, and deploy their software reliably. It has more than 1800 plugins. Jenkins Pipeline is a suite of plugins to support continuous delivery pipelines into Jenkins. In this example, I will demonstrate the following:

  • Install Jenkins and Pipeline plugin
  • Configure the maven tool
  • Build simple pipeline jobs to demonstrate with old node script and new declarative pipeline.

2. Technologies Used

The example code in this article was built and run using:

  • Jenkins 2.3
  • Docker Desktop
  • Github
  • Maven 3.6.1

3. Jenkins Installation

In this step, I will install Jenkins in a docker container on my Windows 10 PC.

  1. Create a folder –C:\MaryZheng\DevTools\Jenkins_home and share it via Docker setting ->Resource ->File Sharing.
  2. Pull docker image jenkins/jenkins:lts-jdk11 from Docker hub.
  3. Start the Jenkins container and map the volume to C:\MaryZheng\DevTools\Jenkins_home.
  4. Install suggested Jenkins plugins (pipeline, git, maven, etc).
  5. Create a “Hello World” Pipeline Job.

3.1 Docker File Sharing

This step is only needed when running Jenkins as a docker container at a windows PC.

Click docker Settings->Resources->File Sharing and click the “plus” icon to add a folder as a shared resource.

jenkins pipeline - docker resource
Figure 1 Docker Resource file Sharing

3.2 Pull Jenkins Docker Image

Create a Docker hub account if you don’t have one.

Execute docker pull command – docker pull jenkins/jenkins:lts-jdk11 to get the image.

docker pull jenkins/jenkins:lts-jdk11

PS C:\MaryZheng\DockerImages> docker pull jenkins/jenkins:lts-jdk11
lts-jdk11: Pulling from jenkins/jenkins
bb7d5a84853b: Pull complete                                                                                             3e2bcf6b1921: Pull complete                                                                                             978539702e19: Pull complete                                                                                             7fa18bcbf207: Pull complete                                                                                             a67725ef6531: Pull complete                                                                                             be5329269e0a: Pull complete                                                                                             f1514eafcdb2: Pull complete                                                                                             a1f0f8fcd02d: Pull complete                                                                                             8d76f0dde4b9: Pull complete                                                                                             9f47eedf727b: Pull complete                                                                                             74d1ec398ccc: Pull complete                                                                                             df71683f45f5: Pull complete                                                                                             95c82c721e5c: Pull complete                                                                                             2569d89b2015: Pull complete                                                                                             40a8b1ea9f1c: Pull complete                                                                                             4d4e70b7b6df: Pull complete                                                                                             d112a9446c9f: Pull complete                                                                                             Digest: sha256:510c7e5a5e62049e48f5d01cc6a5e03197f84fbbce70ea51d9d788043926180a
Status: Downloaded newer image for jenkins/jenkins:lts-jdk11
docker.io/jenkins/jenkins:lts-jdk11

3.3 Start Jenkins

Start the Jenkins from the docker run command.

docker run -p 9090:8080 -p 50000:50000 -v C:\MaryZheng\DevTools\Jenkins_home:/var/jenkins_home jenkins

PS C:\MaryZheng\DockerImages> docker run -p 9090:8080 -p 50000:50000  jenkins/jenkins:lts-jdk11                         Running from: /usr/share/jenkins/jenkins.war
webroot: EnvVars.masterEnvVars.get("JENKINS_HOME")
2021-11-04 22:58:58.605+0000 [id=1]     INFO    org.eclipse.jetty.util.log.Log#initialized: Logging initialized @1684ms to org.eclipse.jetty.util.log.JavaUtilLog
2021-11-04 22:58:58.812+0000 [id=1]     INFO    winstone.Logger#logInternal: Beginning extraction from war file
2021-11-04 22:59:00.671+0000 [id=1]     WARNING o.e.j.s.handler.ContextHandler#setContextPath: Empty contextPath
2021-11-04 22:59:00.858+0000 [id=1]     INFO    org.eclipse.jetty.server.Server#doStart: jetty-9.4.43.v20210629; built: 2021-06-30T11:07:22.254Z; git: 526006ecfa3af7f1a27ef3a288e2bef7ea9dd7e8; jvm 11.0.13+8
2021-11-04 22:59:01.608+0000 [id=1]     INFO    o.e.j.w.StandardDescriptorProcessor#visitServlet: NO JSP Support for /, did not find org.eclipse.jetty.jsp.JettyJspServlet
2021-11-04 22:59:01.729+0000 [id=1]     INFO    o.e.j.s.s.DefaultSessionIdManager#doStart: DefaultSessionIdManager workerName=node0
2021-11-04 22:59:01.730+0000 [id=1]     INFO    o.e.j.s.s.DefaultSessionIdManager#doStart: No SessionScavenger set, using defaults
2021-11-04 22:59:01.733+0000 [id=1]     INFO    o.e.j.server.session.HouseKeeper#startScavenging: node0 Scavenging every 660000ms
2021-11-04 22:59:02.860+0000 [id=1]     INFO    hudson.WebAppMain#contextInitialized: Jenkins home directory: /var/jenkins_home found at: EnvVars.masterEnvVars.get("JENKINS_HOME")
2021-11-04 22:59:03.179+0000 [id=1]     INFO    o.e.j.s.handler.ContextHandler#doStart: Started w.@639aba11{Jenkins v2.303.3,/,file:///var/jenkins_home/war/,AVAILABLE}{/var/jenkins_home/war}
2021-11-04 22:59:03.255+0000 [id=1]     INFO    o.e.j.server.AbstractConnector#doStart: Started ServerConnector@4189d70b{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2021-11-04 22:59:03.257+0000 [id=1]     INFO    org.eclipse.jetty.server.Server#doStart: Started @6337ms
2021-11-04 22:59:03.261+0000 [id=23]    INFO    winstone.Logger#logInternal: Winstone Servlet Engine running: controlPort=disabled
2021-11-04 22:59:03.809+0000 [id=30]    INFO    jenkins.InitReactorRunner$1#onAttained: Started initialization
2021-11-04 22:59:03.887+0000 [id=28]    INFO    jenkins.InitReactorRunner$1#onAttained: Listed all plugins
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.google.inject.internal.cglib.core.$ReflectUtils$2 (file:/var/jenkins_home/war/WEB-INF/lib/guice-4.0.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of com.google.inject.internal.cglib.core.$ReflectUtils$2
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
2021-11-04 22:59:06.702+0000 [id=29]    INFO    jenkins.InitReactorRunner$1#onAttained: Prepared all plugins
2021-11-04 22:59:06.723+0000 [id=28]    INFO    jenkins.InitReactorRunner$1#onAttained: Started all plugins
2021-11-04 22:59:06.767+0000 [id=30]    INFO    jenkins.InitReactorRunner$1#onAttained: Augmented all extensions
2021-11-04 22:59:08.417+0000 [id=29]    INFO    jenkins.InitReactorRunner$1#onAttained: System config loaded
2021-11-04 22:59:08.418+0000 [id=29]    INFO    jenkins.InitReactorRunner$1#onAttained: System config adapted
2021-11-04 22:59:08.420+0000 [id=29]    INFO    jenkins.InitReactorRunner$1#onAttained: Loaded all jobs
2021-11-04 22:59:08.422+0000 [id=29]    INFO    jenkins.InitReactorRunner$1#onAttained: Configuration for all jobs updated
2021-11-04 22:59:08.505+0000 [id=44]    INFO    hudson.model.AsyncPeriodicWork#lambda$doRun$0: Started Download metadata
2021-11-04 22:59:08.529+0000 [id=44]    INFO    hudson.util.Retrier#start: Attempt #1 to do the action check updates server
2021-11-04 22:59:10.189+0000 [id=31]    INFO    jenkins.install.SetupWizard#init:

*************************************************************
*************************************************************
*************************************************************

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

b9a0904907f34d6c85512f51245cff3e

This may also be found at: /var/jenkins_home/secrets/initialAdminPassword

Launch Jenkins at http://localhost:9090 and enter the initial password shown at line 41 to unlock Jenkins.

jenkins pipeline - unlock jenkins
Figure 2 Unlock Jenkins

Click the Continue button and set up an admin user. Now the Jenkins server is ready to use.

3.4 Installed Pipeline Plugin

In this step, I will install the suggested plugins via Jenkins Dashboard->Plugin Manager -> Manage Plugins menu. First, install the suggested plugins and then verify by viewing the “Installed” tab. Figure 3 shows the pipeline plugin is installed.

jenkins pipeline - pipeline plugin
Figure 3 Pipeline plugin is installed

3.5 Create a Hello World Pipeline

In this step, I will create a SimplePipelineJob from the provided “Hello World” script.

Click Dashboard ->New Item and enter “SimplePipelineJob“. Select “Pipeline” and click the OK button.

Figure 4 New SimplePipelineJob

Click the “Pipeline” tab and select the “Hello World” from the “Pipeline script” as shown at Figure 5. Click the “Save” button to create a pipeline job

Figure 5 Hello World Pipeline Job

Click the “Build Now” button and view the “Stages View“.

Figure 6 Hello World Stage View

4. Jenkins Pipeline Jobs

As you can see in the “Hello World” pipeline example, the step’s definition is captured by a groovy script. The stages and steps directives are required for a valid declarative Pipeline. In this step, I will create two pipeline jobs to clone source code from Github, build with maven, and test with JUnit.

4.1 Configure Maven Tool

Click Dashboard -> Manage Jenkins ->Global Tool Configuration ->Maven. Enter the maven361 for the Maven name. The maven name will be used in the pipeline scripts.

Figure 7 Configure Maven

4.2 Create a Scripted Pipeline

In this step, I will create a pipeline job with a choice input parameter. The input variable name is “BuildPara1“.

Figure 8 Input Parameter

Click the Pipeline tab and select the “Scripted Pipeline” option.

Figure 9 Scripted Pipeline

I will update the generated script for the following items:

  • Update the maven tool to “maven361” configured at the previous step.
  • Update the github URL to my testing URL
  • Add a new step to show the input choice value
  • Add a catch clause to accept an input to proceed or abort based on the user’s choice.

updated scripts

node {
    stage('Log parameter choices') {
        sh "echo 'INPUT is ${BuildPara1}' "
    }
    
    def mvnHome
    stage('Preparation') { // for display purposes
        // Get some code from a GitHub repository
        git 'https://github.com/maryzheng01/SinglePlayerPokerGame.git'
        // Get the Maven tool.
        // ** NOTE: This 'maven361' Maven tool must be configured
        // **       in the global configuration.
        mvnHome = tool 'maven361'
    }
    stage('Build') {
        // Run the maven build
        withEnv(["MVN_HOME=$mvnHome"]) {
            if (isUnix()) {
                try{
                    sh '"$MVN_HOME/bin/mvn" clean package'
                } catch (err) {
		    input 'maven clean package failed.  Verify in logs. Proceed to continue'
		}
            } else {
                bat(/"%MVN_HOME%\bin\mvn" -Dmaven.test.failure.ignore clean package/)
            }
        }
        
    }
    stage('Results') {
        junit '**/target/surefire-reports/TEST-*.xml'
        archiveArtifacts 'target/*.jar'
    }
}

Click the “Build with Parameter” button and click the Proceed or Abort button.

Figure 10 Interactive Job

4.3 Create a Declarative Pipeline

In this step, I will create a declarative pipeline with multiple steps.

declarative pipeline scripts

pipeline {
    agent any
    tools {
        maven 'maven361'
    }
    

    stages {
        
        stage('ENV Check') {
            steps {
               sh 'java --version'
            }
        }
        
        stage('GetResource') {
            steps {
               git 'https://github.com/maryzheng01/SinglePlayerPokerGame.git'
            }
        }
        
        stage('Build') {
            steps {
                echo "mvn"
                sh 'mvn -DskipTests clean install'
            }
        }
        
        stage('CleanUp') {
            steps {
               cleanWs()
            }
        }
         
    }
}

Click “Build Now” and view the results.

5. Summary

Jenkins Pipeline is used widely to support continuous integration and continuous deployment (CI/CD). In this example, I first installed Jenkins and Pipeline plugins. Then demonstrated with three Jenkins pipeline jobs:

  • Hello World Simple Pipeline.
  • Scripted Pipeline with an interactive user decision.
  • Declarative Pipeline with several steps.

6. Download the Source Code

Download
You can download the full source code of this example here: Getting Started with Jenkins Pipeline

Mary Zheng

Mary has graduated from Mechanical Engineering department at ShangHai JiaoTong University. She also holds a Master degree in Computer Science from Webster University. During her studies she has been involved with a large number of projects ranging from programming and software engineering. She works as a senior Software Engineer in the telecommunications sector where she acts as a leader and works with others to design, implement, and monitor the software solution.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button