Что должен проверять ваш пайплайн перед деплоем

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

Пайплайн сказал, что всё в порядке. Но это было не так.

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

Сборка должна проходить в первую очередь

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

Этот гейт всегда должен быть первым шагом. Он быстрый, дешевый и отсеивает изменения, которые даже не готовы к тестированию. Если сборка падает, пайплайн останавливается. Разработчик получает мгновенную обратную связь и может исправить проблему до того, как она затронет кого-то еще.

Юнит-тесты проверяют поведение, а не реализацию

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

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

Некоторые команды пишут юнит-тесты, жестко привязанные к деталям реализации: тестируют приватные методы, тестируют каждый класс отдельно, мокают внутренние слои и ломаются при каждом рефакторинге. Такие тесты создают шум и замедляют доставку. Мокайте внешние зависимости когда нужно, но позволяйте внутреннему поведению проходить по пути, который приложение реально использует. Гейт полезен только если тесты надежны. Если ваши юнит-тесты часто падают по нефункциональным причинам, разработчики начнут их игнорировать, и гейт потеряет ценность.

Интеграционные тесты ловят проблемы соединения

Юнит-тесты могут работать без внешних зависимостей. Интеграционные — нет. Они проверяют, что ваша система действительно может общаться с внешним миром: реальной базой данных, очередью сообщений, сторонним API.

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

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

Сканирование безопасности должно работать автоматически

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

  • Есть ли зависимости с известными уязвимостями?
  • Не содержит ли код случайно учетные данные или API-ключи?
  • Есть ли паттерны, которые могут быть эксплуатированы, например SQL-инъекции или небезопасная десериализация?

Некоторые команды запускают статический анализ исходного кода. Другие — динамическое сканирование работающего приложения. Оба подхода ловят разные проблемы. Важно, что пайплайн проверяет безопасность автоматически, каждый раз.

Если сканирование безопасности падает, пайплайн останавливается. Разработчик получает отчет с указанием, что именно не так. Никакого ручного одобрения не нужно, никакого ожидания проверки командой безопасности. Гейт сам блокирует изменение.

Соответствие политикам поддерживает согласованность

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

Распространенные проверки политик:

  • Прошел ли код код-ревью?
  • Соответствует ли имя ветки соглашению (например, feature/ или fix/)?
  • Не слишком ли большой пул-реквест? Некоторые команды ограничивают изменения определенным количеством строк или файлов.
  • Все ли зависимости поступают из одобренного реестра?

Эти проверки административные, но они важны. Они предотвращают ситуации, когда кто-то сливает 2000 строк изменений без ревью, или когда подтягивается зависимость из ненадежного источника. Пайплайн автоматически применяет правила, так что никому не нужно их помнить.

Когда автоматизации недостаточно

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

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

Ключевой принцип: автоматизируйте то, что можно измерить объективно, и оставьте субъективные решения людям. Если проверку можно выразить как правило, которое всегда применимо — автоматизируйте. Если она требует контекста, опыта или компромиссов — оставьте ручной.

Практический чеклист для гейтов вашего пайплайна

Если вы настраиваете или пересматриваете гейты своего пайплайна, вот краткий чеклист для рассмотрения:

Следующая диаграмма показывает, как эти гейты работают вместе в последовательности:

flowchart TD A([Start]) --> B{Build Passes?} B -- Yes --> C{Unit Tests Pass?} B -- No --> X[Stop and Notify] C -- Yes --> D{Integration Tests Pass?} C -- No --> X D -- Yes --> E{Security Scans Pass?} D -- No --> X E -- Yes --> F{Policy Compliance Pass?} E -- No --> X F -- Yes --> G{Manual Review Needed?} F -- No --> X G -- No --> H([Deploy]) G -- Yes --> I{Review Approved?} I -- Yes --> H I -- No --> X
  • Гейт сборки: Останавливается ли пайплайн, если код не компилируется или не создает артефакт?
  • Гейт юнит-тестов: Проверяют ли тесты осмысленное поведение через релевантные точки входа, а не внутреннюю реализацию?
  • Гейт интеграционных тестов: Тестирует ли пайплайн против реальных зависимостей (база данных, очередь, внешний сервис)?
  • Гейт сканирования безопасности: Сканируются ли зависимости на уязвимости? Проверяется ли код на секреты и рискованные паттерны?
  • Гейт соответствия политикам: Применяются ли автоматически правила вроде код-ревью, именования веток и источников зависимостей?

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

Смысл гейта — останавливать проблемы, а не замедлять вас

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

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