webentwicklung-frage-antwort-db.com.de

Verwenden Sie Jenkins 'Mailer' innerhalb des Pipeline-Workflows

Ich möchte das vorhandene Mailer -Plugin von Jenkins in einem Jenkinsfile nutzen, das einen Pipeline-Build-Job definiert. Angesichts des folgenden einfachen Fehlerskripts würde ich bei jedem Build eine E-Mail erwarten.

#!groovy

stage 'Test'
node {
    try {
        sh 'exit 1'
    } finally {
        step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: '[email protected]', sendToIndividuals: true])
    }
}

Die Ausgabe des Builds lautet:

Started by user xxxxx
[Pipeline] stage (Test)
Entering stage Test
Proceeding
[Pipeline] node
Running on master in /var/lib/jenkins/jobs/rpk-test/workspace
[Pipeline] {
[Pipeline] sh
[workspace] Running Shell script
+ exit 1
[Pipeline] step
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 1
Finished: FAILURE

Wie Sie sehen, wird zwar aufgezeichnet, dass die Pipeline step unmittelbar nach dem Fehler ausgeführt wird, es werden jedoch keine E-Mails generiert.

E-Mails in anderen Free-Style-Jobs, die mailer nutzen, funktionieren einwandfrei. Sie werden nur über Pipeline-Jobs aufgerufen.

Dies läuft mit Jenkins 2.2 und Mailer 1.17.

Gibt es einen anderen Mechanismus, mit dem ich fehlgeschlagene Build-E-Mails aufrufen sollte? Ich benötige nicht den gesamten Overhead des Schritts mail Ich benötige nur Benachrichtigungen zu Fehlern und Wiederherstellungen.

37
rkeilty

In der Pipeline fehlgeschlagen sh setzt den currentBuild.result Nicht sofort auf FAILURE, während sein Anfangswert null ist. Daher könnten Build-Schritte, die vom Build-Status abhängen, wie Mailer, scheinbar falsch funktionieren.

Sie können dies überprüfen, indem Sie einen Debug-Ausdruck hinzufügen:

stage 'Test'
node {
    try {
        sh 'exit 1'
    } finally {
        println currentBuild.result  // this prints null
        step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: '[email protected]', sendToIndividuals: true])
    }
}

Diese gesamte Pipeline ist mit einem von Jenkins bereitgestellten Ausnahmehandler umschlossen, weshalb Jenkins den Build am Ende als fehlgeschlagen markiert.

Wenn Sie Mailer verwenden möchten, müssen Sie den Build-Status ordnungsgemäß beibehalten. Zum Beispiel:

stage 'Test'
node {
    try {
        sh 'exit 1'
        currentBuild.result = 'SUCCESS'
    } catch (any) {
        currentBuild.result = 'FAILURE'
        throw any //rethrow exception to prevent the build from proceeding
    } finally {
        step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: '[email protected]', sendToIndividuals: true])
    }
}

Wenn Sie die Ausnahme nicht erneut auslösen müssen, können Sie catchError verwenden. Es handelt sich um eine integrierte Pipeline, die alle Ausnahmen innerhalb ihres Bereichs abfängt, in die Konsole druckt und den Build-Status festlegt. Beispiel:

stage 'Test'
node {
    catchError {
        sh 'exit 1'
    } 
    step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: '[email protected]', sendToIndividuals: true])
}
61
izzekil

Zusätzlich zur hervorragenden Antwort von izzekil können Sie E-Mail-Empfänger basierend auf den Autoren des Commits auswählen. Sie können email-ext verwenden, um dies zu tun (basierend auf ihren Pipeline-Beispielen ):

step([$class: 'Mailer',
      notifyEveryUnstableBuild: true,
      recipients: emailextrecipients([[$class: 'CulpritsRecipientProvider'],
                                      [$class: 'RequesterRecipientProvider']])])

Wenn Sie eine aktuelle E-Mail-Erweiterung (2.50+) verwenden, können Sie diese in Ihrer Pipeline verwenden:

emailext(body: '${DEFAULT_CONTENT}', mimeType: 'text/html',
         replyTo: '$DEFAULT_REPLYTO', subject: '${DEFAULT_SUBJECT}',
         to: emailextrecipients([[$class: 'CulpritsRecipientProvider'],
                                 [$class: 'RequesterRecipientProvider']]))

Wenn Sie keine deklarative Jenkins-Datei verwenden, müssen Sie checkout scm damit Jenkins die Committer finden kann. Siehe JENKINS-46431 .

Wenn Sie noch eine ältere Version von email-ext verwenden, drücken Sie JENKINS-25267 . Sie könnten Ihre eigene HTML-E-Mail rollen:

def emailNotification() {
    def to = emailextrecipients([[$class: 'CulpritsRecipientProvider'],
                                 [$class: 'DevelopersRecipientProvider'],
                                 [$class: 'RequesterRecipientProvider']])
    String currentResult = currentBuild.result
    String previousResult = currentBuild.getPreviousBuild().result

    def causes = currentBuild.rawBuild.getCauses()
    // E.g. 'started by user', 'triggered by scm change'
    def cause = null
    if (!causes.isEmpty()) {
        cause = causes[0].getShortDescription()
    }

    // Ensure we don't keep a list of causes, or we get
    // "Java.io.NotSerializableException: hudson.model.Cause$UserIdCause"
    // see http://stackoverflow.com/a/37897833/509706
    causes = null

    String subject = "$env.JOB_NAME $env.BUILD_NUMBER: $currentResult"

    String body = """
<p>Build $env.BUILD_NUMBER ran on $env.NODE_NAME and terminated with $currentResult.
</p>

<p>Build trigger: $cause</p>

<p>See: <a href="$env.BUILD_URL">$env.BUILD_URL</a></p>

"""

    String log = currentBuild.rawBuild.getLog(40).join('\n')
    if (currentBuild != 'SUCCESS') {
        body = body + """
<h2>Last lines of output</h2>
<pre>$log</pre>
"""
    }

    if (to != null && !to.isEmpty()) {
        // Email on any failures, and on first success.
        if (currentResult != 'SUCCESS' || currentResult != previousResult) {
            mail to: to, subject: subject, body: body, mimeType: "text/html"
        }
        echo 'Sent email notification'
    }
}
28
Wilfred Hughes

Ich denke, eine bessere Möglichkeit, E-Mail-Benachrichtigungen in Jenkins-Pipelines zu senden, besteht darin, den Post-Abschnitt einer Pipeline zu verwenden, wie in jenkins docs beschrieben, anstatt try catch zu verwenden:

pipeline {
  agent any
    stages {
      stage('whatever') {
        steps {
          ...
        }
      }
    }
    post {
        always {
          step([$class: 'Mailer',
            notifyEveryUnstableBuild: true,
            recipients: "[email protected]",
            sendToIndividuals: true])
        }
      }
    }
  }
}
14
Andi