withMaven不稳定的构建结果不保留在Jenkins声明性管道中

withMaven不稳定的构建结果不保留在Jenkins声明性管道中,maven,jenkins,jenkins-declarative-pipeline,Maven,Jenkins,Jenkins Declarative Pipeline,当maven构建步骤由于测试失败而退出时,我想将构建结果设置为不稳定。 我正在使用withMaven构建步骤,该步骤提供了对maven测试结果的特殊处理: 如果测试失败,它会在步骤失败之前将构建结果设置为不稳定 这在使用脚本化管道时非常有效。 但是,在声明性管道的情况下,构建结果设置为FAILURE 下面的代码示例说明了这一点 编辑:请注意,try/catch和post块不是示例工作所必需的。它们的存在只是为了在调用withMaven后立即检查currentBuild.result的值 声明性的

当maven构建步骤由于测试失败而退出时,我想将构建结果设置为
不稳定
。 我正在使用withMaven构建步骤,该步骤提供了对maven测试结果的特殊处理: 如果测试失败,它会在步骤失败之前将构建结果设置为
不稳定

这在使用脚本化管道时非常有效。 但是,在声明性管道的情况下,构建结果设置为
FAILURE

下面的代码示例说明了这一点

编辑:请注意,try/catch和post块不是示例工作所必需的。它们的存在只是为了在调用
withMaven
后立即检查
currentBuild.result
的值

声明性的

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                withMaven() {
                    sh 'mvn clean verify' // -> Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
                }
            }

            post {
                always {
                    echo "CurrentResult: $currentBuild.currentResult" // -> FAILURE
                    echo "Result: $currentBuild.result"               // -> FAILURE
                                                                      // overall build result -> FAILURE
                }
            }
        }
    }
}
脚本化的

node() {
    stage('Build') {
        try {
            withMaven() {
                sh 'mvn clean verify'  // -> Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
            }
        } catch (e) {
            echo "CurrentResult: $currentBuild.currentResult" // -> UNSTABLE
            echo "Result: $currentBuild.result"               // -> UNSTABLE
                                                              // overall build result -> UNSTABLE
        }
    }
}

如何在声明性管道中保留maven构建步骤中的
不稳定
的构建结果


使用的版本:Jenkins 2.204.1、Pipeline Maven Integration Plugin 3.8.2、Maven 3.6.3(安装在build agent上),采用OpenJDK 1.8.0Þ。

管道之间的区别在于在脚本上使用了try/catch。我要做的是以下几点

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                script {
                    try {
                        withMaven() {
                            sh 'mvn clean verify' // -> Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
                        }
                    } catch (e) {
                        echo "CurrentResult: $currentBuild.currentResult" // -> UNSTABLE
                        echo "Result: $currentBuild.result"               // -> UNSTABLE
                    }
                }
            }

            post {
                always {
                    echo "CurrentResult: $currentBuild.currentResult" // -> UNSTABLE
                    echo "Result: $currentBuild.result"               // -> UNSTABLE
                                                                      // overall build result -> UNSTABLE
                }
            }
        }
    }
}

管道之间的区别在于,在脚本化管道上使用了try/catch。我要做的是以下几点

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                script {
                    try {
                        withMaven() {
                            sh 'mvn clean verify' // -> Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
                        }
                    } catch (e) {
                        echo "CurrentResult: $currentBuild.currentResult" // -> UNSTABLE
                        echo "Result: $currentBuild.result"               // -> UNSTABLE
                    }
                }
            }

            post {
                always {
                    echo "CurrentResult: $currentBuild.currentResult" // -> UNSTABLE
                    echo "Result: $currentBuild.result"               // -> UNSTABLE
                                                                      // overall build result -> UNSTABLE
                }
            }
        }
    }
}

正如弗雷德里克勒斯指出的那样,区别在于捕获的例外。 如果Jenkins文件中未捕获异常,则结果将设置为FAILED

