Ceci fait suite à ma question précédente:
Définir un statut d'étape dans Jenkins Pipelines
Il s'avère que je peux garder un pipeline comme SUCCESS mais que je peux marquer une étape individuelle comme INSTABLE si je le souhaite via catchError
comme ceci:
stage("1") { catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') { // do stuff } // perhaps more catchError() blocks if(currentStage.getCurrentResult() == "UNSTABLE") { // do something special if we're unstable } }
Si je veux obtenir l'état actuel du pipeline lui-même, je peux utiliser currentBuild.getCurrentResult()
mais je ne vois pas d'analogue currentStage
à cela.
Je suis intéressé à essayer un modèle qui pourrait ressembler à ceci dans mes étapes:
node() { stage("Stage 1") { catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') { sh 'exit 1' } } }
mais cela échouerait car il n'y a pas de currentStage
disponible.
Donc en gros, catchError()
est sympa mais j'aimerais savoir comment je peux attraper le changement de statut de ma scène si elle est modifiée ... Est-ce que quelqu'un sait comment vous accédez au statut de l'étape actuelle dans laquelle vous vous trouvez à partir d'un pipeline?
4 Réponses :
Bien qu'il n'existe pas de méthode directe pour accéder au résultat d'une étape dans un pipeline à partir de maintenant, vous pouvez contourner ce problème. Cela considère que vous n'êtes intéressé que par les résultats de l'étape SUCCESS
ou UNSTABLE
selon la question et non par l' FAILURE
.
La solution de contournement consiste à initialiser une carte vide en haut de votre pipeline pour stocker le résultat de chaque étape. Maintenant, au lieu de la méthode catchError()
, utilisez la méthode unstable()
en combinaison avec un bloc try-catch. En effet, ce dernier vous permet non seulement de définir le résultat comme instable, mais également d'effectuer d'autres opérations telles que l'ajout du résultat à la carte dans le bloc except. Ensuite, vous pouvez lire ce résultat stocké à partir de la carte dans votre instruction if
.
Exemple
stageResults = [:] ... stage("1") { try { // do stuff // Add to map as SUCCESS on successful execution stageResults."{STAGE_NAME}" = "SUCCESS" } catch (Exception e) { // Set the result and add to map as UNSTABLE on failure unstable("[ERROR]: ${STAGE_NAME} failed!") currentBuild.result = "SUCCESS" stageResult."{STAGE_NAME}" = "UNSTABLE" } if(stageResults.find{ it.key == "{STAGE_NAME}" }?.value == "UNSTABLE") { // do something special if we're unstable } }
Ouais, je fais déjà quelque chose comme ça mais je règle généralement une variable d'état booléenne comme Boolean stageFailed = false
au début du bloc stage
, puis essaye / attrape des trucs et vérifie-le plus tard. J'avais catchError
que catchError
simplifierait un peu cela, mais il semble que cela fonctionne un peu comme un bloc try spécialisé avec un catch caché qui définit un état qui n'est pas accessible au pipeline, ce qui limite son utilité pour nous. Cela change si je peux accéder au statut de l'étape actuelle d'une manière ou d'une autre ... mais il semble que ce n'est pas possible pour le moment. :(
Comme alternative à ajouter à la réponse de Dibakar Aditya, il est possible de tout envelopper dans une fonction qui ressemble à des étapes régulières. C'est à dire:
stage("1") { def localSuccess = catchLocalError { // do stuff } if(!localSuccess) { // do something special if we're unstable } } boolean catchLocalError(Closure c) { try { c() return true } catch (Exception e) { return false } }
Ce que j'aime dans l'utilisation éventuelle de catchError
c'est qu'il peut définir le statut d'une étape individuelle sur UNSTABLE, etc. et cela apparaît dans la vue de la scène dans Jenkins ... y a-t-il un moyen de définir le statut d'une étape individuelle sans en utilisant catchError?
Il devrait être possible de corriger si vous êtes prêt à déplacer l'étape de scène à l'intérieur de catchLocalError / catchError. Si vous êtes intéressé, je peux mettre à jour ma réponse.
Je l'ai fait comme ça (pour garder le catchError):
def boolean test_results = false pipeline { ... stage( 'x' ) { steps{ catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { <Do some dangerous stuff here> // // If we reached here the above step hasn't failed // script { test_results = true } } } } stage( 'y' ) { steps{ script{ if( test_results == true ) { } else { } } } } }
Quant à moi, la façon la plus élégante de le faire, c'est une section de publication . Dans votre exemple, vous marquez la scène comme UNSTABLE
afin de pouvoir l'attraper en utilisant post->unstable
.
stage("1") { steps { catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') { error 'Something goes wrong' } } post { always { echo 'Executed on every build'} unstable { echo 'Executed only if build is unstable (marked by catchError)'} } }