Utiliser Jenkins 'Mailer' à l'intérieur du pipeline de flux de travail
j'aimerais tirer parti de l'existant Mailer plugin Jenkins dans un Jenkinsfile
qui définit un pipeline de travail. Étant donné le script d'échec simple suivant, je m'attendrais à un email sur chaque construction.
#!groovy
stage 'Test'
node {
try {
sh 'exit 1'
} finally {
step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: 'me@me.com', sendToIndividuals: true])
}
}
La sortie de la compilation est:
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
Comme vous pouvez le voir, il n'enregistrer qu'il effectue le pipeline step
immédiatement après l'échec, mais pas de courriels se produit.
Emails dans d'autres travaux de style libre qui l'effet de levier de l' mailer
bon travail, c'est juste invoquer via des travaux de pipeline.
ceci fonctionne avec Jenkins 2.2 et mailer 1.17.
y a-t-il un autre mécanisme par lequel je devrais invoquer les e-mails de compilation échoués? je n'ai pas besoin de tous les frais généraux de l' mail
étape, il faut juste les notifications sur les échecs et les recouvrements.
3 réponses
Dans le Pipeline a échoué sh
ne pas régler immédiatement la currentBuild.result
FAILURE
alors que sa valeur initiale est null
. Par conséquent, les étapes de construction qui dépendent du statut de construction comme Mailer peuvent fonctionner de façon apparemment incorrecte.
Vous pouvez le vérifier par l'ajout d'un débogage d'impression:
stage 'Test'
node {
try {
sh 'exit 1'
} finally {
println currentBuild.result // this prints null
step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: 'me@me.com', sendToIndividuals: true])
}
}
l'ensemble du pipeline est emballé avec un manipulateur d'exception fourni par Jenkins c'est pourquoi Jenkins marque L'échec de la construction à la fin.
Donc, si vous voulez utiliser Mailer vous avez besoin pour maintenir l'état de création correctement. Par exemple:
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: 'me@me.com', sendToIndividuals: true])
}
}
Si vous n'avez pas besoin de renvoyer l'exception que vous pouvez utiliser catchError
. Il s'agit d'un Pipeline intégré qui saisit toute exception dans sa portée, l'imprime dans la console et définit l'état de construction. Exemple:
stage 'Test'
node {
catchError {
sh 'exit 1'
}
step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: 'me@me.com', sendToIndividuals: true])
}
en plus de l'excellente réponse d'izzekil, vous pouvez choisir des destinataires de courriel basés sur les auteurs de commit. Vous pouvez utiliser e-mail-ext pour ce faire (basé sur leurs exemples de pipeline):
step([$class: 'Mailer',
notifyEveryUnstableBuild: true,
recipients: emailextrecipients([[$class: 'CulpritsRecipientProvider'],
[$class: 'RequesterRecipientProvider']])])
Si vous utilisez un récent e-mail-ext (2.50+), vous pouvez l'utiliser dans votre pipeline:
emailext(body: '${DEFAULT_CONTENT}', mimeType: 'text/html',
replyTo: '$DEFAULT_REPLYTO', subject: '${DEFAULT_SUBJECT}',
to: emailextrecipients([[$class: 'CulpritsRecipientProvider'],
[$class: 'RequesterRecipientProvider']]))
si vous n'utilisez pas un Jenkinsfile déclaratif, vous devrez mettre checkout scm
pour que Jenkins puisse trouver les committers. Voir JENKINS-46431.
si vous êtes toujours sur une ancienne version de email-ext, vous frapperez JENKINS-25267. Vous pourriez rouler votre propre e-mail en HTML:
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'
}
}
je pense qu'une meilleure façon d'envoyer des notifications de courrier dans jenkins pipelines est d'utiliser la section de courrier d'un pipeline comme décrit dans le jenkins docs au lieu d'utiliser try catch:
pipeline {
agent any
stages {
stage('whatever') {
steps {
...
}
}
}
post {
always {
step([$class: 'Mailer',
notifyEveryUnstableBuild: true,
recipients: "example@example.com",
sendToIndividuals: true])
}
}
}
}
}