Что такое пайплайн и зачем он нужен

Из чего состоит и какие свойства отличают полезный от формального.

Определение

Пайплайн — автоматическая последовательность шагов, запускаемая изменением в репозитории. Типичный набор:

  1. Проверка — линтер, типы, тесты.
  2. Сборка — артефакт или образ.
  3. Публикация — в реестр.
  4. Выкат — в окружение.

Смысл не в автоматизации ради автоматизации, а в том, что проверки выполняются одинаково и всегда, независимо от того, кто вносит изменение и насколько он торопится.

Свойства, которые отличают полезный пайплайн

Быстрый. Если проверки идут сорок минут, разработчик переключается на другую задачу и возвращается к результату через час, потеряв контекст. Полезное правило — держать основную проверку в пределах десяти минут, вынося долгое в отдельные, необязательные для мержа шаги.

Детерминированный. Один и тот же коммит даёт один и тот же результат. Главный враг — «плавающие» зависимости: npm install вместо npm ci, теги вместо хешей, latest вместо версии.

Честный. Красная сборка означает проблему, зелёная — её отсутствие. Пайплайн, который падает через раз по случайным причинам, хуже отсутствующего: люди привыкают перезапускать не глядя, и настоящая поломка проходит незамеченной.

Порядок шагов

Дешёвые и часто срабатывающие проверки — первыми:

линтер → типы → юнит-тесты → сборка → интеграционные тесты → выкат

Незачем тратить пять минут на сборку образа, чтобы затем упасть на опечатке, которую линтер нашёл бы за десять секунд.

Кеш и его цена

Кеш ускоряет, но именно он чаще всего ломает детерминированность: сборка проходит на закешированных зависимостях, которых нет в чистом окружении. Разумный компромисс — кешировать только то, что однозначно определяется lock-файлом, и включать хеш этого файла в ключ кеша.

Секреты

Секреты не хранятся в репозитории и не передаются как аргументы сборки: ARG остаётся в истории образа, и docker history его покажет. Правильные места — механизм секретов вашего CI, а в рантайме — переменные окружения или смонтированный файл.

Что запускать на каждый коммит

Полный выкат на каждое изменение в ветке обычно не нужен и лишь занимает раннеры. Разумное разделение: