webentwicklung-frage-antwort-db.com.de

Wie implementiere ich eine Wiederholungsoption für fehlgeschlagene Phasen in Jenkins-Pipelines?

Ich habe eine Jenkins-Datei mit mehreren Phasen und eine davon ist in der Tat eine andere Aufgabe (die Bereitstellung einer), die in einigen Fällen fehlschlagen kann.

Ich weiß, dass ich mit Jenkinsfile Eingabeaufforderungen erstellen kann, aber ich weiß nicht, wie ich einen Wiederholungsmechanismus für diesen Job implementieren soll.

Ich möchte in der Lage sein, auf die fehlerhafte Stufe zu klicken und sie erneut zu versuchen. jenkins-pipelines-with-stages

54
sorin

Sie sollten in der Lage sein, retry + input zu kombinieren, um so etwas zu tun

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

sie können auch eine Zeitüberschreitung für die Eingabe verwenden, wenn diese beendet werden soll, wenn niemand validiert. Es gibt auch waitUntil, das nützlich sein könnte, aber ich habe es noch nicht verwendet

Edit: WaitUntil scheint definitiv das Beste zu sein, du solltest ein bisschen damit spielen, aber so etwas ist sauberer:

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

Übrigens gibt es hier doc alle Schritte https://jenkins.io/doc/pipeline/steps

31
fchaillou

Dieses Gist (nicht meins) war eine der besseren Optionen, die ich beim Versuch gefunden habe, diese Funktionalität auch zu implementieren. https://Gist.github.com/beercan1989/b66b7643b48434f5bdf7e1c87094acb9

Es wurde in eine Methode in einer gemeinsam genutzten Bibliothek geändert, die es gerade noch einmal versucht oder abgebrochen hat, um meine Anforderungen zu erfüllen. Außerdem wurde eine maximale Anzahl von Wiederholungsversuchen hinzugefügt und die Zeitüberschreitung variabel festgelegt, damit wir sie je nach dem Auftrag oder der Phase ändern können, die sie benötigt.

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

Beispielverwendung mit maximal 2 Wiederholungsversuchen, die 60 Sekunden auf Eingaben warten.

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

Denken Sie daran, Knoten in den Verschluss einzufügen, damit das Warten auf eine Eingabe keinen Executor blockiert.

Wenn Sie das bezahlte Jenkins-Unternehmen haben, verfügt Cloudbees über ein Checkpoint-Plugin, das dies besser handhabt. Es ist jedoch nicht geplant, es für Open-Source-Jenkins zu veröffentlichen ( JENKINS-33846 ).

7
dben1713

Dieser mit einer schönen inkrementellen Wartezeit

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'
 }
}
6
LuisKarlos