선언적 파이프 라인으로 동적 병렬 작업을 올바르게 달성하는 방법은 무엇입니까?


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


@phedoreanu 저는 선언적인 파이프 라인을 사용하고 있습니다.
thclpr

@phedoreanu 나는 당신의 편집을 거부했습니다. 편집 코드에는 좋은 이유가 있어야합니다. 귀하의 의견으로는 자체 솔루션 인 답변 에서이 종류의 편집을 허용하기에 충분하지 않습니다. 이 편집을 수행하기 전에 답변 작성자와 문제를 논의하기 위해 의견을 말해야한다고 생각합니다.
Tensibai

@phedoreanu 나는 당신이 더 나은 파생물을 가지고 있다고 생각하고, 자신의 답을 쓰고 왜 (오류 처리, 템플릿 등) 더 나은지 설명하십시오.
Tensibai

안녕, 나는 몇 번의 실패한 시도 후에도 같은 것을 알아 냈습니다. 지금 유일한 문제는 노드에 두 개의 stage {..} 섹션을두면 워크 플로 스테이지 차트와 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

임의의 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
                }
            }
        }       
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.