Как заставить работу 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