How to use failFast in dynamic pipeline in Jenkins
Asked Answered
B

3

9

I have pipeline which has dynamic parallel stages and I want my pipeline to fail fast, if any of the stage fail. I tried to add failFast: true but my pipeline is stuck at "Failed at Stage ABC".

  stage("Deploy") {             
        steps {
            script {
                def stages = createStages("Name", "Project")
                fastFail: true
                for (stage in stages) {                        
                    parallel stage                      
                }
            }
        }
    }
Bicycle answered 20/9, 2019 at 10:5 Comment(0)
C
27

Solution: Use failFast flag on Jenkins pipeline.

From Documentation: You can force your parallel stages to all be aborted when one of them fails, by adding failFast true to the stage containing the parallel.

Pay attention that all jobs would be triggered and quit (if one fails) if the agent node was started in each one of them (if job 'a' in pipeline fails but job 'b' is still looking for node and not started yet, it will continue - [this is an edge case]).

Examples - The options are :

1.Use parallelsAlwaysFailFast method in your options pipeline:

pipeline {
agent any
options {
    parallelsAlwaysFailFast()
}
stages {
    stage('Non-Parallel Stage') {
        steps {
            echo 'This stage will be executed first.'
        }
    }
    stage('Parallel Stage') {
        when {
            branch 'master'
        }
        parallel {
            stage('Branch A') {
                agent {
                    label "for-branch-a"
                }
                steps {
                    echo "On Branch A"
                }
            }
            stage('Branch B') {
                agent {
                    label "for-branch-b"
                }
                steps {
                    echo "On Branch B"
                }
            }
            stage('Branch C') {
                agent {
                    label "for-branch-c"
                }
                stages {
                    stage('Nested 1') {
                        steps {
                            echo "In stage Nested 1 within Branch C"
                        }
                    }
                    stage('Nested 2') {
                        steps {
                            echo "In stage Nested 2 within Branch C"
                        }
                    }
                }
            }
        }
    }
}

2.Use before parallel using failFast true

stage('Parallel Stage') {
        when {
            branch 'master'
        }
        failFast true
        parallel {

3.Configure jobs in map and execute with failFast attribute on.

 jobsList = [
    {job: 'jobA', parameters: [booleanParam(name: 'flag', value: true)]},
    {job: 'jobB', parameters: [booleanParam(name: 'flag', value: true)]}
 ]

 jobsList.failFast = true
 parallel(jobsList)
Coprolite answered 27/11, 2019 at 11:23 Comment(2)
RE: "if job 'a' in pipeline fails but job 'b' is still looking for node and not started yet, it will continue" Is there a way to catch this edge case? For us it occurs quite often and failFast is useless that way.Achates
This doesn't work. jobsList is an array an it doesn't have the attribute failFastVaporing
R
4

I couldn't reply to the answer provided by @avivamg but I wasn't able to use his/her solution directly. This worked for me:

stages.failFast = true
parallel stages

Or in your case:

stage("Deploy") {             
        steps {
            script {
                def stages = createStages("Name", "Project")
                stages.fastFail = true
                // I'm not sure if the for loop will work as failFast is on the map
                // so if that doesn't work then you could use this instead:
                // parallel stages
                for (stage in stages) {                        
                    parallel stage                      
                }
            }
        }
    }
Reg answered 10/6, 2020 at 22:2 Comment(0)
D
0

If you're using a scripted pipeline then you need to add the failFast into the parallel step like so -

    stage('SomeStage') {
    parallel (
        "Process1" : { //do something },
        "Process2" : { //do something else },
        failFast: true
    )
}
Dincolo answered 20/10, 2021 at 15:33 Comment(1)
What would this solution look like when process1 and process2 are saved in a map? Ideally an arbitrary number of processes?Achates

© 2022 - 2024 — McMap. All rights reserved.