วิธีการบรรลุการกระทำขนานแบบไดนามิกอย่างเหมาะสมกับท่อส่งประกาศ


21

ปัจจุบันฉันจะต้องมีการใช้งานที่ต้องค้นหาไฟล์ทั้งหมดในไดเรกทอรีและเริ่มงานแบบขนานสำหรับทุกไฟล์ที่พบ

เป็นไปได้ไหมที่จะใช้สิ่งนี้ได้โดยใช้ท่อส่ง

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

ฉันจะทำอย่างไรถ้าฉันต้องการเรียกใช้หลาย ๆ ขั้นตอนตามลำดับและไม่ขนานกัน?
Frank Escobar

แน่นอนว่าด้วยวิธีนี้คุณจะไม่สามารถสร้างงานแบบขนานตัวอย่างเช่นขึ้นอยู่กับไฟล์บางไฟล์ในที่เก็บ
Raúl Salinas-Monteagudo

คำตอบ:


22

จัดการเพื่อแก้ปัญหาด้วยรหัสต่อไปนี้:

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 ฉันได้ปฏิเสธการแก้ไขของคุณรหัสการแก้ไขควรมีเหตุผลที่ดีความคิดเห็นของคุณไม่เพียงพอสำหรับฉันที่จะอนุญาตให้แก้ไขประเภทนี้ในคำตอบซึ่งเป็นวิธีแก้ปัญหาด้วยตนเอง ฉันคิดว่าคุณควรแสดงความคิดเห็นเพื่อหารือเกี่ยวกับเรื่องนี้กับผู้เขียนคำตอบก่อนทำการแก้ไขนี้
Tensibai

@phedoreanu ฉันคิดว่าคุณมีงานต่อเนื่องที่ดีกว่าโปรดเขียนคำตอบของคุณเองและอธิบายว่าทำไมจึงดีกว่า (ในการจัดการข้อผิดพลาดแม่แบบและอื่น ๆ ) แทน
Tensibai

สวัสดีฉันคิดออกเหมือนกันหลังจากความพยายามที่ล้มเหลวไม่กี่ครั้ง ปัญหาเดียวของฉันในตอนนี้คือถ้าฉันใส่ส่วนที่สองของสเตจ .. ในโหนดด้วยเหตุผลบางอย่างแผนภูมิลำดับขั้นของเวิร์กโฟลว์และ Blu Ocean จะสับสน ตัวอย่างเช่นในแผนภูมิลำดับขั้นของเวิร์กโฟลว์ฉันได้รับ NaNy NaNd และใน Blue Ocean ฉันได้รับเฉพาะด่านแรกเท่านั้น
Giuseppe

6

สิ่งนี้ยังใช้งานได้หากคุณต้องการอยู่ใน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
                }
            }
        }       
    }
}

หากคุณต้องการจัดสรรแต่ละงานแบบขนานไปยังโหนด Jenkins ที่แตกต่างกันเพียงแค่ห่อการกระทำในnode {}บล็อกเช่นนี้: tests[f] = { node { echo f.toString() } }
primetheus

1

มันง่ายกว่ามากที่จะใช้ Pipelines แบบสคริปต์เพื่อทำสิ่งนี้เนื่องจากคุณสามารถใช้ Groovy ตามอำเภอใจ แต่คุณควรจะสามารถทำสิ่งนี้กับ Pipelines ที่ประกาศได้โดยใช้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
                }
            }
        }       
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.