Стадии конвейера

Что это такое

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

Почему это важно

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

Ключевые идеи

Каждая стадия отвечает на один вопрос

Компиляция спрашивает «синтаксически и структурно ли это верно»; тесты — «работает ли это так, как надо»; сборка — «можно ли это упаковать»; развёртывание — «запускается ли это здесь». Смешение вопросов в одной стадии делает сообщение о провале неоднозначным и заставляет перезапускать всё, когда меняется что-то одно.

check -> test -> build artifact -> deploy to staging -> deploy to production
секунды  минуты    минуты          минуты              при подтверждении

Соберите один раз и продвигайте артефакт

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

Время обратной связи задаёт темп всей команды

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

Основная ветка должна оставаться зелёной

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

Развёртывание — отдельное решение, а не продолжение тестирования

Сборка и тестирование могут запускаться автоматически на каждое изменение; выпуск в продакшен обычно не должен — или как минимум должен требовать явного подтверждения. Разделение на отдельные стадии позволяет одному конвейеру делать и то и другое, не связывая решение с механикой.

Секреты принадлежат конвейеру, а не логу

Учётные данные поставляет хранилище секретов конвейера, платформа маскирует их там, где это поддерживается, а область действия ограничена стадиями, которым они нужны. Токен, который тест напечатал в логе, — утёкший токен, и его найдут.

Практика

Упорядочите конвейер по скорости обратной связи

Возьмите проект с медленным набором тестов и быстрой проверкой компиляции. Расставьте стадии так, чтобы самая быстрая проверка шла первой, затем разделите набор так, чтобы быстрая часть шла на каждое изменение, а медленная — перед развёртыванием.

Готово, когда: изменение, не проходящее компиляцию, сообщает о провале меньше чем за минуту, а медленный набор больше не блокирует быстрый путь.

Продвиньте один артефакт через два окружения

Соберите артефакт один раз, запишите его версию и разверните именно эту версию сначала в staging, затем в продакшен.

Готово, когда: идентификатор версии одинаков в обоих окружениях и ни одно развёртывание ничего не пересобирало.

Частые ошибки

  • Запуск медленного набора на каждый коммит — обратная связь приходит слишком поздно, чтобы что-то менять; исправить: разделите быстрые и медленные тесты и запускайте медленные по расписанию.
  • Пересборка для каждого окружения — протестирован не тот артефакт, который выпущен; исправить: собирайте один раз и продвигайте по версии.
  • Разрешение слияний в падающую основную ветку — работа всех блокируется, а доверие к конвейеру умирает; исправить: сделайте исправление основной ветки первым приоритетом.
  • Печать секретов в логи сборки — учётные данные открыты каждому, кто может прочитать лог; исправить: используйте маскируемые секреты и ограничивайте их область.
  • Связывание решения о выпуске с прогоном тестов — прошедшая сборка считается разрешением выпускать; исправить: держите развёртывание отдельной, осознанной стадией.

Что читать дальше

  • CI/CD (06-cloud-devops/08-ci-cd) — практика, которую реализуют эти стадии, поэтому прочитайте сначала её.
  • Режимы отказа конвейера (06-cloud-devops/08-ci-cd/02-pipeline-failure-modes) — способы, которыми описанный здесь надёжный конвейер перестаёт быть надёжным.