Jenkins: 忽略流水线构建步骤中的失败

有了 Jenkins build flow 插件,这是可能的:

ignore(FAILURE){
build( "system-check-flow" )
}

如何使用声明性管道语法完成此操作?

139020 次浏览

在新的管道中,可以使用 try-catch 来实现这一点。

node{
try{
build job: 'system-check-flow'
}
catch (err){
echo "system-check-flow failed"
}
try{
build job: 'job2'
}
catch (err){
echo "job2 failed"
}
}

在这里,它将构建“系统检查流”作业。如果失败,它将捕获错误,忽略,然后继续构建‘ job2’

要忽略声明性管道中失败的步骤,基本上有两个选项:

  1. 使用 script步骤和 try-catch块(类似于 R _ K 之前的命题,但是使用声明式风格)
stage('someStage') {
steps {
script {
try {
build job: 'system-check-flow'
} catch (err) {
echo err.getMessage()
}
}
echo currentBuild.result
}
}
  1. 使用 catchError
stage('someStage') {
steps {
catchError {
build job: 'system-check-flow'
}
echo currentBuild.result
}
}

在这两种情况下,构建都不会因为 build job: 'system-check-flow'中的异常而中止。在这两种情况下,都将执行 echo步骤(以及后面的任何步骤)。

但是在这两个选项之间有一个 重要的区别。在第一种情况下,如果 try部分引发异常,则整个构建状态不会改变(因此 echo currentBuild.result = > SUCCESS)。在第二种情况下,整个构建将会失败(因此 echo currentBuild.result = > FAILURE)。

这一点很重要,因为在第一种情况下(通过设置 currentBuild.result = 'FAILURE')总是可能使整个构建失败,但在第二种情况下(currentBuild.result = 'SUCCESS'不起作用)使用 不行 修理构建。

在最近的版本中,可以通过 propogate=false选项来构建步骤。

连结: Https://jenkins.io/doc/pipeline/steps/pipeline-build-step/

build job:"jobName", propagate:false

对于我的发声管道,我找到了另一种解决方案:

stage('Deploy test')
{
steps
{
bat returnStatus: true, script: 'sc stop Tomcat9'
// The return value of the step will be the status code!
// evaluate return status yourself, or ignore it
}
}

Sh 命令在 Unix 平台上执行脚本也是如此。

该示例忽略返回状态,因为由于以前失败的管道运行,tomcat 可能已经停止。

我一直在寻找答案,我找到了一个黑客!我把 try/catch 块放在整个舞台上:

 try {
stage('some-stage') {
//do something
}
} catch (Exception e) {
echo "Stage failed, but we continue"
}
try {
stage("some-other-stage") {  // do something }
} catch (Exception e) {
echo "Stage failed, but we still continue"
}

结果你会得到这样的结果: enter image description here

这仍然不理想,但它给出了必要的结果。

除了简单地通过阶段之外,现在还有可能使阶段失败,但是继续管道并通过构建:

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

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

只要确保您的 Jenkins 是最新的,因为这个特性只有在 “管道: 基本步骤”2.16(2019年5月14日)以后才可用。在此之前,catchError仍然可用,但没有参数:

        steps {
catchError {
sh "exit 1"
}
}

详细讨论请参阅 这篇文章

试试这个例子:

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

你可以把步骤脚本放在“ post”步骤中,如果它是一个类似拆卸的步骤

代码如下:

    post {
always {
script {
try{
echo 'put your alway need run scripts here....if it's a teardown like step'
}catch (err) {
echo 'here failed'
}
script{
emailext (
xxxx
)
}
}
pipeline {
agent any


stages {
stage('Stage') {
steps{
script{
jobresult = build(job: './failing-job',propagate:false).result
if(jobresult != 'SUCCESS'){
catchError(stageResult: jobresult, buildResult: 'UNSTABLE'){
error("Downstream job failing-job failed.")
}
}
}
}
}
}
}

对于那些想知道如何将下游作业的结果设置为阶段/构建的人来说,这不是最优雅的解决方案,但它可以完成工作。有趣的是,如果 stageResult 变量可以作为全局变量或 catchError 块之外的变量使用,那么就不需要这些解决方案了。遗憾的是,事实并非如此,而且我认为唯一能够将舞台结果设置成管道的方法就是这种方法。这里需要 error ()块,否则 catchError 将不会设置 stageResult/buildResult (catchError 块当然需要一个错误)。

最干净、最新的方法是:

stage('Integration Tests') {
steps {
script {
warnError(message: "${STAGE_NAME} stage was unstable.", catchInterruptions: false) {
// your scripts
}
}
}
}

参考资料: https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/#warnerror-catch-error-and-set-build-and-stage-result-to-unstable