Der sauberste Weg, einen Job in der Jenkins-Pipeline vorzeitig als Erfolg zu beenden?


55

Ich habe einen Job, der Dateien erstellt, es sei denn, einer der eingegebenen Werte stimmt mit einem älteren Wert überein. Was ist der sauberste Weg in Jenkins, um den Job abzubrechen oder zu beenden, ohne dass dies der Fall ist FAILED? Das Beenden ist das richtige Verhalten, daher möchte ich, dass der Build markiert wird SUCCESS.

Es wird in einer if-Anweisung wie folgt enden;

stage ('Check value') {

     if( $VALUE1 == $VALUE2 ) {
       //if they do match exit as a success, else continue with the rest of the job 
    }

}

Ich möchte keinen Fehlercode ausgeben, es sei denn, dies kann irgendwie dazu führen, dass ein erfolgreicher Build markiert wird.


1
Nur exit 0...
Tensibai

Ich dachte, dass der Job ein Misserfolg war? Wenn ich mich irre und Sie Unterlagen vorzeigen können, würde ich das gerne als Antwort akzeptieren
Alex,

Nun, nur Bash-Skripte, Exit 0 bedeutet Erfolg, Exit ungleich Null bedeutet Misserfolg ...
Tensibai

Dies ist kein Bash-Skript, sondern der Pipeline-Job selbst, also Groovy. Verändert das die Dinge?
Alex

In Groovy würde ich einfach ein probieren return 0, alles in allem sollte das Ende des Groovy-Codes, der keine Ausnahme auslöst, meiner Meinung nach stimmen. Ich lasse jemanden mit mehr Hintergrundwissen über Jenkins 2 bestätigen oder
gebrechlich werden

Antworten:


46

Herausgefunden. Außerhalb einer Phase (andernfalls wird die jeweilige Phase nur als Erfolg gewertet), gehen Sie wie folgt vor:

if( $VALUE1 == $VALUE2 ) {
   currentBuild.result = 'SUCCESS'
   return
}

return stoppt die Bühne oder den Knoten, auf dem Sie gerade laufen , weshalb das Ausführen außerhalb einer Bühne wichtig ist, während das Festlegen currentBuild.resultverhindert, dass sie ausfällt.


Wenn Sie nur zurückkehren, wird der Build abgeblendet und es wird kein Ergebnis angezeigt. Dies ist also nicht ganz dasselbe wie bei einem fehlgeschlagenen Build.
zog

1
Wie kehren Sie zurück und überspringen alle verbleibenden Phasen?
Jess Bowers

1
@ JessBowers Es geht darum, wo Sie das Snippet setzen. Wenn Sie dies eher auf Knotenebene als auf Bühnenebene tun, wird der gesamte Job abgeschlossen.
Alex

4
Bitte beachten Sie, dass es nur für gescriptete Pipelines funktioniert, nicht für deklarative
kagarlickij

@kagarlickij - Es gab keine korrekten deklarativen Pipelines, als diese Antwort geschrieben wurde!
Alex

10

Sie können auch Fehler verwenden, um die aktuelle Phase zu verlassen. Sie müssen dann nicht die aktuelle Phasenhierarchie und ähnliches berücksichtigen:

def autoCancelled = false

try {
  stage('checkout') {
    ...
    if (your condition) {
      autoCancelled = true
      error('Aborting the build.')
    }
  }
} catch (e) {
  if (autoCancelled) {
    currentBuild.result = 'SUCCESS'
    // return here instead of throwing error to keep the build "green"
    return
  }
  // normal error handling
  throw e
}

Dies würde aber zu einer roten Stufe führen, wenn der Fehler innerhalb einer Stufe auftritt.

Bildbeschreibung hier eingeben

Es hängt von Ihren Anforderungen ab, welchen Weg Sie verwenden möchten.


Wenn du es auf diese Weise machst, mache eine neue Unterklasse von RuntimeExceptionwerfen, anstatt alle Ausnahmen abfangen zu müssen und überprüfe eine Flagge
Michael Mrozek

1

Ehrlich gesagt sollten Sie den Befehl exit nicht speziell verwenden müssen, aber es gibt ein Conditional BuildStep-Plugin, das möglicherweise dasselbe Endergebnis erzielt (Code, der nicht ausgeführt wird).

Darauf bin ich noch nicht gekommen, also habe ich das Plugin nicht benutzt.

Es gibt auch Bedingungen, wie sie in diesem früheren Stapelüberlauf-Post auf Jenkins: Jenkins Pipeline Conditional Step / Stage zu finden sind


1
Obwohl Ihre Antwort gültig zu sein scheint (ich habe sie nicht live überprüft, seit ich eine andere Problemumgehung gefunden habe), halte ich "Ehrlich gesagt, Sie sollten nicht beenden" nicht für eine gute Möglichkeit, sie zu starten. Offensichtlich bedeutet die Existenz dieser Methoden, dass es manchmal notwendig ist, zu beenden.
Alex

Was würdest du vorschlagen? Zu einer Endaussage wechseln? Hinzufügen des Qualifiers "allgemein"? Sie haben "Feedback" gegeben, aber es fällt mir nicht leicht, die Absichten oder Maßnahmen zu erläutern. Seien Sie bitte weniger knapp.
MrMesees

Warte ein bisschen. Ist es deine frage Wenn dies der Fall ist, würden Sie nicht hören wollen, dass Sie nicht beenden sollten, aber keine der von mir vorgeschlagenen Methoden bietet Exits, umgeht sie das Ausführen von Code ... Unterstützt direkt meine Position.
MrMesees

1
Ahh ich verstehe, ich denke ich habe deine Aussage falsch interpretiert als "etwas zu tun, um den Job zu beenden, ist schlecht" anstatt "du solltest nicht den wörtlichen exitBefehl verwenden" - wenn ich mich entschuldige, ist das mein Missverständnis.
Alex

3
Ich habe versucht, es klarer zu machen, keine Notwendigkeit, sich überhaupt zu entschuldigen, Sprache ist ein launisches Biest, besonders im Internet :)
MrMesees

0

Die Executor.interrupt(Result)Methode ist die sauberste und direkteste Methode, die ich finden konnte, um einen Build vorzeitig zu stoppen und als Erfolg zu markieren.

script {
    currentBuild.getRawBuild().getExecutor().interrupt(Result.SUCCESS)
}

Vorteile :

  • Funktioniert in einer deklarativen Pipeline genauso gut wie in einer Skript-Pipeline.
  • Kein Versuch / Fang oder Ausnahmen zu behandeln.
  • Markiert die aufrufende Phase und alle nachfolgenden Phasen in der Benutzeroberfläche als grün / passierend.

Nachteile :

  • Erfordert eine Reihe von in Bearbeitung befindlichen Skriptgenehmigungen, darunter eine, die als unsicher eingestuft wird . Mit Vorsicht genehmigen und verwenden.

Für mich funktioniert es nicht - aufeinanderfolgende Phasen werden ausgeführt.
Łukasz K
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.