2016-04-05 11 views
36

Possiedo un Jenkinsfile con più livelli e uno di questi è in realtà un altro lavoro (quello di distribuzione) che può non riuscire in alcuni casi.Come implementare un'opzione di retry per le fasi non riuscite nelle pipeline Jenkins?

So che posso eseguire prompt utilizzando Jenkinsfile ma non so davvero come implementare un meccanismo di tentativi per questo lavoro.

Desidero poter fare clic sulla fase fallita e scegliere di riprovare. jenkins-pipelines-with-stages

+1

Questa richiesta di funzionalità generale è in [JENKINS-33846] (https://issues.jenkins-ci.org/browse/JENKINS-33846). Esso (in modo del tutto ingiusto) viene selezionato solo per le condotte dichiarative in [JENKINS-45455] (https://issues.jenkins-ci.org/browse/JENKINS-45455). – mkobit

risposta

22

Si dovrebbe essere in grado di combinare tentativi + ingresso per farlo Qualcosa del genere

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

si potrebbe anche usare timeout per l'ingresso se si vuole che finisca se nessuno convalida. C'è anche WaitUntil che potrebbe essere utile, ma non l'ho ancora utilizzato

Edit: WaitUntil sembra decisamente il migliore, si dovrebbe giocare con un po ', ma una cosa del genere è più pulita:

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

A proposito, c'è doc tutti i passaggi qui https://jenkins.io/doc/pipeline/steps

+0

Aggiungerà un prompt di nuovo tentativo? Io dubito. – sorin

+0

Oh no hai ragione. aggiornerò la mia risposta per quello! – fchaillou

+1

È possibile abilitare il timeout solo per la parte riprova? Potrei voler avere un timeout diverso per il lavoro. Non ho ancora accettato la risposta in quanto non trovo un lavoro di blocco come una buona soluzione. Idealmente l'opzione di riprova dovrebbe essere dopo il lavoro già finito. Immagina che questo lavoro sia attivato da un hook GitHub su un PR. Preferirei vedere l'errore su GitHub anziché la mancata risposta in caso di errore. – sorin

2

Questo elenco (non il mio) era una delle migliori opzioni che ho trovato durante il tentativo di implementare anche questa funzionalità. https://gist.github.com/beercan1989/b66b7643b48434f5bdf7e1c87094acb9

Modificato in un metodo in una libreria condivisa che ha appena riprovato o interrotto le mie esigenze. Inoltre, ho aggiunto un numero massimo di tentativi e ho creato la variabile di timeout in modo che potessimo cambiarla a seconda del lavoro o della fase che ne ha bisogno.

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

Esempio di utilizzo con un massimo di 2 tentativi che attende 60 secondi per l'input.

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

Basta ricordarsi di mettere i nodi all'interno della chiusura in modo che in attesa di un input non blocca un esecutore.

Se l'azienda jenkins a pagamento Cloudbees ha un plug-in Checkpoint che può gestirlo meglio, ma non è previsto il rilascio per l'open source Jenkins (JENKINS-33846).

Problemi correlati