Jenkins Declarative Pipeline Tips
Jenkins Declarative Pipelines allow you to script your build process as code and are rapidly being adopted. However, they can be tricky to use, so here are a few tips.
The Snippet and Declarative Directive generators
Jenkins ships with generators for different parts of the pipeline. These can be accessed through the web interface and come with forms for configuring different parts of the build step. This can be useful for generating parts of the pipeline or seeing what functionality is available.
You can find documentation for this in the Getting started with Pipelines guide.
Post actions
A post {}
section can be placed after the whole build (all the stages {}
) or after a any stage {}
. The later allows for post actions to be kept close in code to the relevant stage.
pipeline {
agent {
...
}
stages {
stage('Build Stage') {
steps {
...
}
}
post {
// Steps to be completed after this stage
}
}
post {
// Steps to be completed after the whole build
}
}
Disable build stages with when expressions
Debugging Jenkins pipelines can be tricky, and it can be useful to disable stages. This can be done easily by using a when expression
stage ('Build Stage') {
when {
expression {
false
}
}
...
}
This can used with build parameters to create a conditional build stage.
stage ('Extra tests') {
when {
expression {
${params.performExtraTests}
}
}
}
Timeout after no activity
Its a good idea to use a timeout prevent build jobs taking too much time. But how much time do you need? Well by using the activity
flag you can time the job out if there has not been any activity for a given duration.
This configuration will stop the job after 10 minutes of inactivity.
pipeline {
agent any
options {
timeout(timeout: 10, unit: 'MINUTES', activity: true)
}
}
Be careful with locks
The Lockable Resource Plugin allows builds to set locks to manage access to shared resources. As with any locking mechanism for managing concurrency / shared-resources, they can have unintended consequences. For example, acquiring a build node then waiting for a lock for a long time can prevent other builds from being performed as that node is out of the build pool for a long time. It can be better to acquire locks first then build nodes, thus acquiring the most contended resource first.
pipeline {
agent none
stages {
// Acquire lock without using any Jenkins build nodes
stage('Acquire Lock') {
agent none
steps {
lock('the_lock') {
stages {
// Acquire a linux build node
stage('Test on Linux') {
agent {
label 'linux'
}
}
steps {
...
}
}
}
}
}
}
}
Use withMaven() build step for Maven builds
If you’re using Maven as a build tool, use the Pipeline Maven Plugin which provides the withMaven () {}
build step. This step will ensure the correct Maven tool is available for the build, spy on the process to give better feedback, automatically publish various types of reports such as any JUnit output, and allow you to configure the tool for example providing a hook for specifying the local repo location.
withMaven(maven: 'maven-3.6') {
sh 'mvn clean install'
}