我不是专家,但我提出了一种纯声明性的方法来解决这个问题,以交换更混乱的Jenkins文件

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                catchError(buildResult: null, catchInterruptions: false) {
                    withMaven() {
                        sh 'mvn clean verify' // -> Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
                    }
                }
            }

            post {
                always {
                    echo "CurrentResult: $currentBuild.currentResult" // -> UNSTABLE
                    echo "Result: $currentBuild.result"               // -> UNSTABLE
                }
            }
        }

        stage('Deploy') {
            when {
                expression {
                    currentBuild.result == "SUCCESS"
                }
            }
            steps {
                echo 'Deploy'
            }
        }
    }
}
解释
catchError(buildResult:null,catchInterruptions:false)

buildResult:null
相当于
buildResult:'SUCCESS'
,它防止
catchError
将buildResult设置为失败,而不管之前的值是什么

catchInterruptions:false
告诉catchError不要捕获(分别重新捕获)用于中断管道执行流的某些类型的异常

捕获异常的“缺点”是执行当前和所有后续的
阶段。
要跳过与结果相关的阶段,可以向阶段添加
when
声明性语句

从舞台上看,这就是它的样子


正如弗雷德里克勒斯指出的,区别在于捕获的例外。 如果Jenkins文件中未捕获异常,则结果将设置为FAILED

我不是专家,但我提出了一种纯声明性的方法来解决这个问题,以交换更混乱的Jenkins文件

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                catchError(buildResult: null, catchInterruptions: false) {
                    withMaven() {
                        sh 'mvn clean verify' // -> Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
                    }
                }
            }

            post {
                always {
                    echo "CurrentResult: $currentBuild.currentResult" // -> UNSTABLE
                    echo "Result: $currentBuild.result"               // -> UNSTABLE
                }
            }
        }

        stage('Deploy') {
            when {
                expression {
                    currentBuild.result == "SUCCESS"
                }
            }
            steps {
                echo 'Deploy'
            }
        }
    }
}
解释
catchError(buildResult:null,catchInterruptions:false)

buildResult:null
相当于
buildResult:'SUCCESS'
,它防止
catchError
将buildResult设置为失败,而不管之前的值是什么

catchInterruptions:false
告诉catchError不要捕获(分别重新捕获)用于中断管道执行流的某些类型的异常

捕获异常的“缺点”是执行当前和所有后续的
阶段。
要跳过与结果相关的阶段,可以向阶段添加
when
声明性语句

从舞台上看,这就是它的样子


try/catch在这里没用
withMaven
自动区分由于构建失败而导致的失败的maven调用和由于测试失败而导致的失败的maven调用,并相应地将构建状态设置为
失败
不稳定
。您的建议旨在始终将结果设置为
不稳定
。是吗,我不是withMaven步骤的专家?我更新的答案有用吗?我觉得奇怪的是,你曾经使用try-catch,而你放弃了它,希望得到相同的结果。你的解决方案非常有用,因为它将问题范围缩小到了异常处理。不过,我不喜欢在声明性管道中插入带有常规错误处理的脚本管道块@Dennis Kronbügel发现了一个更具“声明性”的解决方案,所以我更喜欢他的答案。我也喜欢Dennis的答案。就我个人而言,我尽量不使用太多的脚本块。当我需要编写脚本时,我会创建一个共享库steptry/catch在这里没有帮助
withMaven
自动区分由于构建失败而导致的失败的maven调用和由于测试失败而导致的失败的maven调用,并相应地将构建状态设置为
失败
不稳定
。您的建议旨在始终将结果设置为
不稳定
。是吗,我不是withMaven步骤的专家?我更新的答案有用吗?我觉得奇怪的是,你曾经使用try-catch,而你放弃了它,希望得到相同的结果。你的解决方案非常有用,因为它将问题范围缩小到了异常处理。不过,我不喜欢在声明性管道中插入带有常规错误处理的脚本管道块@Dennis Kronbügel发现了一个更具“声明性”的解决方案,所以我更喜欢他的答案。我也喜欢Dennis的答案。就我个人而言,我尽量不使用太多的脚本块。当我需要编写脚本时,我会创建一个共享库。在声明性管道的上下文中,任何未捕获的异常都会导致阶段失败,从而导致运行失败,结果是
失败
,而不管之前设置的任何构建结果(例如
不稳定
withMaven设置)。我喜欢这种方法。在我的例子中,我有一个特定的管道来运行性能测试,当性能低于某个因素时,测试就会失败。我希望管道在性能不好时变为黄色,而在性能不好时变为红色