plugin - jenkins pipeline php example
Utilice Jenkins ''Mailer'' dentro del flujo de trabajo de la tuberÃa (3)
Me gustaría aprovechar el plugin de Mailer existente de Jenkins dentro de un Jenkinsfile
que define un trabajo de compilación de canalización. Dado el siguiente script de falla simple, esperaría un correo electrónico en cada compilación.
#!groovy
stage ''Test''
node {
try {
sh ''exit 1''
} finally {
step([$class: ''Mailer'', notifyEveryUnstableBuild: true, recipients: ''[email protected]'', sendToIndividuals: true])
}
}
El resultado de la compilación es:
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
Como puede ver, registra que realiza el step
canalización inmediatamente después de la falla, pero no se generan correos electrónicos.
Los correos electrónicos en otros trabajos de estilo libre que aprovechan el mailer
electrónico funcionan bien, solo se invoca a través de trabajos de canalización.
Esto se ejecuta con Jenkins 2.2 y mailer 1.17.
¿Hay un mecanismo diferente por el que debería invocar correos electrónicos fallidos? No necesito todos los gastos generales del paso de mail
, solo necesito notificaciones sobre fallas y recuperaciones.
Además de la excelente respuesta de izzekil, es posible que desee elegir destinatarios de correo electrónico en función de los autores del encargo. Puede usar email-ext para hacer esto (en base a sus ejemplos de canalización ):
step([$class: ''Mailer'',
notifyEveryUnstableBuild: true,
recipients: emailextrecipients([[$class: ''CulpritsRecipientProvider''],
[$class: ''RequesterRecipientProvider'']])])
Si está utilizando un correo electrónico-ext reciente (2.50+), puede usarlo en su canalización:
emailext(body: ''${DEFAULT_CONTENT}'', mimeType: ''text/html'',
replyTo: ''$DEFAULT_REPLYTO'', subject: ''${DEFAULT_SUBJECT}'',
to: emailextrecipients([[$class: ''CulpritsRecipientProvider''],
[$class: ''RequesterRecipientProvider'']]))
Si no está utilizando un Jenkinsfile declarativo, deberá poner checkout scm
para que Jenkins pueda encontrar a los committers. Ver JENKINS-46431 .
Si todavía tiene una versión anterior de email-ext, llegará a JENKINS-25267 . Podrías rodar tu propio correo electrónico 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://.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''
}
}
Creo que una mejor forma de enviar notificaciones por correo electrónico en las tuberías de jenkins es utilizar la sección de publicación de una canalización como se describe en los documentos de jenkins en lugar de utilizar try catch:
pipeline {
agent any
stages {
stage(''whatever'') {
steps {
...
}
}
}
post {
always {
step([$class: ''Mailer'',
notifyEveryUnstableBuild: true,
recipients: "[email protected]",
sendToIndividuals: true])
}
}
}
}
}
En Pipeline failed sh
no establece inmediatamente el currentBuild.result
en FAILURE
mientras que su valor inicial es null
. Por lo tanto, los pasos de compilación que dependen del estado de compilación como Mailer podrían funcionar aparentemente incorrectos.
Puede verificarlo agregando una impresión de depuración:
stage ''Test''
node {
try {
sh ''exit 1''
} finally {
println currentBuild.result // this prints null
step([$class: ''Mailer'', notifyEveryUnstableBuild: true, recipients: ''[email protected]'', sendToIndividuals: true])
}
}
Todo este pipeline está envuelto con el manejador de excepción provisto por Jenkins, por eso Jenkins señala que la construcción falló al final.
Entonces, si desea utilizar Mailer, necesita mantener el estado de compilación correctamente. Por ejemplo:
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])
}
}
Si no necesita volver a lanzar la excepción, puede usar catchError
. Es un canal integrado que detecta cualquier excepción dentro de su alcance, lo imprime en la consola y establece el estado de compilación. Ejemplo:
stage ''Test''
node {
catchError {
sh ''exit 1''
}
step([$class: ''Mailer'', notifyEveryUnstableBuild: true, recipients: ''[email protected]'', sendToIndividuals: true])
}