Comment puis-je implémenter une option de nouvelle tentative pour les étapes ayant échoué dans les pipelines Jenkins?

J’ai un fichier Jenkins avec plusieurs étapes et l’une d’entre elles est en fait un autre travail (le déploiement) qui peut échouer dans certains cas.

Je sais que je peux faire des invites en utilisant Jenkinsfile mais je ne sais pas vraiment comment implémenter un mécanisme de nouvelle tentative pour ce travail.

Je veux pouvoir cliquer sur l’étape échouée et choisir de la réessayer. jenkins-pipelines-with-stages

Vous devriez être capable de combiner réessayer + entrer pour le faire

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

Vous pouvez également utiliser timeout pour l’entrée si vous voulez qu’elle se termine si personne ne valide. Il y a aussi waitUntil qui pourrait être utile mais je ne l’ai pas encore utilisé

Edit: WaitUntil semble définitivement le meilleur, vous devriez jouer un peu avec ça mais quelque chose comme ça est plus propre:

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

Au fait, il y a doc toutes les étapes ici https://jenkins.io/doc/pipeline/steps

Cet aperçu (pas le mien) était l’une des meilleures options que j’ai trouvées en essayant d’implémenter cette fonctionnalité aussi. https://gist.github.com/beercan1989/b66b7643b48434f5bdf7e1c87094acb9

Changé en une méthode dans une bibliothèque partagée qui a simplement réessayé ou abandonné pour mes besoins. Vous avez également ajouté un nombre maximal de tentatives et défini la variable timeout afin que nous puissions la modifier en fonction du travail ou de la phase qui en a besoin.

 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.toSsortingng()}" 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; } } } } } 

Exemple d'utilisation avec un maximum de 2 tentatives qui attend 60 secondes pour la saisie.

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

Rappelez-vous juste de mettre des nœuds à l'intérieur de la fermeture pour que l'attente d'une entrée ne bloque pas un exécuteur.

Si vous avez l'entreprise jenkins payée, Cloudbees a un plug-in Checkpoint qui peut mieux gérer cela, mais il n'est pas prévu de le publier pour open source Jenkins ( JENKINS-33846 ).

Celui-ci avec une belle attente incrémentale

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