将Jenkins管道阶段显示为失败而不会使整个作业失败

tec*_*sis 48 groovy jenkins jenkins-workflow jenkins-pipeline

这是我正在玩的代码

node {
    stage 'build'
    echo 'build'

    stage 'tests'
    echo 'tests'

    stage 'end-to-end-tests'
    def e2e = build job:'end-to-end-tests', propagate: false
    result = e2e.result
    if (result.equals("SUCCESS")) {
        stage 'deploy'
        build 'deploy'
    } else {
        ?????? I want to just fail this stage
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法让我将"端到端测试"阶段标记为失败,而不会使整个工作失败?传播假只是总是将舞台标记为真,这不是我想要的,但传播真实标志着失败的工作,我也不想要.

小智 21

Stage现在占用一个块,所以将stage包装在try-catch中.舞台内的Try-catch使其成功.

前面提到的新功能将更加强大.同时:

try {
   stage('end-to-end-tests') {
     node {      
       def e2e = build job:'end-to-end-tests', propagate: false
       result = e2e.result
       if (result.equals("SUCCESS")) {
       } else {
          sh "exit 1" // this fails the stage
       }
     }
   }
} catch (e) {
   result = "FAIL" // make sure other exceptions are recorded as failure too
}

stage('deploy') {
   if (result.equals("SUCCESS")) {
      build 'deploy'
   } else {
      echo "Cannot deploy without successful build" // it is important to have a deploy stage even here for the current visualization
   }
}
Run Code Online (Sandbox Code Playgroud)


Jes*_*ick 13

听起来像JENKINS-26522.目前,您可以做的最好的事情是设置一个总体结果:

if (result.equals("SUCCESS")) {
    stage 'deploy'
    build 'deploy'
} else {
    currentBuild.result = e2e.result
    // but continue
}
Run Code Online (Sandbox Code Playgroud)

  • 有没有办法反之亦然.用红色标记不成功的Stage,但是用蓝色标记构建(那个球)的状态? (4认同)

gre*_*nix 12

我最近尝试使用vaza的答案 将Jenkins管道阶段显示为失败而不会将整个作业作为模板来编写一个函数,该函数在类似于作业名称的自己的阶段中执行作​​业.令人惊讶的是它有效,但也许一些常规专家看看它:)

以下是其中一个作业中止的情况: 在此输入图像描述

def BuildJob(projectName) {
    try {
       stage(projectName) {
         node {      
           def e2e = build job:projectName, propagate: false
           result = e2e.result
           if (result.equals("SUCCESS")) {
           } else {
              error 'FAIL' //sh "exit 1" // this fails the stage
           }
         }
       }
    } catch (e) {
        currentBuild.result = 'UNSTABLE'
        result = "FAIL" // make sure other exceptions are recorded as failure too
    }
}

node {
    BuildJob('job1')
    BuildJob('job2')
}
Run Code Online (Sandbox Code Playgroud)


Eri*_*k B 9

现在甚至可以使用声明性管道:

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'
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,所有阶段都将执行,管道将成功,但是阶段2将显示为失败:

管道示例

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

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

  • @JShorthouse Pipeline:基本步骤需要是 2.18 或更高版本。你用的是什么版本? (3认同)
  • 我收到“无效参数“buildResult”,您的意思是“null”吗?”和“无效参数“stageResult”,您的意思是“null”吗?” (2认同)
  • 我找到了另一种现在有效的方法,但这可能就是问题所在 - 我认为“相当新”意味着它可以在我几个月前安装的 Jenkins 上工作,但从该版本的发布日期来看,我认为你的意思是在上周。 (2认同)

sco*_*ysB 5

为了在下游作业失败时显示失败阶段的成功构建支持用户能够取消构建(包括所有后续阶段),我必须结合使用各种解决方案,特别是try/catch抛出catchError()

env.GLOBAL_BUILD_ABORTED = false        // Set if the user aborts the build

pipeline {
    agent any

    stages {
        stage('First Stage') {
            when { expression { env.GLOBAL_BUILD_ABORTED.toBoolean() == false } }

            steps {
                catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
                    myLocalBuildMethod('Stage #1, build #1')
                    myLocalBuildMethod('Stage #1, build #2')
                }
            }
        }

        stage('Second Stage') {
            when { expression { env.GLOBAL_BUILD_ABORTED.toBoolean() == false } }

            steps {
                catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
                    myLocalBuildMethod('Stage #2, build #1')
                    myLocalBuildMethod('Stage #2, build #2')
                    myLocalBuildMethod('Stage #2, build #3')
                }
            }
        }
    }
}

def myLocalBuildMethod(myString) {
    /* Dummy method to show User Aborts vs Build Failures */

    echo "My Local Build Method: " + myString

    try {
        build (
            job: "Dummy_Downstream_Job"
        )

    } catch (e) {
        /* Build Aborted by user - Stop All Test Executions */
        if (e.getMessage().contains("was cancelled") || e.getMessage().contains("ABORTED")) {

            env.GLOBAL_BUILD_ABORTED = true
        }
        /* Throw the execiption to be caught by catchError() to mark the stage failed. */
        throw (e)
    }

    // Do other stuff...
}
Run Code Online (Sandbox Code Playgroud)