Паттерны пайплайнов: gates, approvals, fan-out
Ручные подтверждения, защищённые окружения, параллельные ветки fan-out/fan-in и условный запуск job.
Когда линейного пайплайна мало
Простой пайплайн идёт сверху вниз одной цепочкой. На реальном проекте этого не хватает: какие-то шаги должны идти параллельно, какие-то требуют человеческого «да», а деплой в прод нельзя пускать с любой ветки. Для этого есть несколько паттернов.
Manual gate: ручное подтверждение
Gate (ворота) останавливает пайплайн и ждёт, пока человек нажмёт кнопку. Типичный случай: до staging катим автоматически, а в прод только после ручного подтверждения.
deploy-prod:
stage: deploy
script:
- ./deploy.sh production
when: manual
allow_failure: false # без этой строки job не блокирует пайплайн
environment:
name: production
when: manual превращает job в кнопку в UI. А вот блокирует ли эта
кнопка пайплайн, зависит от allow_failure, и дефолт тут
контринтуитивный.
У job с when: manual, написанным на верхнем уровне, allow_failure
по умолчанию равен true. GitLab считает такую job необязательной:
пайплайн не останавливается, идёт дальше и красится в зелёный, даже
если кнопку никто не нажал. Получается не гейт, а просто доступное
действие. Классический сюрприз: человек думает, что поставил защиту
перед продом, а пайплайн спокойно завершился успехом мимо неё.
Чтобы это был настоящий гейт, нужно явно поставить
allow_failure: false. Тогда пайплайн встаёт в статус ожидания и
дальше не пойдёт, пока кнопку не нажмут.
Внутри rules: дефолт обратный: там when: manual идёт с
allow_failure: false, то есть блокирует сразу.
deploy-prod:
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual # тут allow_failure по умолчанию false — гейт
Проще не держать это в голове, а писать allow_failure явно в обоих
случаях. Читающему конфиг сразу видно, гейт это или необязательная
кнопка.
Защищённые окружения и approvals
Кнопку нажать может не любой. Environment в GitLab/GitHub связывают с
правами: деплой в production разрешён только мейнтейнерам, и часто нужно
подтверждение второго человека (approval). Так выкат в прод проходит
ревью, как код.
Сюда же относится правило «деплой только из защищённой ветки»: job
деплоя вообще не появляется в пайплайне, если он идёт не из main.
Ровно это и делает условие if: $CI_COMMIT_BRANCH == "main" из примера
выше. Из случайной ветки кнопку не увидит даже мейнтейнер.
Fan-out и fan-in
Fan-out значит разветвить пайплайн на параллельные job, fan-in собрать их обратно. Классика: после сборки одновременно гонять юнит-тесты, линтер и аудит зависимостей, а дальше один общий шаг, который ждёт их все.
Параллельные job не зависят друг от друга и идут разом, поэтому этап
проходит за время самой долгой проверки, а не за их сумму. Шаг package
стартует, только когда все три зелёные.
Условный запуск
Не всё нужно гонять всегда. rules запускают job по условию: только на тег, только при изменении определённых файлов, только в MR.
build-docs:
rules:
- changes:
- docs/** # собирать доки, только если их трогали
Так пайплайн не тратит время на то, что не менялось: правка в docs/ не
запускает пересборку образа приложения, и наоборот.
Что важно запомнить
Manual gate (when: manual) ставит человека на последний контроль перед
продом, не ломая автоматизацию остального. Защищённые окружения и approval
превращают выкат в ревью.
Сам по себе when: manual на верхнем уровне job пайплайн не блокирует:
allow_failure там по умолчанию true, и это просто необязательная
кнопка. Гейт получается с явным allow_failure: false. Внутри rules:
дефолт обратный, поэтому проще писать allow_failure явно везде.
Fan-out разветвляет пайплайн на параллельные независимые job, fan-in собирает их обратно: этап идёт за время самой долгой проверки, а не за сумму.
rules запускают job по условию (ветка, тег, изменённые файлы), чтобы не
гонять лишнее.
В следующем уроке разберём кеш и артефакты: как ускорять сборки и передавать результат между job.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс