如何为Jenkins管道中的失败阶段实现重试选项?

sor*_*rin 58 groovy jenkins-workflow jenkins-pipeline jenkinsfile

我有一个具有多个阶段的Jenkins文件,其中一个实际上是另一个工作(部署一个),在某些情况下可能会失败.

我知道我可以使用Jenkinsfile提示,但我真的不知道如何为这个作业实现重试机制.

我希望能够单击失败的舞台并选择重试它. 詹金斯-管道与 - 阶段

小智 34

你应该能够结合重试+输入来做那样的事情

stage('deploy-test') {
   try {
     build 'yourJob'
   } catch(error) {
     echo "First build failed, let's retry if accepted"
     retry(2) {
        input "Retry the job ?"
        build 'yourJob'
     }
   }
}
Run Code Online (Sandbox Code Playgroud)

如果你想让它完成,如果没有人验证,你也可以使用超时输入.还有waitUntil可能有用但我尚未使用它

编辑:WaitUntil似乎绝对是最好的,你应该玩它一点但这样的东西更干净:

stage('deploy-test') {
   waitUntil {
     try {
       build 'yourJob'
     } catch(error) {
        input "Retry the job ?"
        false
     }
   }
}
Run Code Online (Sandbox Code Playgroud)

顺便说一下,这里有doc所有步骤https://jenkins.io/doc/pipeline/steps


小智 7

这个要点(不是我的)是我在尝试实现此功能时找到的更好的选项之一.https://gist.github.com/beercan1989/b66b7643b48434f5bdf7e1c87094acb9

将其更改为共享库中的方法,该方法仅根据我的需要重试或中止.还添加了最大重试次数并设置了超时变量,以便我们可以根据需要的作业或阶段进行更改.

package com.foo.bar.jenkins

def class PipelineHelper {
    def steps

    PipelineHelper(steps) {
        this.steps = steps
    }

    void retryOrAbort(final Closure<?> action, int maxAttempts, int timeoutSeconds, final int count = 0) {
        steps.echo "Trying action, attempt count is: ${count}"
        try {
            action.call();
        } catch (final exception) {
            steps.echo "${exception.toString()}"
            steps.timeout(time: timeoutSeconds, unit: 'SECONDS') {
                def userChoice = false
                try {
                    userChoice = steps.input(message: 'Retry?', ok: 'Ok', parameters: [
                            [$class: 'BooleanParameterDefinition', defaultValue: true, description: '', name: 'Check to retry from failed stage']])
                } catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) {
                    userChoice = false
                }
                if (userChoice) {
                    if (count <= maxAttempts) {
                        steps.echo "Retrying from failed stage."
                        return retryOrAbort(action, maxAttempts, timeoutMinutes, count + 1)
                    } else {
                        steps.echo "Max attempts reached. Will not retry."
                        throw exception
                    }
                } else {
                    steps.echo 'Aborting'
                    throw exception;
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

最多2次重试的示例用法,等待输入60秒.

def pipelineHelper = new PipelineHelper(this)

stage ('Retry Example'){
    pipelineHelper.retryOrAbort({
        node{
            echo 'Here is an example'
            throw new RuntimeException('This example will fail.')
        }
    }, 2, 60)
}
Run Code Online (Sandbox Code Playgroud)

只记得将节点放在闭包内部,以便等待输入不会阻塞执行程序.

如果你有付费jenkins企业Cloudbees有一个Checkpoint插件可以更好地处理这个,但它不打算发布为开源Jenkins(JENKINS-33846).


Lui*_*los 6

这个有一个很好的增量等待

stage('deploy-test') {
 def retryAttempt = 0
 retry(2) {
    if (retryAttempt > 0) {
       sleep(1000 * 2 + 2000 * retryAttempt)
    }

    retryAttempt = retryAttempt + 1
    input "Retry the job ?"
    build 'yourJob'
 }
}
Run Code Online (Sandbox Code Playgroud)

  • `sleep()` 有[默认单位秒](https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/#sleep-sleep),所以除非你希望第一个等待是超过一个小时,指定 `sleep(..., unit:"MILLISECONDS")` 或使用更少的秒数。 (2认同)