How to use parallelsAlwaysFailFast() in scripted pipeline? - jenkins

How to use parallelsAlwaysFailFast() in Jenkins Scripted Pipeline?
I could not find any example for this.
Edited, here is the code I use and the 'Blue Ocean' screenshot:
stage("Build") {
parallel([
failFast: true,
"Stage 1":{
stage("Stage 1") {
stage("a1") {
println("a1")
};
stage("a2") {
println("a2")
}
}
},
"Stage 2":{
stage("Stage 2") {
stage("b1") {
sh '''pwd'''
};
stage("b2") {
echo '''Here we can see the InterruptedException'''
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
error "Failing the stage"
}
}
}
}
])
}
Blue Ocean img
How can I make all the stages that are executed in parallel to fail as well?
Thanks.

As far as I know, there is no way to change that behavior for all the future parallel stages.
However one can change it for any given set of parallel stages, like this:
def parallel_stages = [:].asSynchronized()
parallel_stages['one'] = {
stage ('One') {
script {
println "One"
}
}
}
parallel_stages['two'] = {
stage ('Two') {
script {
println "Two"
}
}
}
// Here you set this for the given parallel stage
parallel_stages.failFast = true
parallel parallel_stages

Related

How to add error handling code to `catchError()` in Jenkins?

If I have a pipeline where individual stages are allowed to fail, without failing the whole job, how can I add error handling to, for instance, send an email to an admin, when that stage fails? I've tried using post failure, but it doesn't work.
pipeline {
agent any
stages {
stage('1') {
steps {
sh 'exit 0'
}
}
stage('2') {
steps {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh "exit 1"
}
}
post {
failure {
echo 'Sending email to admin...'
}
}
}
stage('3') {
steps {
sh 'exit 0'
}
}
}
}
I got this question in a comment and thought it was worth asking and answering as a proper question.
Unfortunately, for now, I think the only way is to use try catch in a script block and re-throw the error after performing the error handling. See example below:
pipeline {
agent any
stages {
stage('1') {
steps {
sh 'exit 0'
}
}
stage('2') {
steps {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
script {
try {
sh "exit 1"
} catch (e) {
echo 'send email'
throw e
}
}
}
}
}
stage('3') {
steps {
sh 'exit 0'
}
}
}
}

Display Jenkins pipeline stage as failed without failing the whole job

Could you please tell me what I am doing wrong. I would like to failure a Stage1. Stage2 should be green and that case, and I would like to have whole build Success. What I am doing wrong?
pipeline{
agent none
stages{
stage ("Stage1") {
steps {
script{
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
stage ("stege1") {
def seekAndDestroy = build job: 'SeekAndDestroy' // it is going FAILURE
}
}
stage ("Stege2") {
sh "exit 0"
}
}
}
}
}
}
catchError is something similar to try/catch block, so you need to catch error of the code you are executing. For details - see documentation: https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/#catcherror-catch-error-and-set-build-result-to-failure
This works:
pipeline{
agent { label 'jdk11' }
stages {
stage ("stage 1") {
steps {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh "exit 1"
}
}
}
stage ("stage 2") {
steps {
sh "exit 0"
}
}
}
}
And the result is:

Jenkins pipeline execute job and get status

pipeline {
agent { label 'master' }
stages {
stage('test') {
steps {
script {
def job_exec_details = build job: 'build_job'
if (job_exec_details.status == 'Failed') {
echo "JOB FAILED"
}
}
}
}
}
}
I have a pipeline that executing build job, how can I get Job result in jenkins pipeline ?
It should be getResult() and status should be FAILURE not Failed.
so your whole code should be like this
pipeline {
agent { label 'master' }
stages {
stage('test') {
steps {
script {
def job_exec_details = build job: 'build_job', propagate: false, wait: true // Here wait: true means current running job will wait for build_job to finish.
if (job_exec_details.getResult() == 'FAILURE') {
echo "JOB FAILED"
}
}
}
}
}
}
Where is a second way of getting results:
pipeline {
agent { label 'master' }
stages {
stage('test') {
steps {
build(job: 'build_job', propagate: true, wait: true)
}
}
}
post {
success {
echo 'Job result is success'
}
failure {
echo 'Job result is failure'
}
}
}
}
You can read more about 'build' step here

Jenkins multipe post sections per stage

