web-dev-qa-db-ja.com

トリガーされたすべての並列ジョブをパイプラインジョブで待機させる方法

以下のように、ジェンキンスのパイプラインジョブの一部としてGroovyスクリプトを作成しました。

node {
    stage('Testing') {
        build job: 'Test', parameters: [string(name: 'Name', value: 'Foo1')], quietPeriod: 2, wait: false
        build job: 'Test', parameters: [string(name: 'Name', value: 'Bar1')], quietPeriod: 2, wait: false
        build job: 'Test', parameters: [string(name: 'Name', value: 'Baz1')], quietPeriod: 2, wait: false
        build job: 'Test', parameters: [string(name: 'Name', value: 'Foo2')], quietPeriod: 2, wait: false
        build job: 'Test', parameters: [string(name: 'Name', value: 'Bar2')], quietPeriod: 2, wait: false
        build job: 'Test', parameters: [string(name: 'Name', value: 'Baz2')], quietPeriod: 2, wait: false
    }
}

waitフラグがfalseに設定されているため、他の複数のフリースタイルジョブを並行して実行します。ただし、すべてのジョブが終了したら、呼び出し元のジョブが終了するようにします。現在、Pipelineジョブはすべてのジョブをトリガーし、数秒後にそれを終了します。これは、合計時間を追跡できず、トリガーされたすべてのジョブを一度にキャンセルできないためです。

並列のすべてのジョブが完了したときに終了するパイプラインジョブの上記のスクリプトを修正するにはどうすればよいですか?

ビルドジョブをwaitUntil {}ブロックでラップしようとしましたが、機能しませんでした。

15
kenorb

パイプラインparallel式を使用する必要があります。これは、生成されたすべてのジョブ/サブタスクが完了するまで待機します。

stage('testing') {
    def branches = [:]

    for(i = 0; i < params.size(); i += 1) {
        def param = params[i]

        branches["Test${i}"] = {
            build job: 'Test', parameters: [string(name: 'Name', value: param)], quietPeriod: 2
        }
    }
    parallel branches
}

jenkins.io のパイプラインドキュメントでさらにいくつかの例を見つけることができます。

25
agg3l

同じ問題にぶつかり、有効な解決策を見つけてください。 foreachを使用してください。

stage('testing') {
    def jobs = [:]

    [1,2,3,4,5].each{
        i -> jobs["Test${i}"] = {
            build job: 'Test', 
            parameters: [string(name: 'theparam', value: "${i}")],
            quietPeriod: 2
        }
    }
    parallel jobs
}
5
hEngi

ただし、 @ agg3lの例 は複数のジョブで機能しません。

Map jobResults = [:]

Boolean failedJobs = false
def buildJobWithParams(def jobs_list, Map results) {
  def branches = [:]    
  for(job in jobs_list)
  {
    print job
    branches["Test-${job}"] = {
       def jobBuild = build job: job, propagate: false
       def jobResult = jobBuild.getResult()
       echo "Build of '${job}' returned result: ${jobResult}"
       results[job] = jobResult
    }
  }    
  return branches
}

stage('Run integration tests') {
      steps {
            def job_branch = buildJobWithParams(item_list, jobResults)
            print job_branch
            parallel job_branch
          }
}

item_listには複数のジョブがありますが、最後のジョブのみを複数回実行します。

5
GOGS K

これは私のために動作します。 3つのジョブをトリガーします。それらが終了するのを待ちます。余分な「->」に注意して、グルーヴィーなクロージャーを指定してください。各ループに1つ->、平行線に1つあります。これは、並列セクションの実行時に値が評価されることを意味します。

def jobsString = "job1,job2,job3"
ArrayList jobsList = jobsString.split('\\,')

def parallelJobs2Run = [:]
jobsList.each { job ->
    echo "Going to parallel for job ${job}"
    parallelJobs2Run["${job}"] = { ->
        echo "Calling job ${job}"
        jobResults=build job: "${pathJenkinsFolder}${job}",
        parameters: [
            string(name: 'param1', value: "${value1}"),
            string(name: 'param2', value: "${value2}")
        ],
        propagate: true,
        wait: true

        // List of values: https://stackoverflow.com/questions/46262862/how-to-i-get-the-url-of-build-triggered-with-build-step-on-jenkins
        buildNumber = ${jobResults.number}
        echo "${job} Build number |${buildNumber}| result: |${jobResults.result}|"
        echo "See details on: |${jobResults.absoluteUrl}|"
    }
};
parallel parallelJobs2Run
4
hagits