Я определяю декларативный конвейер Jenkins и с трудом настраиваю шаг, чтобы он не выполнялся, если две строки равны.
Я пробовал несколько вещей, но сравнение строк не работает.
Вот мое текущее состояние:
stages {
stage('Check if image has changed') {
steps {
script {
OLD_DIGEST = sh(returnStdout: true, script: "podman manifest inspect registry/myimage:11 2>/dev/null | jq .config.digest").trim()
NEW_DIGEST = sh(returnStdout: true, script: "podman inspect --format='sha256:{{.Id}}' myimage:11-tmp").trim()
}
sh "echo previous digest:${OLD_DIGEST}, new digest:${NEW_DIGEST}"
}
}
stage('Release') {
when {
allOf {
expression { env.RELEASE != null && env.RELEASE == "true" }
expression { env.OLD_DIGEST != env.NEW_DIGEST }
}
}
steps {
sh "echo Releasing image..."
sh "podman image push myimage:11-tmp registry/myimage:11.${DATE_TIME}"
sh "podman image push myimage:11-tmp registry/myimage:11"
}
}
}
В частности, проблемы заключаются в when
:
allOf {
expression { env.RELEASE != null && env.RELEASE == "true" }
expression { env.OLD_DIGEST != env.NEW_DIGEST }
}
Первое выражение работает нормально, но я не могу заставить второе работать: даже если OLD_DIGEST
и NEW_DIGEST
разные, шаг пропускается.
Пример вывода:
previous digest:sha256:736fd651afdffad2ee48a55a3fbab8de85552f183602d5bfedf0e74f90690e32, new digest:sha256:9003077f080f905d9b1a960b7cf933f04756df9560663196b65425beaf21203d
...
Stage "Release" skipped due to when conditional
Я также пробовал expression { OLD_DIGEST != NEW_DIGEST }
(удаление env.
), но теперь результат противоположный: даже если обе строки равны, шаг НЕ пропускается.
Выход в этом случае:
previous digest:sha256:8d966d43262b818073ea23127dedb61a43963a7fafc5cffdca85141bb4aada57, new digest:sha256:8d966d43262b818073ea23127dedb61a43963a7fafc5cffdca85141bb4aada57
...
Releasing image...
Мне интересно, заключается ли проблема в expression
или allOf
в какой-то момент.
@NoamHelmer да, почти уверен, что первое условие работает нормально, как и в случае с expression { OLD_DIGEST != NEW_DIGEST }
Я всегда вхожу в шаг. Даже если OLD_DIGEST
равно NEW_DIGEST
в этом случае не должно.
Я обновил пост с выходом в случае expression { OLD_DIGEST != NEW_DIGEST }
@NoamHelmer имеет правильное решение в комментарии, поскольку ни одна из них не является переменной среды конвейера и, следовательно, не назначается членам в объекте env
. Что касается другой проблемы: это похоже на синтаксис Groovy в expression
и, следовательно, синтаксически требуется явное return
: jenkins.io/doc/book/pipeline/syntax/#when.
Согласно моим тестам в последней версии 2023 года переменные env инициализируются на любом этапе, поэтому предыдущие значения переопределяются.
Примечание. Внутри when переменные env имеют значения по умолчанию, игнорируя ожидаемые значения, заданные на предыдущем этапе. После этого на шагах есть ожидаемые значения (обновленные на предыдущем этапе)
Если вы используете глобальные переменные вместо переменных env, это работает. Я имитирую ваш вывод podman с помощью эха.
def OLD_DIGEST
def NEW_DIGEST
pipeline {
agent any
environment {
RELEASE = "true"
}
stages {
stage('Check if image has changed') {
steps {
script {
OLD_DIGEST = sh(returnStdout: true, script: "echo '1'").trim()
NEW_DIGEST = sh(returnStdout: true, script: "echo '1'").trim()
}
sh "echo previous digest:${OLD_DIGEST}, new digest:${NEW_DIGEST}"
}
}
stage('Release') {
when {
allOf {
expression { env.RELEASE != null && env.RELEASE == "true" }
expression { OLD_DIGEST != NEW_DIGEST }
}
}
steps {
sh "echo Releasing image..."
}
}
}
}
когда OLD_DIGEST = 1 && NEW_DIGEST = 1 этап пропускается
если есть разные, этап выполняется
Итак, ваш ответ работает в вашем случае, но как только я использую свои команды оболочки, он больше не работает. Я предполагаю, что где-то в моих строках есть специальный символ. Буду устранять неполадки еще.
Глупая ошибка с моей стороны, одна из строк на самом деле была "xxx"
, когда другая была xxx
(без кавычек). Каким-то образом вывод Дженкинса не отображает кавычки.
Это работает и без def
.
Основной причиной моей проблемы был вывод двух моих строк для сравнения, которые действительно отличались: одна была "xxx"
, а другая была xxx
, но вывод Дженкинса не показывает двойные кавычки.
Правильное сравнение Дженкинса, как указано в комментариях, это expression { OLD_DIGEST != NEW_DIGEST }
(без env.
).
expression { OLD_DIGEST != NEW_DIGEST }
— правильный подход, префикс.env
актуален, если вы также использовали его для определения:env. OLD_DIGEST = sh(...
. Вы уверены, что ваше второе условие наRELEASE
работает должным образом? поскольку оба они должны быть оценены как true, чтобы этап запустился.