← назад к разделу

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

Trunk-based: короткий путь до main

Суть: одна главная ветка (main/trunk), изменения вливаются маленькими PR из короткоживущих веток — день-два, не недели. Большие фичи режутся на последовательность маленьких слияний, незавершённое прячется за feature flags: код в main, функция выключена.

Почему это связано с CI напрямую: интеграционная боль растёт квадратично от времени жизни ветки. Ветка на месяц — это месяц расхождения с main, конфликтное слияние на день и баги «на стыке», которые никто не тестировал. Маленькие частые слияния делают каждую интеграцию тривиальной — собственно, это и есть continuous integration в исходном смысле слова, а не «сервер, гоняющий тесты».

Старый gitflow (develop, release-ветки, hotfix-ветки) имел смысл при редких коробочных релизах; для сервисов с непрерывной доставкой он добавляет церемоний без защиты. Долгоживущие release-ветки остаются законным случаем для поддержки нескольких версий продукта одновременно (библиотеки, on-premise поставки) — то есть не для нашего случая.

Дисциплина PR

Trunk-based держится на скорости прохождения PR, и она — командная метрика:

  • Маленький PR — одна логическая единица: вертикальный срез, фикс, шаг рефакторинга. PR на две тысячи строк не ревьюится — он пролистывается.
  • Ревью — в течение дня. Висящий PR — это блокированный коллега и зреющие конфликты; ревью чужого кода приоритетнее своего нового.
  • Зелёный CI — до ревью. Человек не тратит время на то, что отловит машина (gates, AI-ревью по стандарту); ревьюеру остаётся дизайн и смысл.
  • Squash при слиянии — main читается как лента осмысленных изменений, а не «fix», «fix2», «really fix».

Версионирование: что считать версией

Для непрерывно деплоящихся сервисов честная версия — SHA коммита (+ build-метаданные в /actuator/info): каждый коммит main — потенциальный релиз, человеко-номера ему не нужны. SemVer (major.minor.patch) обязателен там, где есть внешние потребители контракта: библиотеки, публичные API, события с версиями — semver передаёт смысл изменения (breaking/feature/fix), и присваивается он автоматикой из conventional commits, а не человеком по настроению.

Changelog для сервиса — это лента PR-заголовков в main; для библиотек и API — генерируется из тех же conventional commits. Рукописный CHANGELOG.md умирает на третьей неделе.

Релизный цикл: петля целиком

PR → CI gates → merge в main → образ с SHA → авто-деплой staging
→ smoke/верификация → PR с тегом в GitOps-репо → Argo CD катит прод
→ релиз функции — включением флага, когда продукт готов

Каждый шаг автоматический; человеческие решения — два: апрув PR и включение флага (плюс апрув прод-PR в GitOps-репо, если организация требует четырёх глаз). GitOps замыкает петлю: что в git — то в проде, откат — revert, история деплоев — git log.

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

Антипаттерны

АнтипаттернЧем кончаетсяЧто взамен
Ветка фичи на месяцКонфликтное слияние, непротестированные стыкиРезать на маленькие PR + флаги
Develop + release + hotfix ветки для сервисаЦеремонии без защиты, путаница «где правда»Trunk-based; main = правда
PR висит неделюБлокировки, конфликты, демотивацияРевью в течение дня как норма команды
Версия «1.0-final-new2» рукамиНикто не знает, что задеплоеноSHA для сервисов, авто-semver для библиотек
Деплой прод «по согласованию в чате»Невоспроизводимо, недоказуемоGitOps: PR с тегом — единственный путь
Гигантский PR «вся фича сразу»Ревью пролистыванием, баги в продеВертикальные срезы; flags для неготового

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

  • Принципы конвейера — зелёный main и деплой ≠ релиз.
  • CI для Java/Spring — gates, через которые проходит каждый PR.
  • Стратегии релиза — флаги и canary на выходе петли.
  • Деплой в Kubernetes — GitOps-механика подробно.