Как использовать failFast в динамическом конвейере в Jenkins

У меня есть конвейер с динамическими параллельными этапами, и я хочу, чтобы мой конвейер быстро выходил из строя, если какой-либо из этапов выходит из строя. Я попытался добавить failFast: true, но мой конвейер застрял на «Сбой на этапе ABC».

  stage("Deploy") {             
        steps {
            script {
                def stages = createStages("Name", "Project")
                fastFail: true
                for (stage in stages) {                        
                    parallel stage                      
                }
            }
        }
    }

person aditi gupta    schedule 20.09.2019    source источник


Ответы (3)


Решение. Используйте failFast флаг для конвейера Jenkins.

Из документации: вы можете принудительно использовать параллельные этапы для всех быть прервано, когда один из них выходит из строя, путем добавления failFast true к этапу, содержащему параллель.

Обратите внимание, что все задания будут запущены и завершены (в случае сбоя одного из них), если узел агента был запущен в каждом из них (если задание «а» в конвейере завершается сбоем, но задание «б» все еще ищет для узла, который еще не запущен, он продолжится — [это крайний случай]).

Примеры. Варианты:

1. Используйте метод parallelsAlwaysFailFast в конвейере параметров:

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. Используйте перед параллельным использованием failFast true

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

3. Настройте задания на карте и выполните их с включенным атрибутом failFast.

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

 jobsList.failFast = true
 parallel(jobsList)
person avivamg    schedule 27.11.2019

Я не мог ответить на ответ, предоставленный @avivamg, но я не смог напрямую использовать его / ее решение. Это сработало для меня:

stages.failFast = true
parallel stages

Или в вашем случае:

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                      
                }
            }
        }
    }
person Gabe Villarreal    schedule 10.06.2020

Вы можете определить функцию следующим образом:

void parallelRunner(Map parallelSteps = [:], Closure body) {
    def pjs = parallelSteps.collectEntries { stageName, config ->
        ["${stageName}" : {
            stage("${stageName}") {
                body(config)
            }
        }]
    }

    parallel pjs.plus(([failFast: false]))
}

и вызвать его

def parallelMap = [
    parallel-runner-1: [
       // there are some configs
       git: gitConfig,
       k8s: k8sConfig,
    ],
    parallel-runner-2: [
       // there are some configs
       git: gitConfig,
       k8s: k8sConfig,
    ],
]

parallelRunner(parallelSteps: parallelMap) { config ->
    installXRpm config: [
        git: config.git,
        k8s: config.k8s,
    ]
}

Будут запущены два параллельных задания с разными параметрами (задание parallel-runner-1 и задание parallel-runner-2).

person Xiak    schedule 18.01.2021