继续 Jenkins 管道过去失败的阶段

问题描述 投票:0回答:9

我有一系列执行快速检查的阶段。 我想把它们全部完成,即使有失败。 例如:

stage('one') {
    node {
        sh 'exit 0'
    }
}
stage('two') {
    node {
        sh 'exit 1'   // failure
    }
}
stage('three') {
    node {
        sh 'exit 0'
    }
}

阶段

two
失败,因此默认情况下阶段
three
不执行。

通常这是

parallel
的工作,但我想在舞台视图中显示它们。 在下面的模型中:

  • Build #4 显示了通常发生的情况。 作业
    two
    失败,因此
    three
    无法运行。
  • 我对 Build #6 进行了 Photoshop 处理,以展示我想看到的内容。 作业
    two
    失败并按原样显示,但
    three
    仍在运行。 真正的 Jenkins 可能会显示整个 Build #6 略带红色,这当然很好。

Mock up of desired Stage View result

jenkins jenkins-pipeline
9个回答
137
投票

现在这是可能的。下面是声明性管道的示例,但

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 将显示为失败:

Pipeline Example

正如您可能已经猜到的,您可以自由选择

buildResult
stageResult
,以防您希望它不稳定或其他任何情况。您甚至可以使构建失败并继续执行管道。

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

编辑:您需要“管道:基本步骤”2.16(2019年5月14日)


24
投票

我也有同样的担忧。我这样做能够解决它。

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

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"
    }
}

13
投票

这取决于您使用的是声明式管道语法还是脚本化管道语法

声明式管道语法

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

后置条件块包含与steps部分相同的steps

脚本化管道语法:

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"
    }
}

6
投票

解决方案:为了始终继续詹金斯管道中失败的步骤:

选项 1. 将函数包装在 try/catch 或 bash 脚本中

<someOpertation> || 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"
                    }
                }
            }
        }
    }
}

4
投票

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

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

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

3
投票

我使用后期操作解决了这个问题: https://jenkins.io/doc/pipeline/tour/post/

           post {
            always {
                ...
            }
           }

2
投票

尝试这个例子:

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

2
投票

我的简单建议是,利用 shell 脚本之美, $ cmd1 || cmd2:这将运行 cmd1,如果失败,它将运行 cmd2。 在您的情况下,cmd2 很简单“echo”cmd1 失败,继续下一步” 就这样。 它就像一个魅力:-)


0
投票

这已经很旧了,但我会为其添加一个扩展。 如果您有一个循环并且循环内部出现错误,但您想继续循环:

def markErrorFlag = false; // userdefined marker
def list = [];             // must be declared here to be accessed across stages

pipeline {
agent any
stages {

  stage('1') {
    steps {
      // just a list of numbers
      list = [3,2,1,0,1,2,3];
    }
  }

  stage('2') {
    options {
      // how to mark stage and build 
      catchError(message: "Test failed",    // optional, text into log
                 stageResult: 'FAILURE',    // stage failed
                 buildResult: 'UNSTABLE');  // build unstable
    }
    steps {
      script {
        // step through the list
        for ( int x : list ) {
          try {
            // will cause error except for x=0
            sh "exit $x";
          } catch (err) {
            // to show something in log
            println "error in : $x"
            // set userdefined marker
            markErrorFlag = true;
          }
        }
        
        if (markErrorFlag) {
          // move failure up to catchError()
          sh 'exit 1'
        }
      }
    }
  }

  stage('3') {
    steps {
      println "buildstatus is: ${currentBuild.currentResult}"
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.