How to tell whether job failed or was aborted - jenkins-pipeline

I've got a Jenkins job with a try..catch structure:
try
{
[do work here]
}
catch(err)
{
}
Is there any way, from inside the catch block, that I can tell whether the build failed or was aborted by the user?
I've tried looking at err.getMessage(), err.getCause(), err.toString(), and currentBuild.result, but none of them consistently tell me whether it failed or was aborted.

AFAIK there's no consistent way to tell if a build was failed or aborted. When a user interrupts a build a java.lang.InterruptedException is thrown, so you could start with that. Be careful with other code which could throw an InterruptedException, like the input() step when aborted.
So you could do something like:
try
{
[do work here]
}
catch(err)
{
if (err instanceof InterruptedException) {
[handle error]
} else {
[handle error]
}
}

The aborted status will be setted at build.status or currentBuild.result,
according to the issue from Jenkins official Jira issue (
https://issues.jenkins-ci.org/browse/JENKINS-43339 ):
Regrettably, not much we can do here - the ABORTED status, in some cases, doesn't get set until the Pipeline finishes executing, so we can't tell from Declarative that we should be treating the build as ABORTED.

Related

How can i set the jenkins job to pass when the test are actually failed

I'm trying to do something similar to what this guy is doing:
Jenkins failed build: I Want it to pass
create a pipeline job in Jenkins for all the Known bugs tests, I want the job to PASS when all the tests are FAILED. while when even 1 test is PASS, the job will be GREEN.
I found here this solution
stage('Tests') {
steps {
script{
//running the tests
status = sh "${mvnHome}/bin/mvn clean test -e -Dgroups=categories.knownBug"
if (status === "MARK-AS-UNSTABLE") {
currentBuild.result = "STABLE"
}
}
}
}
but got an error
Unsupported operation in this context # line 47, column 39.
if (status === "MARK-AS-UNSTABLE") {
------------EDIT---------
Thanks to #yrc I changed the code to
try {
sh "${mvnHome}/bin/mvn clean test -e -Dgroups=categories.knownBug"
} catch (err) {
echo "Caught: ${err}"
currentBuild.result = "STABLE"
}
It did help with the error msg, but I want the job to pass when one of the tests is failing. Now, both test and job has failed
Just wrap your execution with a try-catch block.
try {
sh "${mvnHome}/bin/mvn clean test -e -Dgroups=categories.knownBug"
} catch (err) {
echo "Caught: ${err}"
currentBuild.result = "STABLE"
}

Detect shutting-down-controller in post action in declarative pipeline

I have success, failure and aborted under post in declarative pipeline, is there a way to detect
shutting down controller and perform different actions?
e.g:
post {
success {
// do some actions for successful completion
}
failure {
// do some actions for failure completion
}
aborted {
// do some actions when job gets aborted
}
controller-shutting-down {
echo "Jenkins is shutting down."
}
}
OR:
...
aborted {
if (reason == controller-shutting-down) {
echo "Jenkins is shutting down."
} else {
// do some actions when job gets aborted
}
}
...
Is there a way to acheive this?

parameterized-remote-trigger is throwing 405 exception

I am trying to trigger a job A(this is configured as trigger remote) remotely from another job B, and job B needs to hold until results come back to show success or failure, I initially tried using rest API using curl command, it perfectly works.here's the curl code:
curl -v -X POST 'https://xxx.xxx/xxx-xxx/job/xxx/job/master/buildWithParameters?config_files=./jenkins/unit-tests.json' --user xxxx:110f4dfa33ba8f8ef5d8d299beb6aa1543
I choose parameterized plugin code which installed on Jenkins server because it handles the polling mechanism internally and also has handler friendly methods. please see below code for remoteJob, but it fails with 405 error, that means method not allowed in HTTP language, looks like plugin is using GET method instead of post. I added an option for logging , but it does not seems to be showing more log.
def handle = triggerRemoteJob(
remoteJenkinsName: 'remote-master',
job: 'https://xxx.xxx.com/xxx-xxx/job/xxx/job/master/buildWithParameters',
remoteJenkinsUrl: 'https://xxx.xxx.xxx/xxx-xxx/job/xxx/job/master/buildWithParameters',
auth: TokenAuth(apiToken: hudson.util.Secret.fromString('110f4dfa33ba8f8ef5d8d299beb6aa1543'), userName: 'xxxx'),
parameters: 'config_files=./jenkins/unit-tests')
I am getting following error -
[Pipeline] triggerRemoteJob
##########################################################################
Parameterized Remote Trigger Configuration:
- job: https://xxx.xxx.xxx/xxx-xxx/job/xxx/job/master/buildWithParameters
- remoteJenkinsUrl: https://xxx.xxx.xxx/xxx-xxx/job/ius/job/master/buildWithParameters
- auth: 'Token Authentication' as user 'sseri'
- parameters: [config_files=./jenkins/unit-tests]
- blockBuildUntilComplete: true
- connectionRetryLimit: 5
- trustAllCertificates: false
##########################################################################
Connection to remote server failed [405], waiting to retry - 10 seconds until next attempt. URL: https://xxx.xxx.xxx/xxx-xxx/job/xxx/job/master/buildWithParameters/api/json, parameters:
Retry attempt #1 out of 5
Please help me in this regard!
I am not sure about the plugins you are using, but it's quite simple to implement this scenario "call a downstream job from upstream and fail upstream if the downstream fail" without any plugins.
Take a look at my example below.
let say if you have 2 jobs called jobA and jobB and your goal is to call jobB from jobA and fail the jobA if jobB fail.
**Scripted Pipeline for jobA **
node() {
try {
def jobB = build(job: jobName,parameters: [string(name:"parameterName",value: "parameterValue")])
def jobBStatus = jobB.getResult()
if(jobBStatus == "failed") {
throw new RuntimeException("Downstream job-b failed with reason ...");
}
...
}catch(Exception e) {
throw e
}
}
Declarative Pipeline for jobA
pipeline {
agent any;
stages {
stage('call jobB') {
steps {
script {
def jobB = build(job: jobName,parameters: [
string(name:"parameterName",value: "parameterValue")
])
def jobBStatus = jobB.getResult()
if(jobBStatus == "failed") {
error("Downstream job-b failed with reason ...")
}
}
}
}
}
}
Try using this Parameterized-Remote-Trigger-Plugin. It should give you what you want. I'm having some problems configuring it using authentication tokens and users using Jenkinsfile but if you are using the GUI im sure you will get the job done.

Grouping post conditions in a Jenkins declarative pipeline

Is there a way to group post conditions in a Jenkins declarative pipeline ?
For instance, I want to do the same thing for statuses aborted failure and success.
Is there a shorter way to do it than the following ?
post {
aborted { sendNotification(currentBuild.result, "$LIST_NOTIFICATION_JENKINS")
failure { sendNotification(currentBuild.result, "$LIST_NOTIFICATION_JENKINS")
success { sendNotification(currentBuild.result, "$LIST_NOTIFICATION_JENKINS")
}
There is the 'always' condition:
post {
always {sendNotification(currentBuild.result, "$LIST_NOTIFICATION_JENKINS")}
}
The 'always' condition will run regardless of the stage result.
See the documentation on the post section.
If you want a set of common actions between just a few conditions, for example if you wanted to do the same thing for failure and aborted, I would recommend creating a function in your script to call from the failure and aborted post conditions.
You can also do something like the following:
always {
script{
if (currentBuild.currentResult == "ABORTED" || currentBuild.currentResult == "FAILURE")
{
echo "was aborted or failed"
}
}
}

Stop alloy build from a build config task (alloy.jmk)

Let's say I have the following task modifying my Alloy compile process (alloy.jmk build configuration file)
task("pre:compile", function (e, log) {
// execute something that may throw an error
try {
// ...
}
catch(err) {
// do some custom error handling
// ...
// !!! need to stop the build here !!!
}
log.info("My task completed!");
});
How can I stop the build in the catch-clause? Of course I could just remove the try-catch but then my custom error handling won't be executed...
Well, answering my own question here... It seems it was too easy ... Simply throw a custom error inside the catch-statement like so
task("pre:compile", function (e, log) {
// execute something that may throw an error
try {
// ...
}
catch(err) {
// do some custom error handling
// ...
throw('throwing some error to stop the build');
}
log.info("My task completed!");
});

Resources