Viktor Be
Viktor Be

Reputation: 788

Run same stages in parallel on different nodes with Jenkins pipeline

There is a way to execute steps/post-actions on different nodes in parallel described in this article: https://jenkins.io/blog/2017/09/25/declarative-1/

     stage('Run Tests') {
        parallel {
            stage('Test On Windows') {
                agent {
                    label "windows"
                }
                steps {
                    bat "run-tests.bat"
                }
                post {
                    always {
                        junit "**/TEST-*.xml" // DUPLICATE CODE
                    }
                }
            }
            stage('Test On Linux') {
                agent {
                    label "linux"
                }
                steps {
                    sh "run-tests.sh"
                }
                post {
                    always {
                        junit "**/TEST-*.xml" // DUPLICATE CODE
                    }
                }
            }
        }
    }

Is there any possibility to execute same stages on multiple nodes without duplicating code?

Something like this:

     stage('Run Tests') {
        parallel {
            stage("Test On ${NODE_NAME}") {
                agents {
                    label "windows"
                    label "linux"
                }
                steps {
                    // do test steps
                }
                post {
                    always {
                        junit "**/TEST-*.xml"
                    }
                }
            }
        }
    }

Upvotes: 0

Views: 2754

Answers (2)

Viktor Be
Viktor Be

Reputation: 788

Declarative Matrix worked best for me:

pipeline {
    agent none
    stages {
        stage('BuildAndTest') {
            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"
                    }
                }
            }
        }
    }
}

This pipeline will execute the defined stages incl. post build actions on both platforms without any code duplication.

Quote from a Jenkins blog post about declartive matrix:

An equivalent pipeline created without matrix would easily be several times larger, and much harder to understand and maintain.

Upvotes: 0

Sers
Sers

Reputation: 12255

You can create dynamic stages, but for your case not needed

pipeline {
    agent any
    stages {
        stage ("Test") {
            steps {
                script {
                    testStages = ["Windows", "Linux"].collectEntries {
                        ["${it}" : runTests(it)]
                    }
                    parallel testStages
                }   
            }
        }
    }
}

def runTests(def name){
    return {
        node(name) {
            stage("Run on ${name}") {
                script {
                    command = "run-tests"
                    try {
                        switch(name.toLowerCase()) {
                            case "windows": 
                                command += ".bat" 
                                break;

                            case "linux": 
                                command += ".sh" 
                                break;
                        } 

                        echo command
                    } catch (Exception ex) {
                        echo ex
                    } finally {
                        echo "post ${name}"
                    }
                }
            }
        }
    }
}

enter image description here

Upvotes: 2

Related Questions