继续Jenkins管道通过失败阶段

继续Jenkins管道通过失败阶段,jenkins,jenkins-pipeline,Jenkins,Jenkins Pipeline,我有一系列执行快速检查的阶段。我想完成所有这些,即使有失败。例如: stage('one') { node { sh 'exit 0' } } stage('two') { node { sh 'exit 1' // failure } } stage('three') { node { sh 'exit 0' } } 阶段two失败,因此默认情况下不执行阶段two 通常这将是并行的作业,但我想

我有一系列执行快速检查的阶段。我想完成所有这些,即使有失败。例如:

stage('one') {
    node {
        sh 'exit 0'
    }
}
stage('two') {
    node {
        sh 'exit 1'   // failure
    }
}
stage('three') {
    node {
        sh 'exit 0'
    }
}
阶段
two
失败,因此默认情况下不执行阶段
two

通常这将是并行的作业,但我想在阶段视图中显示它们。在下面的模型中:

  • 构建4显示了通常发生的情况。作业
    two
    失败,因此
    two
    不运行
  • 我用Photoshop 6版来展示我想看的东西。作业
    two
    失败并按原样显示,但
    two
    仍在运行。真正的詹金斯可能会展示整个建筑,略带红色,这当然很好

这应该行得通。但是,即使只有一个失败,所有框都是红色的,但您可以看到标有错误标记的框,因此您可以轻松区分失败的作业

def indexes = ['one', 'two', 'three']

node() {
    for (index in indexes) {
        catchError {
            stage(index) {
                println index
                sh '''echo "123"'''
            }
        }
    }
}

我也有同样的担心。通过这样做,我能够解决问题

第二阶段将显示为红色,并标记为失败,而其余阶段将继续运行。 您可以设置一个标志,在阶段结束时检查标志并通知整个构建的状态

node {

    def build_ok = true

    stage('one') {
        sh 'exit 0'
    }

    try{
        stage('two') {
            sh 'exit 1'   // failure
        }
    } catch(e) {
        build_ok = false
        echo e.toString()  
    }

    stage('three') {
        sh 'exit 0'
    }

    ....

    if(build_ok) {
        currentBuild.result = "SUCCESS"
    } else {
        currentBuild.result = "FAILURE"
    }
}

我决定使用post操作:


这取决于您是否正在使用

声明性管道语法

pipeline {
    agent any
    stages {
        stage('one') {
            steps {
                sh 'exit 0'
            }
        }
        stage('two') {
            steps {
                sh 'exit 1'   // failure
            }
        }
    }
    post {
        always {
            sh 'exit 0'
        }
    }
}
node {

    def build_ok = true

    stage('one') {
        sh 'exit 0'
    }

    try{
        stage('two') {
            sh 'exit 1'   // failure
        }
    } catch(e) {
        build_ok = false
        echo e.toString()  
    }

    stage('three') {
        sh 'exit 0'
    }

    if(build_ok) {
        currentBuild.result = "SUCCESS"
    } else {
        currentBuild.result = "FAILURE"
    }
}
包含与节相同的内容

脚本化管道语法

pipeline {
    agent any
    stages {
        stage('one') {
            steps {
                sh 'exit 0'
            }
        }
        stage('two') {
            steps {
                sh 'exit 1'   // failure
            }
        }
    }
    post {
        always {
            sh 'exit 0'
        }
    }
}
node {

    def build_ok = true

    stage('one') {
        sh 'exit 0'
    }

    try{
        stage('two') {
            sh 'exit 1'   // failure
        }
    } catch(e) {
        build_ok = false
        echo e.toString()  
    }

    stage('three') {
        sh 'exit 0'
    }

    if(build_ok) {
        currentBuild.result = "SUCCESS"
    } else {
        currentBuild.result = "FAILURE"
    }
}

这现在是可能的。下面是一个声明性管道的示例,但是
catchError
也适用于脚本化管道

pipeline {
    agent any
    stages {
        stage('1') {
            steps {
                sh 'exit 0'
            }
        }
        stage('2') {
            steps {
                catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
                    sh "exit 1"
                }
            }
        }
        stage('3') {
            steps {
                sh 'exit 0'
            }
        }
    }
}
在上面的示例中,所有阶段都将执行,管道将成功,但阶段2将显示为失败:

正如您可能已经猜到的,您可以自由选择
buildResult
stageResult
,以防它不稳定或其他任何情况。您甚至可以使构建失败并继续执行管道

只要确保您的Jenkins是最新的,因为这是一个相当新的功能


编辑:您需要

解决方案:以便始终继续jenkins管道中失败的步骤:

选项1。在try/catch或bash脚本中包装函数
| | true

尝试/捕获:

script {
  try {
      sh 'do your stuff'
  } catch (Exception e) {
      sh 'Handle the exception!'
  }
}
bash始终正确:

script {
  sh 'cp ~/someFile.txt ~/dev || true'
}
选项2。并行运行jenkins管道,并在步骤中设置
failFast false
配置属性

    pipeline {
    agent any
    stages {
        stage('Parallel Stage') {
            when {
                branch 'master'
            }
            failFast false
            parallel {
                stage('Branch A') {
                    agent {
                        label "for-branch-a"
                    }
                    steps {
                        echo "On Branch A"
                    }
                }
                stage('Branch B') {
                    agent {
                        label "for-branch-b"
                    }
                    steps {
                        echo "On Branch B"
                    }
                }
            }
        }
    }
}
试试这个例子:

stage('StageName1')
{
    steps
    {
        catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE')
        {
            SomeCodeThatCanBeErrored
        }
    }
}
stage('StageName2')
{
    steps
    {
        ContinueOtherCode
    }
}


在第2阶段使用try/catch或内置的
catchError
,如果出现异常,它也会将生成标记为红色。感谢@EngineerDollery和@izzekil的优秀评论。我确实可以使用try/catch阻止stage
two
停止管道,但是现在stage
two
被标记为成功——即使它实际上失败了,它也是绿色的。我能得到的最接近的方法是捕获失败,保存失败的阶段,然后在最后一个阶段完成后,将失败的阶段设置为“失败”。但是,这需要类似于中所要求的
currentStage
(被取代)。您可能会重复此内容,以提供更多详细信息,说明如何解决OP的问题。虽然此代码片段可能是解决方案,但确实有助于提高您文章的质量。请记住,您将在将来回答读者的问题,这些人可能不知道您的代码建议的原因。在本脚本中,是什么原因导致
stage('two)
标记为失败?@handras
sh“exit 1”
导致,这只是一个例子,看看在每种情况下会发生什么case@handras请注意,try-catch不在
阶段('two')
,该阶段仍将失败。我想我们可以在给出答案的日期之前确定自己的目标,但为了清楚起见,您是否介意,请加上介绍的日期,也许还有版本?很好的信息。非常有用的can catchError是否有finally block?@Turcia,一个阶段可以有一个“finally”块,
post{always{}
独立于
catchError
。OP使用的是一个声明性管道——这个示例是一个脚本化管道。声明性答案无法完成OP所寻找的内容。如果有第三阶段,第二阶段中的“退出1”将阻止第三阶段的执行。@drhender,声明性语法确实完成了它。阶段3在生成后操作中作为“始终”操作移动,即使生成失败也会运行。正确的解决方案取决于所需的内容。catch允许在特定阶段失败后继续生成,而生成后操作即使在任何阶段失败时也会执行。@JanHudec,如果上面给出的声明性答案有更改,则可以使其工作。然而,我所说的是正确的。如上所述,声明性回答没有满足OP的需求。这个currentBuild来自哪里?这是局部变量还是jenkins公开的?谢谢