I have a Python script that I'm running in my pipeline that is forced to fail. I'm trying to send the failure output to Slack.
testing.py
import sys
print("Hello World")
sys.exit(1)
pipeline
def slackChannel = "default-ops"
def slackDetails = "${env.JOB_NAME} - (<${env.BUILD_URL}|Open>)"
def shResult() {
script {
sh script: 'set -e; python3 testing.py', returnStdout: true
}
}
pipeline {
agent any
stages {
stage('Execute testing.py') {
steps {
script{
echo "${shResult()}".trim()
if (shResult != 0) {
currentBuild.result = 'FAILURE'
}
}
}
}
}
post {
success {
slackSend(color: '#00FF00',
channel: "${slackChannel}",
message: "SUCCESSFUL: " slackDetails)
}
failure {
slackSend(color: '#FF0000',
channel: "${slackChannel}",
message: "FAILED: " slackDetails shResult())
}
aborted {
slackSend(color: '#808080',
channel: "${slackChannel}",
message: "ABORTED: " slackDetails)
}
}
}
This results in the following error:
Error when executing failure post condition:
hudson.AbortException: script returned exit code 1
at org.jenkinsci.plugins.workflow.steps.durable_task.DurableTaskStep$Execution.handleExit(DurableTaskStep.java:659)
at org.jenkinsci.plugins.workflow.steps.durable_task.DurableTaskStep$Execution.check(DurableTaskStep.java:605)
at org.jenkinsci.plugins.workflow.steps.durable_task.DurableTaskStep$Execution.run(DurableTaskStep.java:549)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
How do I send the output "Hello World" to Slack?
CodePudding user response:
First of all the line message: "FAILED: " slackDetails shResult())
executes the script again, which is probably not what you want.
The second thing is that returnStdout: true
does not return the status code, but the stdout output. So in this case only "Hello World". Use returnStatus: true
to get 0 or 1.
Sadly you can't return both stdout and the status. One way of doing it would be to only use returnStatus: true
and pipe stdout to a file.
The pipeline would look something like this:
def slackChannel = "default-ops"
def slackDetails = "${env.JOB_NAME} - (<${env.BUILD_URL}|Open>)"
def shResult() {
script {
sh script: 'set -e; python3 testing.py > /tmp/somefile 2>&1', returnStatus: true
}
}
pipeline {
agent any
stages {
stage('Execute testing.py') {
steps {
script{
status = shResult()
if (status != 0) {
currentBuild.result = 'FAILURE'
errorMsg = readFile '/tmp/somefile'
}
}
}
}
}
post {
success {
slackSend(color: '#00FF00',
channel: "${slackChannel}",
message: "SUCCESSFUL: " slackDetails)
}
failure {
slackSend(color: '#FF0000',
channel: "${slackChannel}",
message: "FAILED: " slackDetails errorMsg
}
aborted {
slackSend(color: '#808080',
channel: "${slackChannel}",
message: "ABORTED: " slackDetails)
}
}
}
I can't test this pipeline right now but it should work.