Уже больше 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-проектов.