groovy Jenkins宣告式管缐-并行执行多个项目,但如果先前发生失败,则略过“分支”

jaql4c8m  于 2022-11-01  发布在  Jenkins
关注(0)|答案(1)|浏览(125)

我想构建一个Jenkins管道,在一个程序的多个版本(例如,不同的数据库)上构建和运行测试,但当任何一步失败时,我想跳过以下步骤,可以说只是针对该“分支”。
这是我的示例代码,其中阶段1首先运行,可能有并行步骤(1.a,1.b)。该代码不工作,只是我希望它如何工作的某种示例:

pipeline {
    agent any
    environment {
        stageOneFailed = "false"
        stageTwoFailed = "false"
    }

    stages {
        stage ("Stage 1") {
            parallel {
                stage("Stage 1.a") {
                    // Something like this maybe?
                    steps {
                        catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
                            // Do stuff here..
                        }
                    }
                    post {
                        unsuccessful {
                            // When stage did not succeed..
                            // Set stageOneFailed = "true"
                        }
                    }
                }

                stage("Stage 1.b") {
                    // Do Stuff..
                    // If Stage 1.b fails, set stageTwoFailed="true"
                }
            }
        }

        stage("Stage 2") {
            parallel {
                // Only run stages if earlier steps didn't fail
                stage("Stage 2.a") {
                    when {
                        environment(name: "stageOneFailed", value: "false")
                    }
                    steps {
                        // Do stuff..
                        // If Stage 2.a fails, set stageOneFailed="true"
                    }
                }
                stage("Stage 2.b") {
                    when {
                        environment(name: "stageTwoFailed", value: "false")
                    }
                    steps {
                        // Do stuff..
                        // If Stage 2.b fails, set stageTwoFailed="true"
                    }
                }
            }
        }

        // stage()
    }
}

有谁能给予我一个正确的建议吗?
先谢谢你
编辑:更改了代码示例。示例现在运行!

pipeline {
    agent any
    environment {
        stageOneFailed = "false"
        stageTwoFailed = "false"
    }

    stages {
        stage ("Stage 1") {
            parallel {
                stage("Stage 1.a") {
                    steps {
                        catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
                            bat "ech Stage 1.a" // Should fail because ech is no valid command
                        }
                    }
                    post {
                        failure  {
                            script {
                                env.stageOneFailed = "true"
                            }
                        }
                    }
                }

                stage("Stage 1.b") {
                    steps {
                        catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
                            bat "echo Stage 1.b" // Should not fail
                        }
                    }
                    post {
                        failure  {
                            script {
                                env.stageTwoFailed = "true"
                            }
                        }
                    }
                }
            }
        }

        stage("Stage 2") {
            parallel {
                // Only run stages if earlier steps didn't fail
                stage("Stage 2.a") {
                    when {
                        environment(name: "stageOneFailed", value: "false")
                    }
                    steps {
                        catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
                            bat "echo Stage 2.a"
                        }
                    }
                    post {
                        failure  {
                            script {
                                env.stageOneFailed = "true"
                            }
                        }
                    }
                }
                stage("Stage 2.b") {
                    when {
                        environment(name: "stageTwoFailed", value: "false")
                    }
                    steps {
                        catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
                            bat "echo Stage 2.b"
                        }
                    }
                    post {
                        failure  {
                            script {
                                env.stageTwoFailed = "true"
                            }
                        }
                    }
                }
            }
        }
    }
}

但是在运行示例时,阶段1.a失败,但阶段2.a仍在运行,也许任何人都可以在这里提供帮助。
编辑:我添加了输出,以查看stageNFailed设置为什么值。即使在调用env.stageOneFailed之后,当进入下一阶段时,它仍采用旧值false。
我的假设是,当调用脚本env.stageNFailed =“true”时,该值只是临时为该阶段设置的。

fbcarpbf

fbcarpbf1#

您所使用的示例是一种完全可以接受的方法。您引入了2个env变量,用于确定上一步是否失败。您使用了catchError来确保管道在阶段失败时不会失败。您必须在每个阶段使用catchError来防止管道失败(但我想您已经知道了这一点)。在stage的post部分中,您已经将相应的env变量设置为true,这也是正确的。

post {
    failure {
        script {
            env.stageOneFailed = true
        }
    }
}

然后,当下一个相关阶段开始时,您已经使用when条件检查是否应该运行该阶段(您也可以执行类似的操作):

when {
    expression { stageOneFailed == false }
}

所以基本上你做的每件事都是对的。

相关问题