Как реализовать параметр повтора для неудачных этапов в конвейерах Jenkins?
У меня есть Jenkinsfile с несколькими этапами, и один из них - фактически другое задание (развертывание), которое в некоторых случаях может завершиться сбоем.
Я знаю, что могу делать запросы, используя Jenkinsfile, но я не знаю, как реализовать механизм повторных попыток для этой работы.
Я хочу иметь возможность щелкнуть по неудачной стадии и выбрать повторную попытку.
3 ответа
Вы должны быть в состоянии объединить повторные попытки + ввод, чтобы сделать это Что-то подобное
stage('deploy-test') {
try {
build 'yourJob'
} catch(error) {
echo "First build failed, let's retry if accepted"
retry(2) {
input "Retry the job ?"
build 'yourJob'
}
}
}
Вы также можете использовать тайм-аут для ввода, если вы хотите, чтобы он закончился, если никто не проверяет. Есть также waitUntil, который может быть полезен, но я еще не использовал его
Редактировать: WaitUntil кажется определенно лучшим, вы должны поиграть с ним немного, но что-то вроде этого чище:
stage('deploy-test') {
waitUntil {
try {
build 'yourJob'
} catch(error) {
input "Retry the job ?"
false
}
}
}
Между прочим, здесь есть все шаги, описанные здесь: https://jenkins.io/doc/pipeline/steps
Этот с хорошим постепенным ожиданием
stage('deploy-test') {
def retryAttempt = 0
retry(2) {
if (retryAttempt > 0) {
sleep(1000 * 2 + 2000 * retryAttempt)
}
retryAttempt = retryAttempt + 1
input "Retry the job ?"
build 'yourJob'
}
}
Этот смысл (не мой) был одним из лучших вариантов, которые я нашел, пытаясь реализовать эту функцию тоже. https://gist.github.com/beercan1989/b66b7643b48434f5bdf7e1c87094acb9
Изменил его на метод в разделяемой библиотеке, который только что повторил или прервал для моих нужд. Также добавлено максимальное количество повторов и переменная тайм-аута, чтобы мы могли изменить ее в зависимости от задания или этапа, который в этом нуждается.
package com.foo.bar.jenkins
def class PipelineHelper {
def steps
PipelineHelper(steps) {
this.steps = steps
}
void retryOrAbort(final Closure<?> action, int maxAttempts, int timeoutSeconds, final int count = 0) {
steps.echo "Trying action, attempt count is: ${count}"
try {
action.call();
} catch (final exception) {
steps.echo "${exception.toString()}"
steps.timeout(time: timeoutSeconds, unit: 'SECONDS') {
def userChoice = false
try {
userChoice = steps.input(message: 'Retry?', ok: 'Ok', parameters: [
[$class: 'BooleanParameterDefinition', defaultValue: true, description: '', name: 'Check to retry from failed stage']])
} catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) {
userChoice = false
}
if (userChoice) {
if (count <= maxAttempts) {
steps.echo "Retrying from failed stage."
return retryOrAbort(action, maxAttempts, timeoutMinutes, count + 1)
} else {
steps.echo "Max attempts reached. Will not retry."
throw exception
}
} else {
steps.echo 'Aborting'
throw exception;
}
}
}
}
}
Пример использования с максимум 2 повторными попытками, ожидающими ввода 60 секунд.
def pipelineHelper = new PipelineHelper(this)
stage ('Retry Example'){
pipelineHelper.retryOrAbort({
node{
echo 'Here is an example'
throw new RuntimeException('This example will fail.')
}
}, 2, 60)
}
Просто не забудьте поместить узлы внутри замыкания, чтобы ожидание ввода не блокировало исполнителя.
Если у вас есть платная jenkins Enterprise Cloudbees, у нее есть плагин Checkpoint, который может лучше справиться с этим, но его выпуск с открытым исходным кодом Jenkins не планируется ( JENKINS-33846).