Pull to refresh

Мой опыт перевода команд разработки на trunk-based development

Level of difficultyMedium
Reading time6 min
Views3.1K

Привет, Хабр!

За свою карьеру руководителя разработки я успешно перевел на рельсы TBD 5 команд общей численностью 20 человек. Когда я общаюсь с коллегами из других компаний на тему TBD, то часто слышу про негативный опыт. Эта статья - мой личный опыт и разбор типовых ошибок других компаний.

Что такое trunk-based development?

Trunk-based development это, в первую очередь, инструмент. Чтобы эффективно применить инструмент, нужно понять что он делает и где может быть полезен.

Мой вольный перевод вступления с сайта trunkbaseddevelopment.com:

Модель ветвления в системе контроля версий, в которой разработчики совместно работают над кодом в единственной ветке под названием trunk*, избегают создания долгоживущих веток с помощью хорошо зарекомендовавших себя методик и техник. Таким образом, они избегают серьезных конфликтов при слиянии кода, не ломают работающую систему, и живут долго и счастливо.

*trunk это main/master в терминологии Git.

По сути, TBD это набор хорошо зарекомендовавших себя практик. Вот самые важные из них:

  • Branch by Abstraction. Наверное, самая сложная практика для понимания и применения. Суть в чем - если нам надо заменить какой-то кусок программы, неважно это отдельная функция или целый блок программной логики, то мы делаем следующие шаги:

    • Закрываем интерфейсом старую реализацию, который мы хотим заменить.

    • Меняем в коде вызов старой реализации на вызов интерфейса. Dependency Inversion Principle.

    • Пишем новую реализацию и закрываем ее тем же интерфейсом.

    • Подменяем старую реализацию на новую.

    • Удаляем старую реализацию.

    На практике, эту технику нет смысла применять для всех задач, например для исправления багов или для небольших и легко тестируемых задач.

  • Branch for release. Тут есть 2 подхода:

    • Если у нас back-end или front-end разработка, то мы можем собирать релиз прямо из trunk ветки. Например, поставить tag с номером версии на тот коммит, с которого мы хотим собрать релиз и настроить CI/CD на это действие.

    • Если у нас мобильная разработка, то там есть бутылочное горлышко в лице проверки приложений от Apple/Google. Проверки могут быть по несколько дней, и по ее итогам могут прилететь правки. А еще мы можем захотеть сделать тестирование отдельным процессом и не хотим чтобы работа над релизом блокировала основную разработку. В этих случаях, мы заводим release ветку, если прилетают правки, то исправляем их в trunk и забираем в release ветку с помощью cherry-pick. Почему именно такой порядок - чтобы trunk всегда был актуален для остальных разработчиков. На последний коммит релизной ветки мы ставим tag с номером версии. Хранить релизную ветку или нет - решать вам, в моих командах мы храним релизную ветку до следующего релиза.

  • Feature flags. Если мы работаем над какой-то большой фичой, но при этом у нас частые релизы и мы не хотим их блокировать, то мы закрываем нашу работу с помощью feature flag. В моих командах back-end и front-end разработка под feature flags обычно имеют config файлы, а мобильная разработка делать отдельный feature screen, на котором QA отдел может включить/выключить фичи для тестирования.

  • CI/CD. Тут все стандартно:

    • Прогон линтеров и статических анализаторов кода

    • Прогон тестов

    • Сборка билда и отправка в в тестовую и/или боевую среду.

  • Ветки с коротким временем жизни. По сути, это означает что мы делаем фичу поэтапно, каждый этап - отдельная ветка, то есть feature веток на несколько тысяч строк в TBD нет. Как это можно реализовать:

    • Использовать branch by abstraction, каждое действие отправляем на code review.

    • Поставить в команде ограничение на размер merge/pull request. Я обычно ставлю максимум 300±50 строк бизнес-логики.

    • Завести в команде правило делать минимум один merge/pull request в день.

      • Из этого следует еще одно важное правило делать code review в течение получаса-часа, это культура continuous code review. Этот пункт не актуален если у вас pair или mob programming.

      • После каждого merge/pull request нужно сделать pull из ветки trunk, чтобы работать с актуальной версией кода

    Все эти правила нужны для того, чтобы разработчики в команде чаще синхронизировались между собой и не копили свою работу на локальном компьютере.

  • Коммиты прямо в trunk. В IT сообществе часто с осуждением смотрят на тех, кто отправляет свой код сразу в master, но в trunk это одна из основных концепций. Мне тоже потребовалось время чтобы принять эту мысль, но на практике я нашел в ней только плюсы:

    • Такой экстремальный подход порождает культуру написания тестов, если у вас по какой-то причине ее нет.

    • Нету кучи промежуточных веток, как в Git flow, есть только trunk и ветка с коротким временем жизни. Процесс вливания кода в общую ветку разработки становится гораздо проще.

    Отдельно хочется сказать про работу с багами в trunk. Предлагается 2 способа:

    • Fix forward, когда мы просто исправляем баг следующим коммитом.

    • Roll back, когда мы откатываемся на последнюю работающую версию кода.

    Тут все зависит от вашего контекста и SLA. Обычно для команд мобильной разработки я использую fix forward, т.к. мы все равно ограничены проверками Apple/Google и оперативное исправление в целом не играет большой роли. Для back-end и front-end команд я предпочитаю придерживаться стратегии roll back.

