如何使Pipeline作业等待所有触发的并行作业?

ken*_*orb 17 groovy jenkins jenkins-pipeline

我将Groovy脚本作为Jenkins管道工作的一部分,如下所示:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

由于wait标志设置为,因此并行执行多个其他自由式作业false.但是我希望所有工作完成后调用者工作完成.目前,Pipeline作业会触发所有作业并在几秒钟后自行完成,这不是我想要的,因为我无法跟踪总时间,并且我无法一次性取消所有已触发的作业.

当所有并行作业完成后,如何更正管道作业的上述脚本?

我试图在waitUntil {}块中包装构建作业,但它不起作用.

agg*_*g3l 25

您应该使用管道并行表达式,它将等待所有生成的作业/子任务完成:

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
}
Run Code Online (Sandbox Code Playgroud)

您可以在jenkins.io的管道文档中找到更多示例


hEn*_*ngi 6

只是遇到了同样的问题,并找到了可行的解决方案。只需使用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
}
Run Code Online (Sandbox Code Playgroud)


小智 5

但是,@ 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
          }
}
Run Code Online (Sandbox Code Playgroud)

item_list作业有1个以上,但是它将仅执行最后一个作业多次。

  • 在我看来,*job* 变量是在 _for_ 闭包之外创建的,所以当并行执行时,它总是取最后一个值。尝试在 for 中创建一个新的变量,例如:` for(job in jobs_list) { def myJob = job print myJob branch["Test-${myJob}"] = { def jobBuild = build myJob: myJob,propagate: false def jobResult = jobBuild.getResult() echo "Build of '${myJob}' 返回结果:${jobResult}" results[myJob] = jobResult } } ` (2认同)

hag*_*its 5

这对我有用。触发 3 个工作。等他们说完。注意额外的“->”来指定常规的闭包。我在每个循环上有一个 -> ,在平行线上有一个。这意味着将在运行并行部分时评估该值。

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: /sf/ask/3238400371/
        buildNumber = ${jobResults.number}
        echo "${job} Build number |${buildNumber}| result: |${jobResults.result}|"
        echo "See details on: |${jobResults.absoluteUrl}|"
    }
};
parallel parallelJobs2Run
Run Code Online (Sandbox Code Playgroud)