Declarative vs Scripted Handling failures - jenkins

I see on Declarative Pipeline that it's done via "post" section really easy with conditions like 'always', 'failure', ...:
https://jenkins.io/doc/book/pipeline/syntax/#post
But with Scripted Pipeline there are no examples on how it's done:
This link provides an example but only for "always" condition
https://jenkins.io/doc/book/pipeline/jenkinsfile/#handling-failures
I see this docs on how to set that result but I don't understand because with Declarative Pipeline you don't have to set it manually, plugins provided commands handle that for you.
https://support.cloudbees.com/hc/en-us/articles/218554077-How-to-set-current-build-result-in-Pipeline
Can anyone help me with this?
For example if I do this:
node {
try {
error 'Test error'
} catch (ex) {
echo 'Error handled'
}
}
It doesn't trigger the "FAILURE" build status automatically and I don't see the echo. Why?

Your piece of code works as expected :
node { try { error 'Test error' } catch (ex) { echo 'Error handled' } }
gives :
[Pipeline] node
Running on maƮtre in /var/lib/jenkins/workspace/test-pipeline2
[Pipeline] {
[Pipeline] error
[Pipeline] echo
Error handled
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
Explanations :
error 'Test error' isn't supposed to log anything. It's equivalent to the Java throw new Exception("Test error"). See https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/#code-error-code-error-signal
the catch block catches this exception, and logs the message as expected. After this block, no error is thrown to the Jenkins runner, so the job ended as Successful.
If you want to mark your build as failed, you have to do this explicitly in the catch block. You can also use the catchError block to handle this for you. See : https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/#code-catcherror-code-catch-error-and-set-build-result

Related

jenkins job skipped due to when conditional and how to avoid notification as success

I created a jenkins job, which is executes build step when conditions met else job will skipped.
stage script is like this
stage('build') {
when {
anyof {
changeset "**/*.js"
changeset "**/*.xml"
triggeredBy cause: "UserIdCause"
}
}
steps{
build script
}
}
If any of condition is true, build step will executed else job will be skipped.
output looks like:
[Pipeline] stage
[Pipeline] { (build)
[Pipeline] echo
Warning, empty changelog. Have you run checkout?
[Pipeline] echo
Warning, empty changelog. Have you run checkout?
[Pipeline] echo
Warning, empty changelog. Have you run checkout?
[Pipeline] echo
Warning, empty changelog. Have you run checkout?
Stage "build" skipped due to when conditional
Job status is success for skipped builds too.
I don't want to notify the team when build step skipped due to "when condition". How to achieve this. notifying teams via slack from post - success section.
Maybe you can do this in post section
post {
always {
script {
if ("${currentBuild.currentResult}" != 'SUCCESS') {
# add the logic of sending email to developers
}
}
}
}

Jenkins declarative pipeline - proceed to subsequent stages even one stage fails

I have below stage and when it fails, the stage has to be "Paused" for user to take required action to fix the issue at the back end server. After fixing the issue, when user click OK in the input message, the next stage would be executed. But in the below code, when i click OK in the input message box the whole job is terminated. Any idea how to achieve this?
Appreciate your help!
stage('Execute Shellscript')
{
steps
{
script
{
try
{
def var1 = sshCommand remote: remote, command: "sh fastartstop.sh"
sleep(time:30,unit:"SECONDS")
}
catch(Exception e)
{
currentBuild.result ='UNSTABLE'
echo "The current status is ${currentBuild.result}"
echo "Failed: ${e}"
env.RELEASE_SCOPE = input message: 'Job failed. Please fix it manually and proceed further. Else click Abort to terminate the job!!!', ok: 'Proceed'
emailext (body: "",
subject: "HOST ${params.FA_HOST} - FA Patching fails at ${env.STAGE_NAME} stage and refer Job ${env.BUILD_NUMBER} for more info. Please fix the issue manually and proceed further for next step!!",
to: "${params.EMAIL_LIST}")
}
}
}
}

Jenkins cucumber reports

I'm using Cucumber reports plugin in my declarative pipeline like that:
cucumber '**/cucumber.json'
I'm able to check if some tests fail through link on the sidebar, but do I need to do something to mark the stage containing cucumber.json check as failed if some cucumber reports are failed? Because the problem is the build and stage are both green and successful despite there are some failed cucumber reports.
Jenkins version is 2.176.3
Cucumber reports version is 4.10.0
Cucumber command you are using just generates the report regardless the test result.
So yes, you have to make your pipeline fail somehow as the problem you are facing is that your test command is not returning making your pipeline fail.
The way to go is to make that the command that runs the tests returns non-zero exit code (exit 1) if something went wrong on your tests. That would make your pipeline stage to go red.
In case you run your tests using Maven this would be automatically managed on 'mvn test' (or whatever).
Otherwise, if you cannot do that, you will have to manage to make something like for example an sh script
that returns the exit code (0 pass / 1 fail) or a groovy function inside 'script' tag that sets the pipeline currentBuild.result value:
def checkTestResult() {
// Check some file to see if tests went fine or not
return 'SUCCESS' // or 'FAILURE'
}
...
stage {
script {
currentBuild.result = checkTestResult()
if (currentBuild.result == 'FAILURE') {
sh "exit 1" // Force pipeline exit with build result failed
}
}
}
...
I recommend you to use cucumber command on a 'always' post build action of your declarative pipeline
as it is a step that you will likely execute every time at the end of the pipeline either if it passes or fails. See the following example:
pipeline {
stages {
stage('Get code') {
// Whatever
}
stage('Run tests') {
steps {
sh "mvn test" // run_tests.sh or groovy code
}
}
}
post {
always {
cucumber '**/cucumber.json'
}
}
}
It is possible to set BuildStatus : 'FAILURE' to mark build as failed if a report marked as failed.
cucumber fileIncludePattern: '**/cucumber.json', buildStatus: 'FAILURE'

Custom function in Delcarative Pipeline?

I have this simple pipeline (I'm using a more complex but this one reproduces it):
def test(String name) {
println test
}
pipeline {
agent {
dockerfile {
label "jenkins-lnx-slave3"
args "--user root:root"
dir "CICD"
}
}
stages {
stage ('Test') {
steps {
test(name: 'Hello')
}
}
}
}
And Jenkins is giving me this "No Such DSL method 'test' found" error:
> [Pipeline] } [Pipeline] // withEnv [Pipeline] } [Pipeline] // node
> [Pipeline] End of Pipeline java.lang.NoSuchMethodError: No such DSL
> method 'test' found among steps [ArtifactoryGradleBuild,
This goes on and on for many lines. Am I doing the custom function correctly?
Anyone have any ideas?
You're trying to call test with a named argument and that's causing the breakage. This post explains what's happening when you try to use named params in groovy.
Additionally, you have a typo inside test:
println test should be println name.

Jenkins pipeline - try catch for particular stage and subsequent conditional step

I'm trying to replicate the equivalent of a conditional stage in Jenkins pipeline using a try / catch around a preceding stage, which then sets a success variable, which is used to trigger the conditional stage.
It appears that a try catch block is the way to go, setting a success var to SUCCESS or FAILED, which is used as part of a when statement later (as part of the conditional stage).
The code I am using is as follows:
pipeline {
agent any
stages {
try{
stage("Run unit tests"){
steps{
sh '''
# Run unit tests without capturing stdout or logs, generates cobetura reports
cd ./python
nosetests3 --with-xcoverage --nocapture --with-xunit --nologcapture --cover-package=application
cd ..
'''
currentBuild.result = 'SUCCESS'
}
}
} catch(Exception e) {
// Do something with the exception
currentBuild.result = 'SUCCESS'
}
stage ('Speak') {
when {
expression { currentBuild.result == 'SUCCESS' }
}
steps{
echo "Hello, CONDITIONAL"
}
}
}
}
The latest syntax error I am receiving is as follows:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup
failed:
WorkflowScript: 4: Expected a stage # line 4, column 9.
try{
I've also tried lots of variations.
Am I taking the wrong approach here? This seems like a fairly common requirement.
Thanks.
This might solve your problem depending on what you are going for. Stages are only run when the preceding stages succeed, so if you actually have two stages like in your example, and if you want the second to only run when the first succeeds, you want to ensure that the first stage fails appropriately when tests fail. Catching will prevent the (desirable) failure. Finally will preserve the failure, and can also still be used to grab your test results.
So here, the second stage will only run when the tests pass, and the test results will be recorded regardless:
pipeline {
agent any
stages {
stage("Run unit tests"){
steps {
script {
try {
sh '''
# Run unit tests without capturing stdout or logs, generates cobetura reports
cd ./python
nosetests3 --with-xcoverage --nocapture --with-xunit --nologcapture --cover-package=application
cd ..
'''
} finally {
junit 'nosetests.xml'
}
}
}
}
stage ('Speak') {
steps{
echo "Hello, CONDITIONAL"
}
}
}
}
Note that I'm actually using try in a declarative pipeline, but like StephenKing says, you can't just use try directly (you have to wrap arbitrary groovy code in the script step).

Resources