ADR: Модель ветвления
- Status: Accepted by Andrei Ganiushkin
andrey@ganyushkin.ru - Date: 2026-07-26
- Authors: Andrei Ganiushkin
andrey@ganyushkin.ru - Related issues: -
Context
Этот ADR фиксирует набор веток, их назначение и почему выбрана именно такая модель, а не одна из более простых альтернатив (trunk-based, GitHub Flow, полный GitFlow).
Границы решения:
- в рамках ADR: состав типов веток, назначение каждой ветки, источник ответвления и направления слияния, права push.
- вне рамок ADR: способ выполнения слияния — см. ADR 0007; подпись коммитов — ADR 0004. Подпись артефактов релиза — ADR 0005.
Требования, которые модель ветвления обязана поддерживать:
mainсодержит только выпущенные, подписанные состояния — разработка в ней не ведётся (ADR 0005).- Нужна отдельная точка заморозки кода на время ручной подписи артефактов по всем целевым платформам, не блокирующая текущую разработку (ADR 0005).
- Выпущенные версии должны поддерживаться патчами после того, как разработка ушла вперёд, — без размораживания уже закрытого релиза. Линия поддержки открывается тогда, когда для конкретной версии действительно понадобилось изменение.
Decision
Принимается модель из шести типов веток: main, develop, feature/*, fix/*, release/*,
support/*.
| Ветка | Назначение | Источник | Куда сливается | Время жизни | Кто может push |
|---|---|---|---|---|---|
main | История релизов, релизные теги | — | — | постоянно | никто |
develop | Интеграция разработки | main | release/* | постоянно | только maintainer |
feature/* | Новая функциональность | develop или support/* | ветка-источник | до приёмки | автор ветки |
fix/* | Исправления, security-fix | develop, release/* или support/* | ветка-источник | до приёмки | автор ветки |
release/* | Заморозка состава релиза и подпись артефактов | develop | main | до выпуска релиза | только maintainer |
support/* | Долгосрочная поддержка выпущенной минорной версии | тег версии в main, создаётся по необходимости | — (сама выпускает патчи) | месяцы/годы | только maintainer |
Назначение каждой ветки:
main— не место разработки. Хранит последовательность выпущенных состояний и релизные теги. Принимает изменения только изrelease/*.develop— интеграция новой функциональности и обычных исправлений. Единственный источник дляrelease/*.feature/*— реализация одной функциональной задачи. Сливается вdevelop(или вsupport/*для заказных доработок).fix/*— исправление дефекта. Ответвляется от той линии, в которой дефект должен быть исправлен (develop, незакрытаяrelease/*илиsupport/*), и возвращается ровно в неё.release/*— короткоживущий шлюз вmain: обновление версии иCHANGELOG, суффикс-rc.X, прогон проверок, подпись артефактов по платформам. После выпуска релиза удаляется.support/*— долгоживущая линия поддержки одной минорной версии. Создаётся не при выпуске релиза, а когда в эту версию потребовалось внести изменение. Из неё выпускаются патч-релизы (vX.Y.1,vX.Y.2, …) для пользователей, которые не переходят на новую версию, или заказные доработки (LTS-features).
Различие release/* и support/*
Обе ветки работают с релизами, но решают разные задачи:
release/* | support/* | |
|---|---|---|
| Роль | шлюз к выпуску новой версии | линия жизни уже выпущенной версии |
| Создаётся | из develop перед выпуском | из тега версии в main, когда понадобился патч |
| Живёт | до выпуска, затем удаляется | месяцы/годы |
| Принимает | подготовку релиза и fix/* до заморозки | fix/* и feature/* (заказные доработки) |
| Результат | vX.Y.0 в main | vX.Y.1, vX.Y.2, … |
Жизненный цикл:
Правила support/*:
- Ветка
support/vX.Y.xсоздаётся по необходимости — когда в выпущенную версию требуется внести изменение, — от тега соответствующей версии вmain(vX.Y.0или последнего патча этой линии, если она уже существовала). Заранее, в момент выпуска релиза, ветка не создаётся: пока патчи не нужны, линия поддержки представлена самим тегом. - Исправление для поддерживаемой версии делается в
fix/*отsupport/vX.Y.xи возвращается в неё же. Новая функциональность (например, уникальная доработка по запросу клиента) делается вfeature/*отsupport/vX.Y.xи также возвращается в неё. - Патч-релиз (или релиз с доработкой) собирается, подписывается и тегируется (
vX.Y.1) непосредственно изsupport/vX.Y.x.support/*вmainне сливается —mainостаётся линией мажорной линии разработки, а патчи поддерживаемых версий адресуются своими тегами. - Исправление, актуальное и для развиваемой версии, переносится в
develop(и в другие живыеsupport/*) отдельнымfix/*— автором исправления, а не автоматикой. - Срок поддержки каждой
support/*определяется организационно. По его истечении ветка переводится в архивное состояние (запрет push) и не удаляется.
Considered Alternatives
Alternative 1: Trunk-based development (одна ветка main + короткоживущие feature-ветки)
- Pros: минимум веток и правил, быстрая интеграция, нет долгоживущего
develop. - Cons: нет точки заморозки для подготовки и ручной подписи релиза по всем платформам —
релиз пришлось бы готовить прямо в
main, что нарушает рольmainкак истории выпущенных состояний. Нет линии для патчей старых версий. - Reason for rejection: не даёт окна заморозки, обязательного для многоплатформенной ручной подписи релиза.
Alternative 2: GitHub Flow (только main + feature/*, релиз — тег в main)
- Pros: проще GitFlow, привычен небольшим командам.
- Cons: функциональность и исправления попадают в
mainнапрямую, поэтомуmainперестаёт быть историей выпущенных состояний. Нет ветки заморозки и нет поддержки старых версий. - Reason for rejection: отсутствует шаг подготовки релиза и линия поддержки выпущенных версий.
Alternative 3: Модель без support/* (патчи старых версий через release/* от тега)
- Pros: на один тип ветки меньше.
release/*уже умеет собирать и подписывать релиз. - Cons:
release/*по назначению короткоживущая и удаляется после выпуска — при каждом патче старой версии её пришлось бы воссоздавать от тега, теряя историю исправлений этой линии; непонятно, где живёт актуальное состояние поддерживаемой версии между патчами. Смешиваются две разные роли — подготовка нового выпуска и сопровождение старого. - Reason for rejection: долгосрочная поддержка требует именно долгоживущей ветки с собственной историей исправлений.
Alternative 4: Полный GitFlow (с отдельным типом hotfix/*)
- Pros: индустриальный стандарт, покрывает больше частных случаев.
- Cons:
hotfix/*не отличается отfix/*ни правами, ни правилами приёмки — различается только ветка-источник, которая и так фиксирована в таблице. Лишний тип ветки удваивает количество правил автоматизации без новой семантики. - Reason for rejection: hotfix полностью покрывается
fix/*отrelease/*/support/*.
Consequences
Positive
- Роли разделены: разработка (
develop,feature/*,fix/*), выпуск (release/*), история выпусков (main), сопровождение (support/*). release/*даёт явное окно заморозки для ручной подписи артефактов, не блокируяdevelop.- Выпущенные версии можно патчить годами, не влияя на развиваемую линию.
- Набор веток минимален: нет типов веток, дублирующих чужое назначение.
Negative
- Больше веток и правил, чем в trunk-based/GitHub Flow — требуется документация в
CONTRIBUTING.ru.mdиRELEASING.ru.md. - Одновременно живые
support/*требуют переноса исправлений в несколько линий вручную — трудозатраты растут линейно с числом поддерживаемых версий. - Каждая живая
support/*расширяет матрицу сборки и проверок CI.
Risks and Mitigations
- Risk: исправление внесено в
support/*и не перенесено вdevelop— дефект возвращается в следующей версии.- Mitigation: обязательная связанная задача на перенос в
developпри приёмкеfix/*вsupport/*. Проверка закрытия связанных задач перед созданиемrelease/*.
- Mitigation: обязательная связанная задача на перенос в
- Risk: ветки создаются не по конвенции (
feature/*,fix/*,release/*,support/*), что ломает автоматизацию.- Mitigation: проверка имени ветки и ветки-источника в CI.
- Risk: число живых
support/*растёт неограниченно.- Mitigation: явный срок поддержки для каждой минорной версии. Перевод просроченных
support/*в архивное состояние.
- Mitigation: явный срок поддержки для каждой минорной версии. Перевод просроченных
References
- ADR 0007: Стратегия слияния веток — как выполняются слияния между перечисленными ветками.
- ADR 0005: Подпись артефактов релиза — заморозка
release/*и подпись по платформам. - ADR 0004: Подпись коммитов контрибьютором.
CONTRIBUTING.ru.md,RELEASING.ru.md.