繁体   English   中英

如何在Jenkins声明式管道语法中继续失败的阶段

[英]How to continue past a failing stage in Jenkins declarative pipeline syntax

我想在Jenkins声明式管道语法中定义多个阶段,这些阶段可以继续通过其中任何一个失败的阶段。 我找不到任何真正重复的现有问题,因为它们全部采用或允许使用脚本语法。

pipeline {
    agent any
    stages {
        stage('stage 1') {
            steps {
                echo "I need to run every time"
            }
        }
        stage('stage 2') {
            steps {
                echo "I need to run every time, even if stage 1 fails"
            }
        }
        stage('stage 3') {
            steps {
                echo "Bonus points if the solution is robust enough to allow me to continue *or* be halted based on previous stage status"
            }
        }
    }
}

需要澄清的是,我不是在寻找如何通过脚本语法完成此任务。 我试图了解这种流控制是否实际上以声明性语法得到支持和形式化。 为此,我将尝试定义所需的内容:

需要

  • 没有尝试/抓住。 我不想陷入脚本模式,也不想将我的声明式管道“包装”在另一个共享库或脚本块中。
  • 没有post step恶作剧。 我想要真正的多个阶段,而不是一个阶段,一个post always包含其他所有逻辑

可选的

  • 失败阶段应被视为失败; 我不希望失败的阶段显示为绿色,因为它已“跳过”或“继续”。
  • 阶段失败的构建应标记为红色(或黄色,或任何非绿色)。

相关但不充分

我可能会遗漏一些东西,但是声明性的, 观点的管道的想法是提供最简单的用例的覆盖范围。 当您需要一些自以为是的东西时,您不得不诉诸脚本化的管道,这仅是指“声明性管道”的“要求”:现在不会发生。

至于您的其他“需求”,则没有什么意义,因为整个想法是将低级丑陋包装到共享库中,从而为用户提供以下结构:

    mylib.failable_stages({
      stages {
        stage('stage 1') {
          steps {
            echo "I need to run every time"
          }
        }
        stage('stage 2') {
          steps {
            echo "I need to run every time, even if stage 1 fails"
          }
        }
        stage('stage 3') {
          steps {
            echo "Bonus points if the solution is robust enough to allow me to continue *or* be halted based on previous stage status"
          }
        }
      }
    })

自然,您将不得不找到或实现这样的mylib类,并且failable_stages将获得一个闭包,并将其包装在各种管道/样板代码段中。

希望这会有所帮助。

现在可以这样:

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

管道示例

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

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

编辑:这是此答案最初为的问题。 对于其他一些问题,这也是正确的答案,这就是为什么我也在此处发布此答案的原因。 这是解决多个类似问题的正确方法。 我已经针对他们的具体问题量身定制了其他答案,以使其清楚。 我只是复制答案以节省时间。 这并不意味着它不是正确的答案。

我认为这取决于工作彼此之间的依赖程度。 从您的示例得出,我认为

  • 第一阶段独立于所有其他阶段,因为它是第一阶段
  • 阶段2独立于所有其他阶段,因为阶段1可能会立即失败,并且阶段2仍需要运行
  • 第三阶段取决于第一阶段和第二阶段的结果

所以对应的管道可能是

pipeline {
    stages {
        stage('Independent tasks') {
            parallel {
                stage('stage 1') {
                    steps {
                        sh 'exit 1' // failure
                    }
                }
                stage('stage 2') {
                    steps {
                        echo 'Happens even so stage 1 fails'
                        sh 'exit 0' // success
                    }
                }
            }
            post {  // 'stage 3'
                failure {
                    echo "... at least one failed"
                }
                success {
                    echo "Success!"
                }
            }
        }
        stage ('stage 4') {
            steps {
                echo 'Happens only if all previous succeed'
            }
        }
    }
}

第1阶段第2阶段将始终运行, 第3阶段对它们的成功/失败进行反应。


另外的想法:这个概念仅在管道的“末端”起作用。 如果您需要在中间某个地方并且必须继续构建,则可以将其移至自己的作业中并使用build job插件。

pipeline {
    stages {
    stage('Start own job for stage 1, 2, 3') {
        steps {
            build job: 'stageOneTwoThree', propagate: false, wait: true
        }
    }
    stage ('stage 4') {
        steps {
            echo 'Happens always, because "propagate: false"'
        }
    }
}

我使用post实现了它。 我的要求是无论构建状态如何,都发送松弛通知。

@Library('instanceGroups')
import x.z.y.jenkins.libraries.SlackNotifier

def slackHelper = new x.z.y.jenkins.libraries.SlackNotifier(env)
final String projectName = "pomeranian"
final String featureBranchPattern = "f_"

pipeline {
    agent any
    options { disableConcurrentBuilds() }

    stages {
        stage('clean') {
            steps {
                script {
                    try {
                        echo 'Current Branch...' + env.BRANCH_NAME
                        sh 'rm -rf /var/lib/jenkins/.gradle/caches'
                        sh './gradlew clean'
                    } catch (e) {
                        currentBuild.result = 'FAILURE'
                        slackHelper.buildGenericJobFailureNotificationMessage()
                        throw e
                    }
                }
            }
        }

        stage('compile') {
            steps {
                script {
                    try {
                        sh "./gradlew compileJava"
                    } catch (e) {
                        currentBuild.result = 'FAILURE'
                        slackHelper.getCompilationFailureSlackNotificationMessage()
                        throw e
                    }
                }
            }
        }

        stage('test') {
            steps {
                script {
                    try {
                        sh "./gradlew test"
                    } finally {
                        junit 'build/test-results/test/*.xml'

                        slackHelper.getTestStatuses(currentBuild)
                        slackHelper.buildUnitTestSlackNotificationMessage()
                    }
                }
            }
        }

        stage('publish 2 nexus') {
            steps {
                script {
                  // some code
                }
            }
        }

        stage('git tagging') {
            steps {
                script {
                    // some more code...
            }
        }
    }


    post {
        always {
            script {
                slackHelper.finalBuildStatusMessage(currentBuild)
                slackSend(channel: '#ci-cd', attachments: slackHelper.getFinalSlackMessage())
            }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM