Reputation: 13071
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?
Upvotes: 18
Views: 27100
Reputation: 788
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.
Upvotes: 2
Reputation: 1509
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"
}
}
}
}
}
}
}
Upvotes: 18