I have two question for usage of post section in Jenkins pipeline
1.Can we use multiple post section per stage in Jenkins declarative Pipeline?
2.Can we run sh command in post section?
pipeline{
stages{
stage("....") {
steps {
script {
....
}
}
post {
failure{
sh "....."
}
}
stage("Second stage") {
when {
expression { /*condition */ }
}
steps {
script{
....
}
post {
always {
script {
sh "..."
}
}
}
}
}
You can find information in https://jenkins.io/doc/book/pipeline/syntax/#post
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
post {
success {
sh label: 'success', script: 'ls'
}
failure {
sh label: 'failure', script: 'ls'
}
aborted {
sh label: 'aborted', script: 'ls'
}
}
}
You can use Post steps each Stage, but pipeline will stop on first failure. In example below, if Stage 1 fail Stage 2 will be skipped. Post after all stages will always executed.
pipeline{
stages{
stage("Stage 1") {
steps {
catchError(message: 'catch failure') {
script {
sh "echo stage 1"
}
}
}
post {
always {
sh "echo post stage 1"
}
}
}
stage("Stage 2") {
when {
expression { /*condition */ }
}
steps {
script{
sh "echo stage 2"
}
}
post {
always {
script {
sh "echo post stage 2"
}
}
}
}
}
post {
always {
sh "echo post after all stages"
}
}
}

Jenkins pipeline with parallel

Here is my Jenkins pipeline that i am trying to execute. I am following this tutorial:
pipeline {
agent any
stages {
stage('one') {
parallel "first" : {
echo "hello"
},
"second": {
echo "world"
}
}
stage('two') {
parallel "first" : {
echo "hello"
},
"second": {
echo "world"
}
}
}
}
But the job fails with following message.
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 4: Unknown stage section "parallel". Starting with version 0.5, steps in a stage must be in a steps block. # line 4, column 9.
stage('one') {
^
WorkflowScript: 12: Unknown stage section "parallel". Starting with version 0.5, steps in a stage must be in a steps block. # line 12, column 9.
stage('two') {
^
WorkflowScript: 4: Nothing to execute within stage "one" # line 4, column 9.
stage('one') {
^
WorkflowScript: 12: Nothing to execute within stage "two" # line 12, column 9.
stage('two') {
^
4 errors
Can someone please help me out why this is failing.
You need to add a steps block after your stage declaration.
pipeline {
agent any
stages {
stage('Example Stage 1') {
steps {
parallel(
"step 1": { echo "hello" },
"step 2": { echo "world" },
"step 3": { echo "world" }
)
}
}
stage('Example Stage 2') {
steps {
parallel(
"step 1": { echo "hello" },
"step 2": { echo "world" },
"step 3": { echo "world" }
)
}
}
}
}
To Make your Stages Parallel use this, both solutions show up very similar in Blue Ocean :
pipeline {
agent any
stages {
stage('Example Stage') {
parallel {
stage('Stage 1') {
steps { sh 'echo stage 1 passed' }
}
stage('Stage 2') {
steps { sh 'echo stage 2 passed' }
}
stage('Stage 3') {
steps { sh 'echo stage 3 passed' }
}
}
}
}
}
You need to upgrade the Declarative Pipeline plugin on your Jenkins to Version 1.2 (Sept 21, 2017) or above
In declarative pipeline, in case if you want to add stage, inside steps, this nesting is also possible.
If the steps are same in that case you can declare step as a function.
def steps = ['first', 'second']
def generateSteps(stepLabel) {
return {
step("${stepLabel}") {
echo "Running on ${stepLabel}"
}
}
}
def parallelStepMap = steps.collectEntries {
["${it}" : generateSteps(it)]
}
pipeline {
agent any
stages {
stage('non-parallel stage') {
steps {
echo 'This stage will be executed first.'
}
}
stage('parallel stage') {
steps {
script {
parallel parallelStepMap
}
}
}
}
}
General need is to execute different stages into different nodes.
in such case above function can be modified to execute on different agent nodes as follows.
def agents = ['master', 'agent1', 'agent2']
def generateStage(nodeLabel) {
return {
stage("Runs on ${nodeLabel}") {
node(nodeLabel) {
echo "Running on ${nodeLabel}"
}
}
}
}
def parallelStagesMap = agents.collectEntries {
["${it}" : generateStage(it)]
}
pipeline {
agent none
stages {
stage('non-parallel stage') {
steps {
echo 'This stage will be executed first.'
}
}
stage('parallel stage') {
steps {
script {
parallel parallelStagesMap
}
}
}
}
}
With nodelabel defined inside the function and agent none during start of pipeline, the stages will be executed into different nodes.

Resources