Як правильно досягти динамічної паралельної дії декларативним трубопроводом?


22

В даний час мені знадобиться реалізація, яка повинна знаходити всі файли в каталозі і починати паралельне завдання для кожного знайденого файлу.

Чи можна цього досягти, використовуючи декларативні трубопроводи?

pipeline {
    agent any
    stages {
        stage("test") {
            steps {
                dir ("file_path") {
                    // find all files with complete path
                    parallel (
                        // execute parallel tasks for each file found.
                        // this must be dynamic
                        }
                    }
                }
            }
        }
    }
}

Як я можу зробити, якщо хочу виконувати кілька кроків послідовно, а не паралельно?
Френк Ескобар

Звичайно, але таким чином ви не можете динамічно генерувати паралельні завдання, наприклад, залежно від деяких файлів у сховищі.
Рауль Салінас-Монтеагудо

Відповіді:


23

Вдалося вирішити це за допомогою наступного коду:

pipeline {
    agent { label "master"}
    stages {
        stage('1') {
            steps {
                script {
                    def tests = [:]
                    for (f in findFiles(glob: '**/html/*.html')) {
                        tests["${f}"] = {
                            node {
                                stage("${f}") {
                                    echo '${f}'
                                }
                            }
                        }
                    }
                    parallel tests
                }
            }
        }       
    }
}

Будь ласка, ознайомтесь із офіційними прикладами трубопроводу - jenkins.io/doc/pipeline/examples/#parallel-multiple-nodes
phedoreanu

@phedoreanu Я використовую декларативний конвеєр ...
thclpr

@phedoreanu Я відхилив ваше редагування, редагування коду повинно бути вагомими причинами. Ваш коментар недостатньо для того, щоб дозволити редагувати подібну відповідь на відповідь, яке було самостійним рішенням. Я думаю, вам слід було б прокоментувати, щоб обговорити це питання з автором відповіді, перш ніж редагувати це.
Тенсібай

@phedoreanu Я вважаю, що ви маєте кращу похідну роботу, тоді, будь ласка, напишіть власну відповідь та поясніть, чому це краще (в роботі з помилками, шаблонах тощо).
Тенсібай

Привіт, я зрозумів те саме після кількох невдалих спроб. Моя єдина проблема зараз полягає в тому, що якщо я поміщую два етапи {..} секції всередину вузла, то з якихось причин діаграма етапу робочого процесу та Blu Ocean заплутаються. Наприклад, у графіку етапу робочого процесу я отримую NaNy NaNd, а в Blue Ocean я отримую лише перший етап.
Джузеппе

7

Це також працює, якщо ви хочете залишитися в Declarative Pipelineпросторі

// declare our vars outside the pipeline
def tests = [:]
def files

pipeline {
    agent any
    stages {
        stage('1') {
            steps {
                script {
                    // we've declared the variable, now we give it the values
                    files = findFiles(glob: '**/html/*.html')
                    // Loop through them
                    files.each { f ->
                        // add each object from the 'files' loop to the 'tests' array
                        tests[f] = {
                            // we're already in the script{} block, so do our advanced stuff here
                            echo f.toString()
                        }
                    }
                    // Still within the 'Script' block, run the parallel array object
                    parallel tests
                }
            }
        }       
    }
}

1
Якщо ви хочете виділити кожне паралельне завдання на різні вузли Дженкінса, тоді просто загортайте дії в node {}блок, як це: tests[f] = { node { echo f.toString() } }
Приметей

1

Набагато простіше використовувати скриптовані трубопроводи для цього, оскільки ви можете використовувати довільний Groovy, але ви все одно можете це зробити з декларативними трубопроводами, використовуючи findFilesкрок.


1

Пам’ятайте, що динамічні кроки збирання можуть спричинити деякі проблеми в деяких етапах збирання, наприклад, коли ви телефонуєте на іншу роботу:

pipeline {
    stages {
        stage('Test') {
            steps {
                script {
                    def tests = [:]
                    for (f in findFiles(glob: '**/html/*.html')) {
                        // Create temp variable, otherwise the name will be the last value of the for loop
                        def name = f
                        tests["${name}"] = {
                            build job: "${name}"
                        }
                    }
                    parallel tests
                }
            }
        }       
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.