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.
- Create a folder –C:\MaryZheng\DevTools\Jenkins_home and share it via Docker setting ->Resource ->File Sharing.
- Pull docker image jenkins/jenkins:lts-jdk11 from Docker hub.
- Start the Jenkins container and map the volume to C:\MaryZheng\DevTools\Jenkins_home.
- Install suggested Jenkins plugins (pipeline, git, maven, etc).
- 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.
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.
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.
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.
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
Click the “Build Now” button and view the “Stages 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.
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“.
Click the Pipeline tab and select the “Scripted Pipeline” option.
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.
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
You can download the full source code of this example here: Getting Started with Jenkins Pipeline