Нужен ли вам TBD?

На мой взгляд, нужно регулярно задавать себе вопрос "Не фигню ли я делаю?", особенно если вы - руководитель и хотите затащить в команду какую-то новую практику. TDB не исключение.

Итак, я не буду завозить в команду TBD если:

  • Команда 1-3 человека и расширение не планируется. В большинстве случаев, для такого размера команды TBD довольно сложный инструмент.

  • Процесс в команде налажены и бизнес доволен скоростью работы команды. Как говорится, работает - не трогай, лучшее - враг хорошего.

  • Merge conflicts в команде довольно редкие или их вообще нет.

  • У команды нет времени на внедрение новых практик из-за высокой загруженности, например в стартапе или при ограничениях по времени и срокам проектов от бизнеса. TBD требует времени на осмысление, принятие идей и интеграцию в работу. Быстро занести все практики в команду практически невозможно.

У каждого из вас, кто будет читать эту статью, наверняка будет свой контекст, поэтому мой список не является исчерпывающим.

Upd. после дискуссии в комментариях с @sshikov я хотел бы отметить, что важны не только параметры по отдельности, но также их совокупность. Также бывают и исключения. Например, в команду из 2 человек есть смысл завозить TBD, если у них активная продуктовая разработка и бывают пересечения по задачам.

Разбор основных ошибок при переходе на TBD

Команда не поняла зачем это нужно и начала сопротивляться, пришлось оставить все как есть.

Любая система стремится к гомеостазу, то есть к поддержанию своего текущего состояния. Кардинальное изменение рабочего процесса и неизвестность вызывает тревогу у любого человека. Я обычно делаю команде презентацию, в которой есть следующие пункты:

  1. Определение текущих проблем. Тут важно взять именно кейсы из командной работы, которые можно исправить с помощью TBD. Например, неудачные слияния большого количества кода, огромные merge/pull requests, большое количество merge conflicts и т.д.

  2. Показать какие есть альтернативы, помимо TBD. Я всегда делаю это упражнение, и вам советую - часто бывает полезно посмотреть какие еще решения для вашей проблемы есть на рынке.

  3. Подробный рассказ про TBD. Выше я рассказал про основные практики, команда должна точно понимать что это такое и как это будет работать.

  4. Отработка возражений. Это мой любимый пункт. В своей работе я стремлюсь к тому, чтобы продать команде идею и преодолеть сопротивление непонимания. Если возражения не отработаны, то идея перехода на TBD с большой долей вероятности провалится.

Обычно в команде находится несколько людей, которым эта идея интересна, поэтому можно выделить небольшую группу заинтересованных и провести эксперимент.

Команда не поняла как это работает и откатилась к своим привычным рабочим процессам.

Часто встречаю такую фразу у тех, кто пытается затащить в команду сразу все практики из TBD. Дело в том, что каждая из практик требует осмысления, поэтому проще есть слона по кусочкам. Выберите какую-то одну практику, детально разберитесь в ней, затем аккуратно интегрируйте ее в работу команды и проконтролируйте чтобы все специалисты соблюдали эту практику.

Мы внедрили TBD, поработали, нам не понравилось и мы решили вернуться к привычным рабочим процессам.

Тут я встречал 2 варианта:

  1. Неправильно реализовали практики, которые в итоге стали мешать. Например, feature toggle делались абсолютно на все фичи и не удаляли старые реализации, что в итоге привело к захламлению кода. Или не писали тесты и не проводили code review, вследствие чего trunk очень часто ломался и невозможно было выпустить срочный релиз.

  2. Правильно реализовали практики, но не получили ожидаемого прироста в производительности и/или качестве. Обычно в таких командах изначально уже все было неплохо, поэтому разница была несущественной. В этом случае откат вполне закономерен и ничего страшного нет.

Как изменились метрики команды при переходе на TBD

  1. Скорость поставки фичей вырастала на 20-30% при тех же командных усилиях.

  2. Объем кода на merge/pull request сократился, поэтому делать code review стало легче и быстрее на 15-20%. Однако, отмечу что это субъективные ощущения разработчиков в команде.

  3. Процесс релиза в мобильной разработке сократился с 3-5 до 1-2 дней. Во front-end и back-end разработки он сократился с 2-3 дней до 1 дня.

К сожалению, никто и ничто не может гарантировать вам того, что метрики вашей команды так же изменятся в лучшую сторону. Однако, если инструмент TBD подходит под ваш контекст, то попробовать точно стоит.

Tags:
Hubs:
Total votes 5: ↑4 and ↓1+4
Comments21

Articles