Como obter adequadamente uma ação paralela dinâmica com um pipeline declarativo?


19

Atualmente, vou precisar de uma implementação que encontre todos os arquivos em um diretório e inicie uma tarefa paralela para cada arquivo encontrado.

É possível conseguir isso usando pipelines declarativos?

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
                        }
                    }
                }
            }
        }
    }
}

Como posso fazer se eu quiser executar várias etapas sequencialmente e não paralelo?
Frank Escobar

Respostas:


21

Conseguiu resolvê-lo com o seguinte código:

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
                }
            }
        }       
    }
}

Por favor verifique, também, os exemplos oficiais Pipeline - jenkins.io/doc/pipeline/examples/#parallel-multiple-nodes
phedoreanu

@phedoreanu eu estou usando gasoduto declarativa ...
thclpr

@phedoreanu Rejeitei sua edição, o código de edição deve ter boas razões, seu comentário não é suficiente para permitir uma edição desse tipo em uma resposta que foi uma solução automática. Acho que você deveria ter comentado para discutir o assunto com o autor da resposta antes de fazer esta edição.
Tensibai

@phedoreanu Eu acho que você tem um trabalho derivado melhor, então escreva sua própria resposta e explique por que é melhor (no tratamento de erros, modelos, etc.).
Tensibai

Oi, eu descobri o mesmo depois de algumas tentativas fracassadas. Meu único problema agora é que, se eu colocar duas seções do estágio {..} dentro de um nó, por alguns motivos, o gráfico do estágio do fluxo de trabalho e o Blu Ocean ficarão confusos. Por exemplo, no gráfico de etapas do fluxo de trabalho, recebo o NaNy NaNd e, no Blue Ocean, apenas o primeiro estágio.
21719 Giuseppe

6

Isso também funciona, se você quiser ficar dentro do Declarative Pipelineespaço

// 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
                }
            }
        }       
    }
}

Se você deseja alocar cada tarefa paralela para diferentes nós Jenkins, basta agrupar as ações em um node {}bloco, como este: tests[f] = { node { echo f.toString() } }
primetheus

1

É muito mais fácil usar Pipelines com script para fazer isso, pois você pode usar o Groovy arbitrário, mas ainda deve conseguir fazer isso com Pipelines declarativos usando a findFilesetapa.


1

Esteja ciente de que as etapas dinâmicas de construção podem causar alguns problemas em algumas etapas, por exemplo, quando você chama outro trabalho:

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
                }
            }
        }       
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.