Зелёный Jenkins ещё ничего не значит: 12 ошибок, которые не ломают сборку

kmoseenk 47 минут назад Зелёный Jenkins ещё ничего не значит: 12 ошибок, которые не ломают сборку Сложный 8 мин 1.4K Блог компании OTUS Системное администрирование * DevOps * Аналитика Перевод Автор оригинала: Muhammad...
<5 — 2026'da uzaya kaç SpaceX Starship fırlatması ulaşacak?
Значимый прорыв формирует отрасль ИИ: kmoseenk 47 минут назад Зелёный Jenkins ещё ничего не значит: 12 ошибок, которые не ломают сборку Сложный 8 мин 1. 4K Блог компании OTUS Системное администрирование * DevOps * Аналитика Перевод Автор оригинала: Muhammad Ibtisam Ни на одно из этих мест не указал ни один инструмент. До каждого исправления пайплайн был зеленым и после оставался таким же.
Изменилось другое: то, что на самом деле означал этот зеленый статус. График покрытия принимал сбои инфраструктуры за регрессии в тестах, сообщение об успешном завершении утверждало, что образы опубликованы, хотя ничего не было отправлено в репозиторий, а тег при определенных условиях мог отправить в деплой четырехсимвольную строку null, если бы один из этапов хоть раз оказался пропущен. Исправления пронумерованы прямо в Java Jenkinsfile как FIX #1–FIX #13.
Технические детали
Номера #11 нет: во время ревью это исправление объединили с другим изменением. Еще шесть исправлений с номерами R4#n находятся в workflow GitHub Actions. Я оставил нумерацию прямо в файлах, а не вынес ее в changelog, потому что смысл каждого исправления понятен только рядом со строкой, которую оно защищает.
Все эти проблемы можно разделить на четыре вида лжи. Ложь № 1: интерполяция, которая подставляет nullGroovy интерполирует ${VAR} внутри блока """... """ на этапе разбора.
А shell внутри этого блока подставляет $VAR уже во время выполнения. Выглядят эти конструкции почти одинаково, но срабатывают в совершенно разные моменты. Этап передачи в CD записывает тег образа в репозиторий деплоя.
Отраслевые последствия
В начале стоит защитная проверка:if ; then echo '❌ IMAGE_TAG is empty — aborting CD repo update' exit 1 fiОбратный слеш здесь важнее всего остального в строке. \\${IMAGE_TAG} проходит через Groovy без изменений и доходит до shell как ${IMAGE_TAG}, а shell вычисляет эту переменную уже при выполнении этапа. Если убрать экранирование и написать:${IMAGE_TAG}Groovy подставит значение еще при разборе пайплайна, задолго до выполнения этапа.
Если этап Versioning к этому моменту не выполнялся, env. IMAGE_TAG содержит null, а Groovy при преобразовании в строку превращает его в четыре буквальных символа null. Тогда проверка становится такой:if ; thenи условие оказывается ложным, потому что "null" — вполне себе непустая строка.
Проверка проходит, в манифест записывается IMAGE_TAG=null, изменение коммитится, а инструмент деплоя получает команду скачать образ с тегом null. То же правило экранирования действует для:\${GIT_USER} \${GIT_TOKEN}которые withCredentials передает в окружение shell. В области видимости Groovy этих переменных вообще нет, поэтому без экранирования вместо них подставится пустая строка, и клонирование пойдет без учетных данных.
Событие, по словам экспертов, усилит конкуренцию в сфере ИИ.






