Вадим Ваганов, ведущий эксперт разработки в Газпромбанке
Привет! Меня зовут Вадим, я техлид команды разработки платформы кеширования в Газпромбанке. Хочу рассказать о том, как внедрили, использовали и улучшали Trunk Based Development, совершили все возможные ошибки, но в итоге получили то, что хотели — быструю и надежную разработку. Cycle time у нас теперь около одного дня, по одному сервису больше 30 деплоев в месяц, и команда больше не боится пятничных релизов.
Если коротко про TBD — это подход к разработке с одной интеграционной веткой (trunk), куда все делают мердж-реквесты несколько раз в день. Никаких долгоживущих feature-веток, никакого git-flow с develop.
Эта история не про теорию — про практику. Расскажу, какие проблемы мы решали, в какие ямы падали и как выбирались. В итоге соберу чек-лист из семи мудростей, которые мы поняли за этот год — надеюсь, они помогут вам избежать наших граблей.

Амбиции и реальность
Мы работаем с высоконагруженным сервисом. Когда тысячи клиентов одновременно заходят в мобильное приложение, нагрузка идет через нас.
Не могу сказать, что наш процесс был совсем плох, но нам нужно было стать быстрее. Поставили себе цель: «от коммита до продакшена за один час».
У нас каждый релиз был болью: пока все тестировал и согласовывали, бизнес терял время, а разработчики — мотивацию: код писать хотели все, а вот релизиться желание падало чем дальше, тем больше. Тогда и решили попробовать внедрить Trunk Based Development.
Звучит просто: создали ветку транк и — все, TBD готов. Но сходу возникла куча проблем: очереди из мердж-реквестов, ветки от веток, полная неуверенность в стабильности транка.
Что такое TBD и чего мы от него хотели
Мы сформулировали четыре хотелки от TBD:
Мердж-реквесты сливаются в основную ветку в течение дня.
Ветки живут максимум несколько дней.
Команда уверена в состоянии транка (если что-то попало в trunk, оно точно ничего не сломает).
Коммиты быстро доставляются на прод.
Звучит красиво. Реальность сложнее.
Четыре главные проблемы нашего пути
Проблема 1: Болото мердж-реквестов
Первое, что случилось — наши мердж-реквесты начали «пахнуть». Образовалась огромная очередь, которую мы просто не успевали разгребать.
Причин было две. Первая — банальная нехватка времени на ревью. Разработчики были заняты «важными» задачами, а ревью казалось чем-то второстепенным.
Вторая — сами мердж-реквесты были в ужасном состоянии. Огромные, разнородные изменения, которые невозможно просмотреть за полчаса.
Срабатывает простая психология: между понятным и непонятным человек всегда выберет понятное. Есть непонятный мердж-реквест, а есть понятная задача — пошел делать задачу.
Проблема 2: Бессмертные ветки
Наши фича-ветки жили намного дольше нескольких дней. Хуже того — началась эпидемия «веток от веток». Один разработчик делает фичу, другому нужна его фича, и получается ветка от ветки.
Проблема 3: Кризис доверия к транку
Даже когда код попадал в транк, мы не были уверены, что ничего не сломали. Пайплайн мог мигать зеленым, но при этом тестов не хватало и очень часто на стейдже все разваливалось из-за того, что мы что-то не учли на стыках.
Проблема 4: Страх деплоя
Последний психологический барьер — страх деплоя на прод. Поднимите руку, кто не деплоит в пятницу.
Семь мудростей TBD
Год экспериментов научил главному: TBD работает, но только если понимать, как именно. Вот семь ключевых инсайтов — каждый решает конкретную проблему, с которой мы столкнулись.
Мудрость 1: Код-ревью — самый важный (почти) приоритет
Мы взяли внутреннюю документацию и расписали приоритеты команды:
Инциденты на продакшене;
Инциденты на стейдже;
Установка готовых поставок на прод;
Код-ревью мердж-реквестов;
Все остальное.
Зафиксировали это в документации команды. Теперь, когда разработчик говорит «я занят, не могу делать ревью», смело говорим ему: «Можешь. По приоритету у тебя сейчас ревью».
Сделали дашборд, где у нас по приоритетам все расположено: инциденты продакшена, инциденты стейджа, неустановленные поставки, код-ревью. По сути, такая игра — «опустоши все корзинки».
Мудрость 2: Автор несет ответственность за мердж-реквест
Есть тайная сущность разработчика: долго делаешь фичу, преодолеваешь проблемы, и когда все готово, хочется побыстрее от этого избавиться. Закидываешь мердж-реквест и думаешь: «Ребят, все, пока. Когда «вольете», сообщите».
Мы инвертировали ответственность. Зафиксировали в документации: за мердж-реквест отвечает его автор. Если он не попадает в транк в течение дня — это проблема автора.
Разница огромная. Когда человек делает код, который удобно проверять — это совсем другой уровень. Он подумал, дал контекст, убрал лишние изменения, разбил на несколько мердж-реквестов. В итоге ревью проходит за 15 минут вместо мучительного часа с тремя итерациями правок.
Мудрость 3: Никаких веток от веток
Установили жесткие правила:
Ветвиться только от транка;
Никаких веток от веток (кроме транка);
Если работаешь в своей ветке — только ты туда коммитишь.
Я как техлид больше всех нарушал последнее правило. Смотришь мердж-реквест, видишь мелкую фигню и думаешь: «Сейчас я сам поправлю». Идешь, коммитишь, а потом видишь — изменения пропали. Потому что автор параллельно форс-пушнул что-то свое.
Еще один лайфхак — мы отказались от релизных веток. Просто релизимся с транка. Законом не запрещено.
Мудрость 4: Декомпозируйте на уровне кода
В GitFlow привыкли: ветвишь фичу и работаешь в ней неделями. В TBD можно по-другому — коммитить кусочки кода.
Добавить модель данных? Отличный мердж-реквест. Маппер? Тоже хорошо. Интерфейс? Вообще красота. Проверять такое — дело нескольких минут.
Возникает вопрос: а что если код не используется или что-то поломает? Тут в дело вступают фича-тогглы — умный if, который выключает новый код. Если тоггл выключен, ваш код для продакшена не существует. Пишете код, он поставляется, но не работает.
Мудрость 5: Распараллеливание через абстракции
Параллелиться можно не только ветками, но и абстракциями. В TBD есть термин Branch by Abstraction — не ветки под каждую абстракцию, а ветвление с помощью абстракций.
Пример из практики. У меня три разработчика:
Паша дорабатывает текущий репозиторий с синхронным драйвером
Даниил пишет новую функциональность, которая зависит от репозитория
Артур хочет сделать новую быструю асинхронную реализацию
Решение простое — делаем интерфейс под репозиторий. Все. Паша работает с тем же кодом, прикрытым абстракцией. Данилу все равно, какая именно реализация — он работает через интерфейс. Артур пишет новую реализацию того же интерфейса.
Звучит банально, но работает.
Мудрость 6: Уверенность через shift-left
Мы перенесли максимум проверок на этап мердж-реквеста — классический shift-left подход.
Мастхэв — интеграционные и компонентные тесты. Они поднимают нужное окружение, но изолируются от других сервисов. Без них постоянно были ситуации: юниты зеленые, логика правильная, а на стыке все разваливается. Spring-контекст не поднимается, или все ломается на стейдже.
Добавили контрактные тесты, подтянули навык написания юнит-тестов. Самое важное — запускаем все это на мердж-реквесте. Если что-то упало — мердж-реквест красный, можно не проверять.
Да, это может замедлить, особенно вначале. Интеграционные тесты могут валиться по разным причинам, но когда пайплайн зеленый — появляется полная уверенность в изменениях. Можно деплоить без страха, что что-то сломается.
Мудрость 7: Деплой — это не релиз
Главное осознание: деплой и релиз — разные сущности. У нас есть фича-тогглы, Branch by Abstraction, сильный пайплайн. Когда деплоимся — просто доставляем код на прод, не доставляем новые фичи.
Чего мы обычно боимся? Что новая фича не заработает, сломает старую. Но если доставляем код, а не фичу — что это может поломать? Кажется, ничего.
Получается, можем деплоить в любой момент. Наш следующий шаг — автоматический деплой на прод. А релизы происходят, когда готовы вы, готовы смежники, когда хорошо протестировали фичу. Когда готовы — включили тоггл.
Главное — в любой момент можем посмотреть на мониторинг, увидеть проблемы и просто выключить фичу. Деплой и релизы становятся безопасными.
TBD рождается в голове
Самая важная мудрость: TBD — это в первую очередь культура, а не инструменты. Можно зайти на trunkbaseddevelopment.com, прочитать практики и начать их бездумно применять. Скорее всего, не сработает.
Работает только когда команда понимает, зачем это нужно. Когда обсуждаете подходы к решению задач, поправляете друг друга в сторону TBD-практик. Видите большой мердж-реквест — предлагаете разбить на несколько. Замечаете ветку от ветки — напоминаете про правило «только от транка». Это становится частью культуры команды.
Чек-лист
Создайте приоритет для ревью — задокументируйте, вшейте в процессы;
Наделите автора ответственностью — за мердж-реквест отвечает тот, кто его создал;
Откажитесь от интеграционных веток — только транк для ветвления;
Декомпозируйте на уровне кода — добавляйте код маленькими частями;
Параллельтесь через абстракции — интерфейсы вместо веток от веток
Сделайте серьезный shift-left — максимум проверок на мердж-реквест;
Разделите деплой и релиз — деплой доставляет код, релиз включает фичи.
Выводы после года с TBD
TBD может ускорить разработку, НО делать придется правильно. И чтобы практика реально заработало, придется менять мышление.
TBD заставит серьезно заняться CI/CD-пайплайном. Когда команда начинает коммитить в основную ветку несколько раз в день, качество и скорость пайплайна становятся критичными. В какой-то момент он станет главным ограничением — команда настолько быстро создает и ревьюит мердж-реквесты, что основное время тратится на ожидание результатов тестов и проверок. Это хорошая проблема — она заставляет оптимизировать пайплайн и делать его быстрее.
В общем, мы уже с трудом представляем, как работать по-другому. До заветного часа «коммит-продакшн» мы пока не дошли, но путь того стоил.
Комментарии (12)
APXEOLOG
08.07.2025 08:29Есть тайная сущность разработчика: долго делаешь фичу, преодолеваешь проблемы, и когда все готово, хочется побыстрее от этого избавиться. Закидываешь мердж-реквест и думаешь: «Ребят, все, пока. Когда «вольете», сообщите».
Мы инвертировали ответственность. Зафиксировали в документации: за мердж-реквест отвечает его автор. Если он не попадает в транк в течение дня — это проблема автора.
Подождите, а что, быть ответственным за свой код - это была не норма? Кто лучше автора кода может разрешить мерж конфликт? О_о
vrvaganov Автор
08.07.2025 08:29Согласен, может звучать дико. При этом ответственность за свой код - штука довольно очевидная, и вряд ли кто-то это отрицает или искреннее не понимает. Но простая манифестация аля "чувак, если твой MR застрял, то иди попингай ревьюеров/мейнтейнеров" или "чувак, если твой MR долго смотрят, возможно стоит его разделить на куски" нам помогла ускорить процесс. Было на что ссылаться, и со временем такая культура укоренилась в команде. Возможно, больший эффект был именно от других мер, но, как говорится, из песни слов не выкинешь, делюсь всем :) Спасибо за комментарий!
APXEOLOG
08.07.2025 08:29Еще один важный элемент при таком подходе, это постоянно вливать в бранчи все изменения из транка (как правильно простенькой автоматизации хватает). Отсутствие мерж конфликта не означает, что изменения не конфликтуют на уровне бизнес логики. Поэтому для ревью необходимо иметь версию, где все тесты проходят на "текущей" версии транка.
vrvaganov Автор
08.07.2025 08:29Замечание хорошее, мы уже даже разок обожглись, когда ветка была "зелёная", а при мёрдже в транк всё сломалось. Теперь у нас во всех репозиториях стоит стратегия мёрджа в trunk fast-forward only, так что физически нельзя смёрджить, не подлив trunk. Больше таких проблем не было и не будет!)
astypalaia
08.07.2025 08:29Если нет релизных веток - то где править баги, которые обнаружили (клиенты) в релизе? В транке? Но он мог слишком сильно "убежать" вперед.
vrvaganov Автор
08.07.2025 08:29Вопрос отличный! Делюсь опытом.
Сейчас мы уже экспериментируем с Continuous Deployment, и в таком случае - всегда в транк.
А если вернуться к контексту статьи, то есть такая фишка, что релизную ветку можно "отрезать" ретроспективно - от того коммита, который сейчас на ПРОД, и в котором найден баг. Дальше делаем фикс TBDшным образом: баг-фикс через MR в trunk, а потом коммит с баг-фиксом черри-пикается во вновь отведённую релизную ветку, после чего на этот коммит ставится новый тэг (на релизной ветке) и катится на ПРОД.
Также не стоит забывать, что новые фичи (или важные доработки) всегда должны быть под фича-тогглом, следовательно, если есть критичный баг в новой фиче, то фичу можно просто отключить и спокойно пофиксить баг в транке. После выкатки баг-фикса снова включить фичу на ПРОД.
IVNSTN
08.07.2025 08:29"Хороший тамада и конкурсы интересные" (с), т.е. здорово, что стало лучше и более по-взрослому, тем не менее, с моделью ветвления все четыре озвученных изначальных проблемы связаны приблизительно никак. Бескультурье и бардак вполне можно вернуть и при TBD, как и навести порядок и окультуриться в любой другой версии процесса.
Отказ от интеграционных веток, безусловно, ход конём, достойный восхищения, но как бы и намекающий, что в ваших обстоятельствах они может изначально были не особенно нужны. В каких-то других обстоятельствах собрать конфигурацию фича-тоглов или аналогов могло бы оказаться заметно сложнее, чем взять конкретную ветку. А могло бы оказаться более продуктивно активно пихать в общую промежуточную ветку и ее уже сквошить и катить в прод после тестирования. Беспредметно, в отрыве от всех обстоятельств вроде характера разрабатываемого продукта, его объёма, организации работы со смежными подразделениями, управления задачами и планирования, истории о лихом воплощении радикальных подходов не более интересны, чем объяснение полиморфизма на классах Cat и Dog.
Но, в любом случае, здорово, что куда-то подвигались и получилось. Может однажды и про техническую сторону тех самых пайплайнов, про организацию тестирования и систематизацию управления фича-тоглами расскажете. Будет интересно узнать.
vrvaganov Автор
08.07.2025 08:29Спасибо за конструктив!
с моделью ветвления все четыре озвученных изначальных проблемы
Бескультурье и бардак вполне можно вернуть и при TBD, как и навести порядок и окультуриться в любой другой версии процесса.
Согласен, что проблемы универсальны для любой модели ветвления и решения часто похожие. Особенно момент с культурой ревью. Некоторые же решения важны в бОльшей мере из-за специфики TBD.
Отказ от интеграционных веток, безусловно, ход конём, достойный восхищения, но как бы и намекающий, что в ваших обстоятельствах они может изначально были не особенно нужны.
Абсолютно так. Если мы можем без них жить - значит они не нужны.
Беспредметно, в отрыве от всех обстоятельств вроде характера разрабатываемого продукта, его объёма, организации работы со смежными подразделениями, управления задачами и планирования, истории о лихом воплощении радикальных подходов не более интересны, чем объяснение полиморфизма на классах Cat и Dog.
Услышал, что нужно больше "мяса", спасибо, буду улучшаться :)
Но, в любом случае, здорово, что куда-то подвигались и получилось. Может однажды и про техническую сторону тех самых пайплайнов, про организацию тестирования и систематизацию управления фича-тоглами расскажете. Будет интересно узнать.
Раз есть интерес - обязательно поделюсь опытом! Про тогглы, тесты и пайпы действительно есть что рассказать.
nin-jin
Так запретите форс-пуши.
Похоже на Gitlab Flow.
vrvaganov Автор
Спасибо за комментарий!
Мы запретили друг-другу работать в чужих ветках и оно работает ещё лучше :) Хочет автор сделать форс-пуш в своей ветке - пожалуйста. Если хочется сделать прям доработку - надо делать отдельную задачу+ветку, хочется поправить что-то в рамках текущей задачи/МР - оставляем комментарий и просим автора доработать. Думаю, тут главным злом было моё желание "да щас 5 сек сам сделаю".
Сходства есть, но есть радикальное отличие в плане использования этих веток. В TBD ветки никуда не ставятся (ну, кроме локали), путь один - в trunk.
В целом, TBD - это не какая-то магия, прорыв или серебряная пуля, просто набор хороших практик, которые работают при соблюдении "правил игры". Но работать по нему довольно приятно, когда получилось настроить процесс.
nin-jin
Если автор хочет форс-пушнуть, значит ему не привили культуру совместной разработки. Его ветка только одна - на его машине. Всё, что на сервере - это общедоступные ветки, если в них подделывать историю, то это создаёт множество проблем: от конфликтов историй при синхронизации, до сломанного бисекта. Как техлид, вы должны это знать и не допускать.
Вы перепутали gitlab и gihub, это разные flow. Будьте внимательнее.
vrvaganov Автор
Но если что-то пушнуть в ветку другого человека без его ведома, то это тоже не похоже на совместную разработку :)
И у меня возникает вопрос: а как же люди тогда ребейзят, сквоши делают и т. д.? Не имел проблем с форс-пушем, если он запрещен на защищённых ветках. Возможно, я ещё просто не обжёгся. Другой вопрос, что это в принципе инструмент довольно опасный, тут абсолютно согласен.
Да, пардон, начал читать сверху, а ссылка вела на самый последний раздел, спасибо, что поправили. Тогда апдейт - да, действительно, идея похожая.