Как заставить работу Pipeline ждать всех запущенных параллельных заданий?

У меня Groovy script как часть задания Pipeline в 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
    }
}

который выполняет несколько других заданий фристайла параллельно, из-за того, что флаг wait установлен на false. Однако я хотел бы, чтобы задание вызывающего абонента заканчивалось, когда все задания были завершены. В настоящее время задание Pipeline запускает все задания и заканчивает его через несколько секунд, что не то, что я хочу, потому что я не могу отслеживать общее время, и у меня нет возможности отменить все запущенные задания за один раз.

Как я могу исправить выше script для завершения задания Pipeline, когда все параллельные задания завершены?

Я попытался завершить задания сборки в блоке waitUntil {}, но это не сработало.

Ответ 1

Вы должны использовать параллельное выражение конвейера, которое будет ждать завершения всех заданий/подзадач:

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

Ответ 2

Просто столкнитесь с той же проблемой и найдите рабочее решение. Просто используйте 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
}

Ответ 3

Однако @agg3l example не работает с несколькими заданиями.

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 имеет более одного задания, однако он будет выполнять только последнее задание несколько раз.

Ответ 4

Это работает для меня. Триггеры 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: https://stackoverflow.com/info/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