Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jenkinsfile 'parallel' directive

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?

like image 625
lanoxx Avatar asked May 11 '17 11:05

lanoxx


People also ask

What is the use of parallel stages in Jenkins?

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.

Is the jenkinsfile setup with the pipeline directive or node directive?

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:

Is there a jenkinsfile that adds stages dynamically?

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.

What is the use of Jenkins in declarative pipeline?

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.


2 Answers

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"
                        }
                    }
                }
            }
        }
    }
}
like image 191
Spencer Malone Avatar answered Oct 01 '22 06:10

Spencer Malone


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.

like image 40
Viktor Be Avatar answered Oct 01 '22 07:10

Viktor Be