Git: какие ветки создавать

Уже больше 100 заметок и только сейчас дошли руки до git. Наверное, казалось слишком очевидным. В заметке не будет команд, будет описан общий подход. В последующих будет работающий пример.

Изначально был очень популярен git flow. Сейчас – GitHub Flow (aka разработка через MR/PR). В целом, изменение произошло из-за того, что сейчас редко поддерживаются множество версий одновременно, т.к. это просто слишком дорого.

Разработка нормальная

  • создается ветка dev/<тикет>-<краткое описание> из main. Например, dev/MY-123-adds-create-user-endpoint.
  • в ветке идет работа. В Gitea/Gitlab/Github создается соответствующий MR/PR (далее просто MR).
  • нам не важны отдельные комиты в ветке, важно описание MR.
  • после окончания разработки MR вмердживается в main одним комитом (squash). Описание комита берется из описания MR.

Релиз нормальный

  • создается тег на комит в main. Например, v1.2.0
  • CICD создает релиз в терминах Gitea/Gitlab/Github (и подставляет туда сгенерированный release notes).
  • CICD создает необходимые артефакты (например, docker image, инсталятор или пакет в Maven)

Разработка горячего исправления

  • горячая ветка создается от тега. Например, release/1.2 от тега v1.2.2 (до этого исправления 1.2.1 и 1.2.2 шли из main, т.е. не были горячими)
  • идет работа в ветке, обычно MR не создается
  • в первом комите (чтобы не забыть, технически можно в любом) описываем как в комите для main, чтобы сгененировать корректно release notes. Описание остальных комитов не так важно.
  • после окончания разработки релиза создается обычная ветка разработки из main и туда переносятся исправления (сложность переноса, да и вообще необходимость, зависит от того насколько main отличается от этой ветки). Это новая ветка уже идет по стандартной процедуре.
  • в какой-то момент времени горячая ветка удаляется (если рассчитываем, что может быть больше исправлений в будущем, то можем сразу не удалять)

Горячий релиз

  • как нормальный, но тег ставится на комит в горячей ветке
  • естественно, это изменение только 3ей цифры в версии, т.к. только исправление
  • в остальном, дальше как обычный релиз

Ключевые моменты (aka архитектурные решения)

  • хочется оставить максимальную свободу внутри ветки и наоборот чистоту истории в main, поэтому squash вмердживание в main
  • релиз не меняет код репозитария – release notes и версии – нечто внешнее относительно кода. Почему? Непонятно зачем автоматические комиты в исходники – это время от времени приводит ко всяким проблемам.
  • версионирование идет по семантическим версиям. Так что для указанного комита автоматически высчитывается предыдущая версия, а по пометкам, оставленным в описании коммитов автоматически понимается какую из 3х цифр нужно увеличивать на единицу.
  • для деплоя на тестовые окружения нет необходимости делать релиз. В этом случае версия будет типа v1.2.3-7-g432e5 , где 7 – кол-во комитов в ветке, а g432e5 – id последнего комита.
  • в одном MR/PR может быть несколько фич и исправлений ошибок. Почему? Кол-во тестовых окружений ограниченно, а исправления могут быть в одну строчку. Парсер release note должен поддерживать это. Поэтому спецификация https://www.conventionalcommits.org/en/v1.0.0/ как есть не подходит (да и мало кто ее по этому же и использует).
  • с точки зрения CICD ручной запуск работы релиза производится из main и горячих веток
  • тут не описаны проверки кода на уровне CICD и code review – да, это все нужно делать

PS. Понятно, что могут быть и другие варианты, это лишь мое видение для backend-проектов.