Конвейер обрабатывает то, что ему приносит 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-механика подробно.