Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jenkins pipeline with parallel

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.

like image 289
Shahzeb Khan Avatar asked Apr 04 '17 15:04

Shahzeb Khan


People also ask

What is parallel stage in Jenkins pipeline?

This means that one stage could run on a certain machine, and another stage of the same pipeline could run on another machine. Thus having a Jenkins distributed build and not just a Jenkins parallel build.

Is parallel execution possible in Jenkins?

This plugin adds a tool that lets you easily execute tests in parallel. This is achieved by having Jenkins look at the test execution time of the last run, split tests into multiple units of roughly equal size, then execute them in parallel.


Video Answer


3 Answers

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" }
                )
            }
        }
    }
}

Blue Ocean Parallel Steps

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' }
                }
            }
        }
    }
}

Blue Ocean Parallel Stages

like image 142
zypherman Avatar answered Oct 17 '22 05:10

zypherman


You need to upgrade the Declarative Pipeline plugin on your Jenkins to Version 1.2 (Sept 21, 2017) or above

like image 2
MEhran Avatar answered Oct 17 '22 06:10

MEhran


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.

like image 1
np2807 Avatar answered Oct 17 '22 05:10

np2807