jenkins 存在并行调用时的异常阶段行为

w7t8yxp5  于 2023-03-29  发布在  Jenkins
关注(0)|答案(1)|浏览(203)

在我的流水线中,有一些阶段可能会自己失败,但不会使构建过程失败。我希望这些阶段被指示为失败,因此将它们 Package 在try-catch块中。然而,有些阶段一直显示为成功,而实际上是失败的。经过一些研究,我能够查明问题:所有的“错误显示”阶段都有parallel调用(即使parallel中的块完全不做任何事情,效果也会发生)。最后,我能够将问题归结为这个最小的可重复示例:

node {
    try {
        stage("A") {
            error "E"
        }
    } catch(e) {}
    
    try {
        stage("B") {
            parallel a : {}, b : {}
            error "E"
        }
    } catch(e) {}
}

在这里,A阶段将显示为失败,B阶段将显示为成功。交换它们将产生相同的结果(A失败;B成功)。将error "E"更改为throw new Exception("E")并没有任何区别。在这两种情况下,异常都被抛出和捕获,没有任何问题,只是阶段外观受到影响。
之后,我尝试执行多个类似于B的阶段,结果发现每个阶段最初都显示为成功(即使它失败了)。当下一个阶段完成时,它也显示为成功,但同时前一个阶段开始显示为失败。当第三个阶段完成时,第二个阶段更改为失败,以此类推,直到最后一个阶段。最后一个阶段保持成功,因为没有下一个阶段来“更新”它。从逻辑上讲,这可以通过在链中的最后一个阶段之后插入一个虚拟parallel调用来解决:

...
parallel foo : {}
...

问题是:parallel是怎么回事?是我用错了还是有什么bug?
重要提示:我使用的是Jenkins 2.150.2,无法迁移到更新版本。

r6hnlfcb

r6hnlfcb1#

我认为parallel背后的想法一定是关于在之前或之后没有任何其他步骤的专用阶段。这种设计在声明式管道中非常明显:

pipeline {
    agent any
    stages {
        stage("A"){
            steps{
                catchError( stageResult: 'FAILURE'){
                    error "E"
                }
            }
        }
        stage("B") {
            parallel {
                stage("p1") {
                     steps{
                         catchError( stageResult: 'FAILURE'){
                         error "a"
                         }
                     }
                }
                stage("p2") {
                      steps{
                         catchError( stageResult: 'FAILURE'){
                          echo "b"
                         }
                      }
                }
            }
            //echo "test1" // illegal
        }
        stage("C"){
            steps{
                error "E"
            }
        }
    }
}

如果你试图在parallel后面放任何东西,都会有语法错误。所以来回答这个问题:你必须使用不可预测的步骤序列,所以你得到奇怪的结果.仍然,结果是奇怪的,只有舞台视图插件,因为我可以在我的Jenkins示例中看到.所以你有失败的阶段,但整个作业状态是失败,因为它应该是实际的绿色矩形.
回到你的脚本示例:

node {
        stage("A") {
            catchError(stageResult: 'FAILURE'){
            error "E"
            }
        }
        stage("B") {
            catchError( stageResult: 'FAILURE'){
            parallel a : {stage("p1"){error "a"}}, b : {stage("p2"){echo "b"}}
            }
        }
        stage("C"){
            error "E"
        }
}

使用catchError step更简洁。要将任何东西放在并行之后,您应该为此目的使用单独的阶段。如果您为并行保留单独的阶段,您将获得一致的Jenkins行为。

相关问题