I have a Jenkins pipeline for automation tests in which it downloads the source from Git and builds it before starting to test.
I would like to have a slack notification when a Jenkins pipeline build fails.
Not if there are test errors - only if the code does not build.
The post conditions I found are as follows:
always - Always, regardless of the outcome of stage/pipeline.
changed - If completion status differs from the previous run.
fixed - When status went from failed or unstable to successful.
regression - When status was successful in the previous run but is failure, unstable or aborted now.
aborted - When the status is aborted.
failure - When the status is failure.
success - When the status is success.
unstable - When the status is unstable.
unsuccessful - When the status is not success, but any one of the others.
cleanup - Always, regardless of the outcome, but as the last one after all others have been run.
I don't see here a condition of build failure or something related.
Is there a way to achieve that? Does failure condition contains also build failures?
So far I used:
post{
failure{
slackSend( channel: "#my_alerts", token: "slack_webhook token", color: "good", message: "${custom_msg()}")
}
}
but is it relevant to use failure condition?
CodePudding user response:
If the whole build fails, then we will be notified by the failure
step in the post
section.
EDIT:
def onBuildAborted() {
env.BUILD_STATUS = "build was aborted by user :stop_sign:";
env.BUILD_TYPE = "INFO";
}
def onBuildSucceeded() {
env.BUILD_STATUS = "build succeeded :check:";
env.BUILD_TYPE = "SUCCESS";
}
def onBuildFailed() {
env.BUILD_STATUS = "build failed :cross_mark:";
env.BUILD_TYPE = "ERROR";
}
def onBuildSucceededButUnstable() {
env.BUILD_STATUS = "build succeeded, but tests did not pass :prohibited:";
env.BUILD_TYPE = "WARNING";
}
def notifyBuildEnd() {
String buildStatus = env.BUILD_STATUS != null ? env.BUILD_STATUS : ""
String resultType = env.BUILD_TYPE != null ? env.BUILD_TYPE : "";
String buildDuration = currentBuild.durationString;
buildDuration = buildDuration.replace(" and counting", "");
// remove 'and counting' at end of string
String messageHeader = "${buildStatus} in ${buildDuration}";
String messageBody = env.BUILD_TESTRESULTS != null ? env.BUILD_TESTRESULTS : "";
String stacktrace = env.BUILD_STACKTRACE != null ? env.BUILD_STACKTRACE : "";
sendNotification(resultType, messageHeader, messageBody, stacktrace);
}
def sendNotification(String type = 'INFO', String header = 'update', String body = '', String stacktrace = '') {
echo "preparing to send messaging platform notifications: type=${type}, header=${header}, body=${body}, stacktrace=${stacktrace}"
// colors taken from bootstrap (see https://www.bitdegree.org/learn/bootstrap-colors)
String color_neutral = '#17a2b8'; // teal
String color_success = '#28a745'; // green
String color_error = '#dc3545'; // red
String color_warning = '#ffc107'; // yellow
String color_default = ' #007bff'; // blue
String messagecolor = color_default
if ('SUCCESS' == type) {
messagecolor = color_success;
} else if ('INFO' == type) {
messagecolor = color_neutral;
} else if ('WARNING' == type) {
messagecolor = color_warning;
} else if ('ERROR' == type) {
messagecolor = color_error;
}
def jobName = env.JOB_NAME;
jobName = jobName.replace("/", "/");
jobName = jobName.replace("#", "#");
def jobIdentifier = "<${env.BUILD_URL}|${jobName} - build ${env.BUILD_NUMBER}>"
header = "*${header}*"
if ("" != stacktrace) {
stacktrace = "```${stacktrace}```"
}
def attachmentsArr = [
[
text : header,
color: messagecolor
],
[
text : jobIdentifier,
color: messagecolor
],
[
text : body,
color: color_neutral
],
[
text : stacktrace,
color: color_neutral
]
];
def markdownJobIdentifier = "[${jobName} - build #${env.BUILD_NUMBER}](${env.BUILD_URL})"
zulipSend message: "${header}\n${markdownJobIdentifier}\n${body}", stream: 'jenkins', topic: 'some_zulip_channel'
echo "messaging platform notifications sent"
}
This will give you messages like this:
The only thing you need to change is zulipSend to slackSend. If you need help with the slackSend command try this Stackoverflow answer.
CodePudding user response:
Any failure in the Pipeline will trigger the failure{}
block. Even if your test execution throws an error the build will be marked as Failed. Basically at the end of the Pipeline Stage executions, based on currentBuild.result
the relevant book will be executed.
Having said that, so the behavior really depends on how you have implemented your Pipeline. For example, if you don't want test execution to mark your build as a failure you will have to handle it explicitly. Something like below. So if the tests fail the build will be marked as Unstable
and the unstable block will be executed.
stage('Test') {
steps {
script {
try {
echo "Executing your tests here"
} catch(e) {
currentBuild.result = "UNSTABLE"
}
}
}
}