Come ottenere correttamente un'azione parallela dinamica con una pipeline dichiarativa?


20

Al momento, avrò bisogno di un'implementazione che deve trovare tutti i file all'interno di una directory e avviare un'attività parallela per ogni file trovato.

È possibile raggiungere questo obiettivo utilizzando pipeline dichiarative?

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

Come posso fare se voglio eseguire più passaggi in sequenza e non in parallelo?
Frank Escobar,

Risposte:


22

Gestito per risolverlo con il seguente codice:

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

Consulta anche gli esempi ufficiali di pipeline - jenkins.io/doc/pipeline/examples/#parallel-multiple-nodes
phedoreanu

@phedoreanu sto usando una pipeline dichiarativa ...
thclpr

@phedoreanu Ho rifiutato la tua modifica, la modifica del codice dovrebbe avere buone ragioni, il tuo commento non mi è sufficiente per consentire una modifica di questo tipo su una risposta che fosse una soluzione autonoma. Penso che avresti dovuto commentare per discutere della questione con l'autore della risposta prima di fare questa modifica.
Tensibai,

@phedoreanu Penso che tu abbia un lavoro derivato migliore, quindi scrivi la tua risposta e spiega perché è meglio (nella gestione degli errori, modelli, ecc.).
Tensibai,

Ciao, ho capito lo stesso dopo alcuni tentativi falliti. Il mio unico problema in questo momento è che se metto due sezioni dello stage {..} all'interno di un nodo per alcuni motivi, lo schema del flusso di lavoro e Blu Ocean si confondono. Ad esempio, nella tabella delle fasi del flusso di lavoro ottengo NaNy NaNd e in Blue Ocean ottengo solo la prima fase.
Giuseppe,

6

Funziona anche se vuoi rimanere nello Declarative Pipelinespazio

// 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 si desidera allocare ciascuna attività parallela a diversi nodi Jenkins, semplicemente avvolgere le azioni in un node {}blocco, in questo modo: tests[f] = { node { echo f.toString() } }
primetheus

1

È molto più facile usare Pipeline con script per farlo poiché puoi usare Groovy arbitrario, ma dovresti comunque essere in grado di farlo con Pipeline dichiarative usando il findFilespassaggio.


1

Tenere presente che i passaggi dinamici di compilazione potrebbero causare alcuni problemi in alcuni passaggi di creazione, ad esempio quando si chiama un altro lavoro:

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
                }
            }
        }       
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.