Jenkins pipeline part 5 – options
Hello Everyone
Welcome to CloudAffaire and this is Debjeet.
In today’s blog post, we will discuss what are different options available in a Jenkins pipeline.
What is options is Jenkins pipeline?
The options directive allows configuring Pipeline-specific options from within the Pipeline itself. Pipeline provides a number of these options, such as buildDiscarder, but they may also be provided by plugins, such as timestamps.
Similar to pipeline-level options, Jenkins also supports stage-level options. The options directive for a stage is similar to the options directive at the root of the Pipeline. However, the stage-level options can only contain steps like retry, timeout, or timestamps, or Declarative options that are relevant to a stage, like skipDefaultCheckout.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
## ------- ## options ## ------- pipeline { agent { ... } options { } stages { stage(' options { } steps { } ... } ... } } |
Let’s dig down a bit with some examples.
Jenkins pipeline part 5 – options
Prerequisites
One system with Jenkins installed.
buildDiscarder:
Persist artifacts and console output for the specific number of recent Pipeline runs. For example: options { buildDiscarder(logRotator(numToKeepStr: ‘1’)) }
Parameters for logRotator:
- daysToKeepStr: history is only kept up to these days.
- numToKeepStr: only this number of build logs are kept.
- artifactDaysToKeepStr: artifacts are only kept up to these days.
- artifactNumToKeepStr: only this number of builds have their artifacts kept.
Create a new pipeline in your Jenkins controller server using below Jenkinsfile. Replace the label as per your Jenkins configuration.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
## ------------------------ ## options | buildDiscarder ## ------------------------ pipeline { agent { label 'test' } options { buildDiscarder(logRotator(numToKeepStr: '1')) } stages { stage('hello') { steps { echo "Hello World!" } } } } |
Trigger the pipeline depending on you pipeline setup.
Since we have set numToKeepStr to one, Jenkins will only maintain logs for one pipeline line run, try to rerun the pipeline and refresh the page.
checkoutToSubdirectory:
Perform the automatic source control checkout in a subdirectory of the workspace. For example: options { checkoutToSubdirectory(‘foo’) }
Update the pipeline configuration and set to “Pipeline script for SCM” and configure the rest of the settings as per your git remote repository configuration
Update your Jenkinsfile in remote git repository with below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
## -------------------------------- ## options | checkoutToSubdirectory ## -------------------------------- pipeline { agent { label 'test' } options { checkoutToSubdirectory('MyCustomDir') } stages { stage('checkout') { steps { sh 'pwd' sh 'ls -l' sh 'ls -l MyCustomDir' } } } } |
Trigger the pipeline depending on you pipeline setup.
Observe, Jenkins has cloned your remote repository in your custom directory specified in option directive.
disableConcurrentBuilds:
Disallow concurrent executions of the Pipeline. By default, Jenkins allow you to rerun the pipeline while existing run InProgress but sometimes you may one to disable any new runs while an existing run InProgress using disableConcurrentBuilds option. For example: options { disableConcurrentBuilds() }
Update the Jenkins file with below and rerun the pipeline. While the pipeline is executing, try to run a new pipeline.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
## --------------------------------- ## options | disableConcurrentBuilds ## --------------------------------- pipeline { agent { label 'test' } options { disableConcurrentBuilds() } stages { stage('LongRunning') { steps { sh 'sleep 300' } } } } |
Observe, no new pipeline can get triggered until the current one complete its execution.
disableResume:
disableResume option do not allow the pipeline to resume if the controller restarts. For example: options { disableResume() }
Update the Jenkins file with below and rerun the pipeline. While the pipeline is executing, try to restart the Jenkins controller.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
## ----------------------- ## options | disableResume ## ----------------------- pipeline { agent { label 'test' } options { disableResume() } stages { stage('LongRunning') { steps { sh 'sleep 300' } } } } |
Observe, pipeline will not get resumed automatically after the controller restart.
newContainerPerStage:
Used with docker or dockerfile top-level agent. When specified, each stage will run in a new container instance on the same node, rather than all stages running in the same container instance.
Update the Jenkins file with below and rerun the pipeline.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
## ------------------------------ ## options | newContainerPerStage ## ------------------------------ pipeline { agent { docker { image 'alpine:latest' label 'dev' } } options { newContainerPerStage() } stages { stage('One') { steps { sh 'hostname' } } stage('Two') { steps { sh 'hostname' } } } } |
Note: You need to setup your Jenkins agent to be able to run your pipeline on a docker container
Observe, the two stages were executed in two different containers using the same image.
overrideIndexTriggers:
Allows overriding default treatment of branch indexing triggers. If branch indexing triggers are disabled at the multibranch or organization label, options { overrideIndexTriggers(true) } will enable them for this job only. Otherwise, options { overrideIndexTriggers(false) } will disable branch indexing triggers for this job only.
This require a multi-branch Jenkins project which is not covered yet, hence just giving the syntax of this option without hands-on.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
## ------------------------------- ## options | overrideIndexTriggers ## ------------------------------- pipeline { agent { label 'test' } options { overrideIndexTriggers(true) } stages { stage('one') { steps { echo env.BRANCH_NAME } } } } |
preserveStashes:
Preserve stashes from completed builds, for use with stage restarting. For example: options { preserveStashes() } to preserve the stashes from the most recent completed build, or options { preserveStashes(buildCount: 5) } to preserve the stashes from the five most recent completed builds.
Update the pipeline definition with below and rerun the pipeline.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
## ------------------------- ## options | preserveStashes ## ------------------------- pipeline { agent { label 'test' } options { preserveStashes(buildCount: 1) } stages { stage('one') { steps { sh "mkdir input" writeFile file: "input/myfile${BUILD_NUMBER}", text: "Hello world!" stash name: "mystash", includes: "input/*" sh "rm -r input" } } stage('two') { steps { sh "mkdir output" dir("output") { unstash "mystash" sh "ls -lR ${pwd()}" } sh "rm -r output" } } } } |
Observe, we were successfully able to unstash in stage two, now restart only stage “two”
Observe, we are still able to unstash in stage two.
Now remove the option block from the pipeline and rerun the pipeline.
The pipeline will get executed successfully for the first time. Now try to restart stage “two”.
Observe, you get an error since stash in stage “one” was not preserved, hence not available in stage “two” when restarted.
quietPeriod:
Set the quiet period, in seconds, for the Pipeline, overriding the global default. For example: options { quietPeriod(30) }
Update the pipeline with Jenkins file hosted in GitHub and trigger is through webhook using below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
## --------------------- ## options | quietPeriod ## --------------------- pipeline { agent { label 'test' } options { quietPeriod(600) } stages { stage('hello') { steps { echo "hello world!" } } } } |
Now try to push couple of changes to your GitHub repository in quick succession.
Observe, the pipeline will get triggered for the 1st time and the next trigger will wait till quite period is over.
retry:
On failure, retry the entire Pipeline the specified number of times. For example: options { retry(3) }
Update the pipeline with below and rerun the pipeline.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
## --------------- ## options | retry ## --------------- pipeline { agent { label 'test' } options { retry(3) } stages { stage('error') { steps { sh "exit 1" } } } } |
Observe, the pipeline will fail as expected but after three retires.
skipStagesAfterUnstable:
Skip stages once the build status has gone to UNSTABLE. For example: options { skipStagesAfterUnstable() }
Update the pipeline definition with below and rerun the pipeline.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
## --------------------------------- ## options | skipStagesAfterUnstable ## --------------------------------- pipeline { agent { label 'test' } options { skipStagesAfterUnstable() } stages { stage('Stable') { steps { sh 'exit 0' } } stage('Unstable') { steps { unstable(message: "unknown error") } } stage('StableAgain') { steps { sh 'exit 0' } } } } |
Observe, the stage after the unstable stage was skipped and not run.
Now remove the option block and rerun the pipeline.
Observe, this time the stage after the unstable stage was executed.
timeout:
Set a timeout period for the Pipeline run, after which Jenkins should abort the Pipeline. For example: options { timeout(time: 1, unit: ‘HOURS’) }
Update the pipeline definition with below and rerun the pipeline.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
## ----------------- ## options | timeout ## ----------------- pipeline { agent { label 'test' } options { timeout(time: 60, unit: 'SECONDS') } stages { stage('logn running') { steps { sh "sleep 180" } } } } |
Observe, the pipeline will get aborted due to timeout.
parallelsAlwaysFailFast
Set failfast true for all subsequent parallel stages in the pipeline. For example: options { parallelsAlwaysFailFast() }
Update the pipeline definition with below and rerun the pipeline.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
## --------------------------------- ## options | parallelsAlwaysFailFast ## --------------------------------- pipeline { agent { label 'test' } options { parallelsAlwaysFailFast() } stages { stage('iNormal') { steps { sh 'exit 0' } } stage('iParallel') { parallel { stage('iFailed') { steps { sh 'exit 1' } } stage('iPassed') { steps { sh 'exit 0' } } } } } } |
Observe, if any stage failed in the parallel stage, all subsequent stage fails.
You can also define options in stage level.
Jenkins stage-level options:
The options directive for a stage is similar to the options directive at the root of the Pipeline. However, the stage-level options can only contain steps like retry, timeout, or timestamps, or Declarative options that are relevant to a stage, like skipDefaultCheckout.
Inside a stage, the steps in the options directive are invoked before entering the agent or checking any when conditions.
Jenkins stage-level options example:
Update the pipeline definition with below and rerun the pipeline.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
## ----------------------------- ## stage-level options | timeout ## ----------------------------- pipeline { agent { label 'test' } stages { stage('logn running 1') { steps { sh "sleep 120" } } stage('logn running 2') { options { timeout(time: 60, unit: 'SECONDS') } steps { sh "sleep 120" } } } } |
Observe, the first log running stage was executed successfully but the second long running stage got aborted due to timeout.
Hope you have enjoyed this article, to get more details on Jenkins, please refer below Jenkins official documentation.