webentwicklung-frage-antwort-db.com.de

Zeigen Sie eine Jenkins-Pipeline-Phase als fehlgeschlagen an, ohne dass der gesamte Job fehlschlägt

Hier ist der Code, mit dem ich spiele

node {
    stage 'build'
    echo 'build'

    stage 'tests'
    echo 'tests'

    stage 'end-to-end-tests'
    def e2e = build job:'end-to-end-tests', propagate: false
    result = e2e.result
    if (result.equals("SUCCESS")) {
        stage 'deploy'
        build 'deploy'
    } else {
        ?????? I want to just fail this stage
    }
}

Gibt es eine Möglichkeit für mich, die Phase „End-to-End-Tests“ als fehlgeschlagen zu markieren, ohne dass der gesamte Auftrag fehlschlägt? Propagate false markiert nur immer die Bühne als true, was nicht das ist, was ich will, aber Propagate true markiert den Job als failed, was ich auch nicht will.

43
techgnosis

Stage nimmt jetzt einen Block ein, also wickeln Sie die Bühne in Try-Catch. Try-Catch in der Bühne macht es erfolgreich.

Die zuvor erwähnte neue Funktion wird leistungsfähiger sein. Inzwischen:

try {
   stage('end-to-end-tests') {
     node {      
       def e2e = build job:'end-to-end-tests', propagate: false
       result = e2e.result
       if (result.equals("SUCCESS")) {
       } else {
          sh "exit 1" // this fails the stage
       }
     }
   }
} catch (e) {
   result = "FAIL" // make sure other exceptions are recorded as failure too
}

stage('deploy') {
   if (result.equals("SUCCESS")) {
      build 'deploy'
   } else {
      echo "Cannot deploy without successful build" // it is important to have a deploy stage even here for the current visualization
   }
}
21
vaza

Klingt nach JENKINS-26522 . Derzeit können Sie nur ein Gesamtergebnis festlegen:

if (result.equals("SUCCESS")) {
    stage 'deploy'
    build 'deploy'
} else {
    currentBuild.result = e2e.result
    // but continue
}
13
Jesse Glick

Ich habe kürzlich versucht, die Antwort von vaza zu verwenden Eine Jenkins-Pipeline-Phase als fehlgeschlagen anzeigen, ohne dass der gesamte Job fehlgeschlagen ist als Vorlage zum Schreiben einer Funktion, die einen Job in einer eigenen Phase mit dem Namen des Jobnamens auslöst. Überraschenderweise hat es funktioniert, aber vielleicht schauen sich einige gute Experten das an :)

So sieht es aus, wenn einer der Jobs abgebrochen wird: enter image description here

def BuildJob(projectName) {
    try {
       stage(projectName) {
         node {      
           def e2e = build job:projectName, propagate: false
           result = e2e.result
           if (result.equals("SUCCESS")) {
           } else {
              error 'FAIL' //sh "exit 1" // this fails the stage
           }
         }
       }
    } catch (e) {
        currentBuild.result = 'UNSTABLE'
        result = "FAIL" // make sure other exceptions are recorded as failure too
    }
}

node {
    BuildJob('job1')
    BuildJob('job2')
}
11
grenix

Dies ist jetzt auch mit deklarativen Pipelines möglich:

pipeline {
    agent any
    stages {
        stage('1') {
            steps {
                sh 'exit 0'
            }
        }
        stage('2') {
            steps {
                catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
                    sh "exit 1"
                }
            }
        }
        stage('3') {
            steps {
                sh 'exit 0'
            }
        }
    }
}

Im obigen Beispiel werden alle Phasen ausgeführt, die Pipeline ist erfolgreich, Phase 2 wird jedoch als fehlgeschlagen angezeigt:

Pipeline Example

Wie Sie vielleicht erraten haben, können Sie buildResult und stageResult frei wählen, falls Sie möchten, dass es instabil ist oder etwas anderes. Sie können den Build sogar fehlschlagen und die Ausführung der Pipeline fortsetzen.

Stellen Sie einfach sicher, dass Ihre Jenkins auf dem neuesten Stand sind, da dies eine ziemlich neue Funktion ist.

3
Erik B

Sie können eine explizite Fehleraufgabe hinzufügen, z. B. 'sh "nicht vorhandener Befehl"' in der Phase.

if (result.equals("SUCCESS")) {
   stage 'deploy'
   build 'deploy'
} else {
   try {
       sh "not exist command"
   }catch(e) {
   }
}
2
anyone.can.test

Lösungsschritte

  • Sie müssen einen Fehler in einer Phase ausgeben, um ihn als Fehler zu markieren
  • Behandeln Sie die Ausnahme außerhalb des Bereichs von stage und wählen Sie den Erstellungsstatus aus
  • Dies führt dazu, dass einige Benutzer hier den gewünschten Effekt erzielen, darunter ich selbst, @ user3768904, @Sviatlana

Erfolg mit fehlgeschlagenem Schritt Beispiel

node("node-name") {
  try {
    stage("Process") {
      error("This will fail")
    }
  } catch(Exception error) {
    currentBuild.result = 'SUCCESS'
    return
  }
  stage("Skipped") {
     // This stage will never run
  }
}

enter image description here

Abgebrochen mit Fehler Schritt Beispiel

node("node-name") {
  try {
    stage("Process") {
      error("This will fail")
    }
  } catch(Exception error) {
    currentBuild.result = 'ABORTED'
    return
  }
  stage("Skipped") {
     // This stage will never run
  }
}

enter image description here

1