Выбор workflow
Как выбрать workflow ветвления: взвесь модель релизов (непрерывный против версионного), размер команды, зрелость CI, инфраструктуру флагов и структуру репозитория. Веб + CD + малая команда — GitHub flow; крупная организация — trunk-based; библиотека, десктоп, прошивка — git-flow.
Теперь ты знаешь три workflow. Сеньорский навык — не в том, чтобы их перечислить, а в том, чтобы войти в команду, прочитать её ограничения и сказать «вам стоит применять вот этот, и вот почему», а затем распознать антипаттерн, когда кто-то предлагает неверный. Большинство боли с workflow в реальных компаниях — это не плохой workflow, исполненный плохо; это несоответствующий workflow, исполненный добросовестно — полная церемония git-flow, прикрученная к веб-приложению, которое деплоится ежечасно.
К концу этого урока у тебя будет процедура принятия решения: горстка факторов, которые реально определяют ответ, правила, которые отображают их на workflow, и антипаттерны, сигналящие о несоответствии прежде, чем оно обойдётся тебе в месяцы.
После этого урока ты сможешь провести решение по выбору workflow: определить решающие факторы (модель релизов, размер команды, зрелость CI и флагов, структура репозитория), отобразить их на git-flow, GitHub flow или trunk-based development с защитимой аргументацией и назвать антипаттерны, которые сигналят о несоответствии.
Модель релизов — доминирующий фактор, реши её первой. До размера команды, до всего остального спроси: ты отгружаешь непрерывно деплоящийся сервис или версионный продукт? Веб-приложение или SaaS, который деплоит то, что на main, потенциально много раз в день, не имеет понятия «версия 1.5.0 в поле» — есть только то, что живое. Библиотека в npm, десктоп-приложение или прошивка устройства отгружают дискретные версионные релизы и часто должны поддерживать несколько версий в поле одновременно (клиент на 1.4, который ещё не может обновиться). Это единственное различие делает большую часть сортировки: непрерывный деплой указывает на GitHub flow или trunk-based; версионные релизы с несколькими живыми версиями — единственный случай, который действительно хочет структуру git-flow.
Затем взвесь ещё четыре фактора, которые разрешают оставшиеся ничьи. Когда модель релизов сузила поле, эти решают остальное:
- Размер команды и скорость. Горстка инженеров против тысяч. Масштаб — это то, что толкает тебя от GitHub flow к trunk-based, потому что цена конфликтов слияния растёт сверхлинейно с числом параллельных веток.
- Зрелость CI. И trunk-based, и GitHub flow полностью опираются на автотесты как страховочную сеть. Слабый или нестабильный CI делает любой из них опасным и является предпосылкой, которую нужно починить первой.
- Инфраструктура feature-флагов. Trunk-based невозможен без реальных флагов; GitHub flow сильно их хочет. Отсутствие системы флагов ограничивает, насколько короткими могут быть твои ветки.
- Структура репозитория. Monorepo с тысячами коммитеров сильно благоволит trunk-based (длинные ветки против постоянно меняющегося дерева неработоспособны); много маленьких репозиториев дают больше свободы.
Ничто из этого не перебивает модель релизов, но вместе они выбирают между опциями непрерывного деплоя.
Примени правила. Они отображают факторы на дефолтный ответ, который ты можешь защитить:
- Веб-приложение или сервис + непрерывный деплой + малая-средняя команда → GitHub flow. Одна деплоибельная
main, короткие PR-ветки, флаги для крупной работы. Это верный дефолт для подавляющего большинства продуктовых команд. - Крупная организация + высокая скорость + сильный CI + реальные feature-флаги (часто monorepo) → trunk-based development. Толкай время жизни ветки к нулю, чтобы цена интеграции оставалась плоской на масштабе.
- Библиотека, десктоп, прошивка или любой продукт с версионными релизами и несколькими поддерживаемыми версиями → git-flow (или хотя бы долгоживущие релизные ветки). Структура
develop/release/hotfixотрабатывает свой вес, когда нужно стабилизировать и патчить дискретные версии.
Относись к ним как к дефолтам, а не законам: маленькая команда с отличным CI и флагами может работать на trunk-based, а большая команда без них должна остаться на GitHub flow.
▸Почему это работает
Заметь, что GitHub flow и trunk-based не настоящие соперники — это одна и та же идея (одна деплоибельная линия, короткие ветки) на разных масштабах, где trunk-based добавляет строгость флагов и CI, которую вынуждает масштаб. Честная рамка — это спектр: начни с GitHub flow, и по мере роста размера команды, частоты коммитов и зрелости CI ты ужимаешь время жизни ветки и сильнее опираешься на флаги, пока фактически не делаешь trunk-based. Git-flow стоит в стороне на совсем другой оси — он отвечает на «как мне поддерживать несколько отгруженных версий одновременно», вопрос, который непрерывно деплоящиеся сервисы никогда не задают. Поэтому модель релизов — первый разрез: она решает, находишься ли ты вообще на оси git-flow.
Выучи антипаттерны — это то, как ты ловишь несоответствие рано. Каждый из них — добросовестное исполнение неверного выбора:
- Git-flow на CD-веб-приложении. Чистые накладные расходы:
develop, релизные ветки и церемония тегирования для продукта, у которого нет версий. Признак: «мы нарезали релизную ветку» для того, что деплоится ежечасно. - Долгоживущие фичеветки где угодно. Универсальный антипаттерн. Ветка, открытая неделями, расходится и детонирует в момент слияния при любом workflow. Лечение всегда одно: меньшие инкременты, флаги, более быстрая интеграция.
- Незащищённая
main. Любой workflow на незащищённой main — workflow лишь на словах: один плохой пуш ломает всех. Защищённая ветка (обязательные CI + ревью до слияния) — необсуждаемый пол под всеми тремя моделями. - Принятие браночного правила trunk-based без его включателей. Коммит незавершённого, нефлагированного кода в trunk со слабым CI даёт тебе вечно сломанный trunk, а не скорость.
Замечать это — сеньорский вклад: workflow на вики может быть нормальным, но его исполнение съехало в одну из этих форм отказа.
Три команды, три верных ответа.
Команда A — SaaS-стартап из 7 человек, деплоит в прод несколько раз в день, приличный CI, базовая настройка LaunchDarkly. Модель релизов: непрерывная. Масштаб: малый. Ответ: GitHub flow — защищённая main, короткие PR-ветки, флаги для всего многодневного. Предложить здесь git-flow было бы классическим антипаттерном; нет версии, которую нужно стабилизировать.
Команда B — 400 инженеров в одном monorepo, тысячи коммитов в день, зрелый CI, первоклассная платформа флагов. Модель релизов: непрерывная, но на масштабе, где дневные ветки постоянно бы сталкивались. Ответ: trunk-based development — почти нулевое время жизни ветки, всё за флагами, релизные ветки только когда конкретный деплой нужно зафиксировать и патчить.
Команда C — команда из 12 человек, отгружает устанавливаемое десктоп-приложение, поддерживает версии 3.2, 3.3 и 3.4 в поле одновременно. Модель релизов: версионная, несколько живых версий. Ответ: git-flow (или хотя бы устойчивые релизные ветки) — им реально нужно патчить 3.2 для клиента, который не может обновиться, пока 3.5 в разработке на develop. Та же церемония, что накладные расходы для команды A, несущая для команды C.
Урок: workflow поменялся не из-за вкуса — он выпал из модели релизов и масштаба каждой команды.
▸Частая ошибка
Самая дорогая ошибка — выбирать workflow по престижу, а не по соответствию. «FAANG использует trunk-based, значит и нам надо» игнорирует, что у тебя может не быть инфраструктуры CI и флагов, которая делает trunk-based безопасным — ты получишь сломанный trunk, а не их скорость. Равно «git-flow — профессиональный стандарт» (убеждение, оставшееся с 2012 года) навешивает на непрерывно деплоящееся веб-приложение версионную церемонию, которой оно никогда не воспользуется. Выбирай под свою модель релизов, масштаб и инфраструктуру — а не под логотип компании, популяризировавшей workflow. Правильный workflow — это тот, чьи предусловия ты реально выполняешь.
Команда из 10 человек отгружает устанавливаемое десктоп-приложение и должна продолжать патчить версии 4.1 и 4.2 в поле, пока строит 4.3. Какой workflow подходит и почему?
Выбор workflow — это решение, а не предпочтение. Реши модель релизов первой — непрерывный деплой против версионных релизов с несколькими живыми версиями — затем дай размеру команды, зрелости CI, инфраструктуре feature-флагов и monorepo против многих репозиториев разрешить ничьи. Правила: веб-приложение + CD + малая/средняя команда → GitHub flow; крупная, высокоскоростная, с сильным CI, оснащённая флагами организация → trunk-based development; версионная библиотека, десктоп или прошивка → git-flow. Берегись антипаттернов — git-flow на CD-веб-приложении, долгоживущих веток где угодно и кардинального греха незащищённой main. GitHub flow и trunk-based — одна идея на двух масштабах; git-flow отвечает на совсем другой вопрос. Сопоставь workflow с предусловиями, которые ты реально выполняешь, и боль команды с git по большей части исчезает.
Практика
Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.