I am trying to write a Jenkinsfile
that executes in parallel a sequence of steps. The goal is to have two agents
(aka. nodes
). One should do a windows build and the other a linux build. However I do not want this to happen sequentially but in parallel. I am trying to find documentation for the parallel
directive that is described in Pipeline - Parallel execution of tasks.
I found one occurence of parallel
one on the Jenkins, but it seems the documentation is broken: https://jenkins.io/doc/pipeline/steps/workflow-cps/
parallel: Execute in parallel
org.kohsuke.stapler.NoStaplerConstructorException:
There’s no @DataBoundConstructor on any constructor of class
org.jenkinsci.plugins.workflow.cps.steps.ParallelStep
How should I setup a Jenkinsfile that can execute a series of build steps on two different agents (one linux, one windows) in parallel?
In particular, should I rather use the declarative or script based pipeline DSL?
In declarative pipelines, Jenkins allows the definition of parallel stages. It further allows scripted pipeline general purpose scripts to create and manipulate the artifacts of the declarative pipeline. For example, it can create stages dynamically.
From some of the examples I have seen, I notice that the Jenkinsfile is setup with the Pipeline directive: In other examples, I notice that the Jenkinsfile is setup with a node directive:
Below is a simple Jenkinsfile that dynamically adds stages using groovy code. These stages are sequential. I would like a Jenkinsfile that adds stages dynamically as below, but uses the parallel construct at the stage level. As a result, three stages that run parallel should be generated by the program.
In declarative pipelines, Jenkins allows the definition of parallel stages. It further allows scripted pipeline general purpose scripts to create and manipulate the artifacts of the declarative pipeline.
You can use either declarative or script based for doing parallel work. The script based docs for parallel can be found here: https://jenkins.io/doc/book/pipeline/jenkinsfile/#advanced-scripted-pipeline
They give the following example...
stage('Build') {
/* .. snip .. */
}
stage('Test') {
parallel linux: {
node('linux') {
checkout scm
try {
unstash 'app'
sh 'make check'
}
finally {
junit '**/target/*.xml'
}
}
},
windows: {
node('windows') {
/* .. snip .. */
}
}
}
For declarative, I believe you'll do this:
stage('Build') {
steps {
parallel (
"Windows" : {
echo 'done'
},
"Linux" : {
echo 'done'
}
)
}
}
Since Declarative Pipeline 1.2, the preferred declarative syntax is:
pipeline {
agent none
stages {
stage('Run Tests') {
parallel {
stage('Test On Windows') {
agent {
label "windows"
}
steps {
bat "run-tests.bat"
}
post {
always {
junit "**/TEST-*.xml"
}
}
}
stage('Test On Linux') {
agent {
label "linux"
}
steps {
sh "run-tests.sh"
}
post {
always {
junit "**/TEST-*.xml"
}
}
}
}
}
}
}
Declarative Matrix is a great feature for running parallel tasks. It allows you to execute the defined stages (incl. post build actions) for every configuration defined in the matrix directive without code duplication.
Example:
pipeline {
agent none
stages {
stage('Test') {
matrix {
agent {
label "${PLATFORM}-agent"
}
axes {
axis {
name 'PLATFORM'
values 'linux', 'windows'
}
}
stages {
stage('Test') {
steps {
echo "Do Test for ${PLATFORM}"
}
}
}
post {
always {
junit "**/TEST-*.xml"
}
}
}
}
}
}
Quote from a Jenkins blog post:
An equivalent pipeline created without matrix would easily be several times larger, and much harder to understand and maintain.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With