如何在Jenkins声明式管道中的多个节点上运行相同的阶段?

时间:2019-05-22 01:36:34

标签: jenkins groovy jenkins-pipeline jenkins-declarative-pipeline

我们有一个这样的管道:

pipeline {
    agent none

    stages {
        stage('Build') {
            // ...
        }

        stage('Test') {
            parallel {
                stage('Test on Debian') {
                    agent {
                        label 'debian'
                    }
                    steps {
                        unstash 'compile-artifacts'
                        unstash 'dot-gradle'

                        sh './gradlew check --stacktrace'
                    }
                    post {
                        always {
                            junit '*/build/test-results/**/*.xml'
                        }
                    }
                }

                stage('Test on CentOS') {
                    agent {
                        label 'centos'
                    }
                    steps {
                        unstash 'compile-artifacts'
                        unstash 'dot-gradle'

                        sh './gradlew check --stacktrace'
                    }
                    post {
                        always {
                            junit '*/build/test-results/**/*.xml'
                        }
                    }
                }

                stage('Test on Windows') {
                    agent {
                        label 'windows'
                    }
                    steps {
                        unstash 'compile-artifacts'
                        unstash 'dot-gradle'

                        bat "gradlew.bat check --stacktrace"
                    }
                    post {
                        always {
                            junit '*/build/test-results/**/*.xml'
                        }
                    }
                }

                stage('Test on macOS') {
                    agent {
                        label 'macos'
                    }
                    steps {
                        unstash 'compile-artifacts'
                        unstash 'dot-gradle'


                        sh './gradlew check --stacktrace'
                    }
                    post {
                        always {
                            junit '*/build/test-results/**/*.xml'
                        }
                    }
                }
            }
        }
    }
}

每个阶段基本上都是相同的,除了Windows块中我已经知道如何处理的一行之外,是否有办法对这些阶段的公共部分进行模板化以消除重复?

我已经尝试过将循环内联,但这不是声明性管道允许您执行的操作。 :(

2 个答案:

答案 0 :(得分:2)

您可以使用常规方法重构step{}块:

def stageX(boolean linux)
{
    unstash 'compile-artifacts'
    unstash 'dot-gradle'
    if (linux) {
        sh './gradlew check --stacktrace' }
    else {
        bat "gradlew.bat check --stacktrace" }
}

您必须像在step{}中那样调用它:

steps
{
   script { stageX( true) } // or with false for your windows agent
}

当然,您可以对junit-plugin-call进行相同的操作:

def junitCall()
{
    junit '*/build/test-results/**/*.xml'
}

并这样称呼它:

            post {
                always {
                    script { junitCall() }   
                }
            }

您不会赢得很多行,但是它将大大改善代码的处理。如果您想进一步清理Jenkinsfile,可以将这些方法放入您导入的共享库中,这样就不会在您的Jenkinsfile中声明它们。

答案 1 :(得分:0)

目前基本上无法完成您想做的事情。正如https://jenkins.io/doc/book/pipeline/shared-libraries/#defining-declarative-pipelines所述:

  

到目前为止,只能在共享库中定义整个管道   时间。这只能在vars / *。groovy中完成,并且只能在调用中完成   方法。一次只能执行一条声明性管道   构建,如果您尝试执行第二个构建,则构建将   结果失败了。

因此,您可以定义方法来捆绑多个步骤,也可以将整个管道捆绑在共享库中,但两者之间什么也没有。真可惜。