Reputation: 3642
Here is my Jenkins pipeline that i am trying to execute. I am following this tutorial:
pipeline {
agent any
stages {
stage('one') {
parallel "first" : {
echo "hello"
},
"second": {
echo "world"
}
}
stage('two') {
parallel "first" : {
echo "hello"
},
"second": {
echo "world"
}
}
}
}
But the job fails with following message.
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 4: Unknown stage section "parallel". Starting with version 0.5, steps in a stage must be in a steps block. @ line 4, column 9.
stage('one') {
^
WorkflowScript: 12: Unknown stage section "parallel". Starting with version 0.5, steps in a stage must be in a steps block. @ line 12, column 9.
stage('two') {
^
WorkflowScript: 4: Nothing to execute within stage "one" @ line 4, column 9.
stage('one') {
^
WorkflowScript: 12: Nothing to execute within stage "two" @ line 12, column 9.
stage('two') {
^
4 errors
Can someone please help me out why this is failing.
Upvotes: 18
Views: 23031
Reputation: 1160
In declarative pipeline, in case if you want to add stage, inside steps, this nesting is also possible.
If the steps are same in that case you can declare step
as a function
.
def steps = ['first', 'second']
def generateSteps(stepLabel) {
return {
step("${stepLabel}") {
echo "Running on ${stepLabel}"
}
}
}
def parallelStepMap = steps.collectEntries {
["${it}" : generateSteps(it)]
}
pipeline {
agent any
stages {
stage('non-parallel stage') {
steps {
echo 'This stage will be executed first.'
}
}
stage('parallel stage') {
steps {
script {
parallel parallelStepMap
}
}
}
}
}
General need is to execute different stages into different nodes.
in such case above function can be modified to execute on different agent nodes
as follows.
def agents = ['master', 'agent1', 'agent2']
def generateStage(nodeLabel) {
return {
stage("Runs on ${nodeLabel}") {
node(nodeLabel) {
echo "Running on ${nodeLabel}"
}
}
}
}
def parallelStagesMap = agents.collectEntries {
["${it}" : generateStage(it)]
}
pipeline {
agent none
stages {
stage('non-parallel stage') {
steps {
echo 'This stage will be executed first.'
}
}
stage('parallel stage') {
steps {
script {
parallel parallelStagesMap
}
}
}
}
}
With nodelabel
defined inside the function and agent none
during start of pipeline, the stages will be executed into different nodes.
Upvotes: 1
Reputation: 657
You need to add a steps block after your stage declaration.
pipeline {
agent any
stages {
stage('Example Stage 1') {
steps {
parallel(
"step 1": { echo "hello" },
"step 2": { echo "world" },
"step 3": { echo "world" }
)
}
}
stage('Example Stage 2') {
steps {
parallel(
"step 1": { echo "hello" },
"step 2": { echo "world" },
"step 3": { echo "world" }
)
}
}
}
}
To Make your Stages Parallel use this, both solutions show up very similar in Blue Ocean :
pipeline {
agent any
stages {
stage('Example Stage') {
parallel {
stage('Stage 1') {
steps { sh 'echo stage 1 passed' }
}
stage('Stage 2') {
steps { sh 'echo stage 2 passed' }
}
stage('Stage 3') {
steps { sh 'echo stage 3 passed' }
}
}
}
}
}
Upvotes: 35
Reputation: 93
You need to upgrade the Declarative Pipeline plugin on your Jenkins to Version 1.2 (Sept 21, 2017) or above
Upvotes: 2