Jenkins管道在使用catchError后获取当前阶段状态

Jenkins管道在使用catchError后获取当前阶段状态,jenkins,jenkins-pipeline,Jenkins,Jenkins Pipeline,这是我先前问题的后续行动: 事实证明,我可以将管道保持为成功,但如果我愿意,可以通过catchError将单个阶段标记为不稳定,如下所示: node() { stage("Stage 1") { catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') { sh 'exit 1' } } } 如果我想获取管道本身的当前状态,我可以使用c

这是我先前问题的后续行动:

事实证明,我可以将管道保持为成功,但如果我愿意,可以通过
catchError
将单个阶段标记为不稳定,如下所示:

node()
{
    stage("Stage 1")
    {
        catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE')
        {
            sh 'exit 1'
        }
    }
}
如果我想获取管道本身的当前状态,我可以使用
currentBuild.getCurrentResult()
,但我看不到类似的
currentStage

我有兴趣尝试一种模式,在我的阶段可能看起来像这样:

stage("1") {
    catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') {
        // do stuff
    }
    // perhaps more catchError() blocks
    if(currentStage.getCurrentResult() == "UNSTABLE") {
        // do something special if we're unstable
    }
}
但这将失败,因为没有可用的
currentStage


因此,基本上,
catchError()
很好,但我想知道,如果状态发生变化,如何将状态变化捕捉到我的阶段。。。有人知道您如何通过管道访问当前阶段的状态吗

尽管目前还没有直接的方法来访问管道中某个阶段的结果,但您可以解决这个问题。这是考虑到您只对
成功
不稳定
问题阶段结果感兴趣,而不是
失败

解决方法是在管道顶部初始化一个空映射,以存储每个阶段的结果。现在,不要使用
catchError()
方法,而是将
unstable()
方法与try-catch块结合使用。这是因为后者不仅允许您将结果设置为不稳定,还可以执行其他操作,例如将结果添加到except块中的贴图。然后,您可以从
if
语句中的映射中读取存储的结果

示例

stageResults = [:]
...
stage("1") {
    try {
        // do stuff
        // Add to map as SUCCESS on successful execution 
        stageResults."{STAGE_NAME}" = "SUCCESS"
    } catch (Exception e) {
        // Set the result and add to map as UNSTABLE on failure
        unstable("[ERROR]: ${STAGE_NAME} failed!")
        currentBuild.result = "SUCCESS"
        stageResult."{STAGE_NAME}" = "UNSTABLE"
    }
    if(stageResults.find{ it.key == "{STAGE_NAME}" }?.value == "UNSTABLE") {
        // do something special if we're unstable
    }
}

作为Dibakar Aditya答案的补充,可以将所有内容封装在一个类似于常规步骤的函数中。即:

stage("1") {
    def localSuccess = catchLocalError {
        // do stuff
    }
    if(!localSuccess) {
        // do something special if we're unstable
    }
}

boolean catchLocalError(Closure c) {
    try {
        c()
        return true
    } catch (Exception e) {
        return false
    }
}
我是这样做的(为了保持捕捉错误):

def布尔测试结果=false
管道{
...
阶段('x'){
台阶{
catchError(buildResult:'SUCCESS',stagerResult:'FAILURE'){
//
//如果我们到达这里,上述步骤没有失败
//
脚本{test_results=true}
}
}
}
阶段('y'){
台阶{
剧本{
如果(测试结果==真){
}否则{
}
}
}
}
}

对于我来说,这是最优雅的方式,它是一个部分。 在您的示例中,您将阶段标记为
不稳定
,这样之后就可以使用
post->UNSTABLE
捕获它

stage("1") {
    steps {
        catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') {
            error 'Something goes wrong'
        }
    }
    post {
        always { echo 'Executed on every build'}
        unstable { echo 'Executed only if build is unstable (marked by catchError)'}
    }
}

是的,我已经做了类似的事情,但我通常只是在
阶段
块的开头设置一个布尔状态变量,比如
boolean stageFailed=false
,然后做try/catch,稍后再检查。我曾希望,
catchError
会简化这一点,但它看起来就像一个带有隐藏捕获的专门try块,设置了一些管道无法访问的状态,这限制了它对我们的实用性。如果我能以某种方式访问当前阶段的状态,情况就会改变。。。但现在看来这是不可能的(我喜欢可能使用
catchError
的一点是,它可以将单个阶段的状态设置为不稳定等。这显示在Jenkins的阶段视图中……有没有一种方法可以在不使用catchError的情况下设置单个阶段的状态?应该可以修复的是,您愿意将阶段步骤移动到catchLo中calError/catchError。如果有兴趣,我可以更新我的答案。
stage("1") {
    steps {
        catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') {
            error 'Something goes wrong'
        }
    }
    post {
        always { echo 'Executed on every build'}
        unstable { echo 'Executed only if build is unstable (marked by catchError)'}
    }
}