Wie erreicht man mit einer deklarativen Pipeline eine dynamische Parallelität?


18

Derzeit benötige ich eine Implementierung, die alle Dateien in einem Verzeichnis finden und für jede gefundene Datei eine parallele Aufgabe starten muss.

Ist dies mit deklarativen Pipelines möglich?

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

Wie kann ich vorgehen, wenn ich mehrere Schritte hintereinander und nicht parallel ausführen möchte?
Frank Escobar

Antworten:


21

Konnte es mit dem folgenden Code lösen:

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


@phedoreanu Ich verwende deklarative Pipeline ...
thclpr

@phedoreanu Ich habe Ihre Bearbeitung abgelehnt. Der Bearbeitungscode sollte gute Gründe haben. Ihr Kommentar reicht mir nicht aus, um eine Bearbeitung dieser Art für eine Antwort zuzulassen, die eine Selbstlösung war. Ich denke, Sie hätten kommentieren sollen, um die Angelegenheit mit dem Antwortautor zu besprechen, bevor Sie diese Bearbeitung durchführen.
Tensibai

@phedoreanu Ich denke du hast eine bessere abgeleitete Arbeit, dann schreibe bitte deine eigene Antwort und erkläre, warum es besser ist (in Fehlerbehandlung, Vorlagen, etc.).
Tensibai

Hallo, das habe ich auch nach einigen Fehlversuchen herausgefunden. Mein einziges Problem im Moment ist, dass, wenn ich aus bestimmten Gründen zwei Abschnitte {..} innerhalb eines Knotens platziere, das Workflow-Stage-Chart und Blu Ocean verwirrt werden. Zum Beispiel in der Workflow-Tabelle bekomme ich NaNy NaNd und in Blue Ocean bekomme ich nur die erste Stufe.
Giuseppe

5

Dies funktioniert auch, wenn Sie im Declarative PipelineRaum bleiben möchten

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

Wenn Sie jede parallele Aufgabe verschiedenen Jenkins-Knoten zuweisen möchten, schließen Sie die Aktionen einfach node {}wie tests[f] = { node { echo f.toString() } }
folgt

1

Es ist viel einfacher, skriptbasierte Pipelines zu verwenden, da Sie beliebiges Groovy verwenden können. Sie sollten jedoch weiterhin in der Lage sein, dies mit deklarativen Pipelines zu tun, die den findFilesSchritt verwenden.


0

Beachten Sie, dass dynamische Erstellungsschritte in einigen Erstellungsschritten zu Problemen führen können, z. B. wenn Sie einen anderen Job aufrufen:

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
                }
            }
        }       
    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.