Моя стратегия ветвления/тегирования пакетов

Источник: «My branching/tagging strategy for packages»
Это та статья в блоге, которую я хотел бы получить, когда искал хороший рабочий процесс для ветвления и тегирования пакетов/библиотек с открытым исходным кодом.

Оглавление

Я вечно не мог разобраться, как нужно создавать ветви для библиотек с открытым исходным кодом. Существует множество ресурсов, рассказывающих о том, как правильно создавать ветви и теги для проектов (git-flow, GitHub flow, Trunk based development, …), но они не очень хорошо соотносятся с распределёнными библиотеками.

Моя стратегия

Этот рабочий процесс похож на то, что я наблюдал в других пакетах/библиотеках/фреймворках. Он не претендует на то, чтобы быть исчерпывающим руководством к тому, как вы должны это делать, а служит преимущественно напоминанием и руководством для меня. Итак, давайте приступим.

Начало разработки

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

Пометка тегом первой версии

Когда вы будете готовы пометить свою первую мажорную версию (v1.0.0), сначала создайте ветку под названием 1.x. Именно из неё вы будете помечать тегом свою первую версию.

git switch main
git pull origin main
git switch -c 1.x
git push origin 1.x
git tag -s v1.0.0 -m 'Version 1.0.0'
git push origin v1.0.0

Не забудьте также сделать ветку 1.x веткой по умолчанию на GitHub. С этого момента ветка main предназначена для разработки v2.0.0. Я бы также перестал напрямую коммитить в любую из этих веток и вместо этого работал бы через pull requests. Эти pull request'ы чаще всего нацелены на 1.x и переносятся в main.

Например, у вас есть новая функция, без существенных изменений в работе. Запрос на pull request для этой функции будет нацелен на 1.x, так что он попадёт в v1.1.0. После одобрения и слияния с 1.x, вы объедините это изменение в main:

git switch 1.x
git pull origin 1.x
git switch main
git pull origin main
git merge 1.x --ff-only
git push origin main

Вы также можете облегчить это слияние из пользовательского интерфейса GitHub, используя страницу "compare". Добавьте /compare/main...1.x к URL вашего репозитория, и вы увидите кнопку для создания запроса на слияние изменений из 1.x в main.

Пометка тегом новых минорных и патч версий

Как только версия 1.1.0 будет готова к выпуску, пометьте её тегом в ветке 1.x:

git switch 1.x
git pull origin 1.x
git tag -s v1.1.0 -m 'Version 1.1.0'
git push origin v1.1.0

Два точка 0 и далее

Когда вы вносите критическое изменение в один из ваших pull request'ов, вы должны направить его в ветку main. В тот момент, когда вы будете готовы поставить тег v2.0.0, вы создаёте новую ветку 2.x и поставите тег следующей мажорной версии оттуда. Это практически то же самое, что и пометить тегом первую версию.

git switch main
git pull origin main
git switch -c 2.x
git tag -s v2.0.0 -m 'Version 2.0.0'
git push origin v2.0.0

Не забудьте также обновить ветку по умолчанию до 2.x на этом этапе.

Исправления багов в предыдущих версиях

Если появляется исправление, которое должно быть применено к 2.x и 1.x (или другим предыдущим версиям), оно должно быть направлено в последнюю ветку, в которой присутствует баг. В данном случае я предположу, что это 2.x. Как только исправление будет внесено в 2.x, вы сможете выбрать коммит(ы) для других затронутых версий:

git switch 2.x
git pull origin 2.x
git switch 1.x
git cherry-pick <commit sha>
# Или, если вы хотите выбрать несколько коммитов:
# git cherry-pick <first commit>^..<last commit>
git push origin 1.x
git tag -s v1.x.y -m 'Version 1.x.y' # Где 'y' увеличивается
git push origin v1.x.y
git switch main

Альтернатива

Я рассматривал стратегию, в которой веткой main всегда является текущая последняя версия, но это приводит к ещё большему количеству забытой административной работы. Кроме того, то, что я описал выше, на самом деле делает Laravel (насколько я могу судить), и это похоже на то, чему следует Symfony. Так что мы в хорошей компании.

Заключение

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

Дополнительные материалы

Предыдущая Статья

Автоматическое хэширование значений моделей кастом "Hashed"

Следующая Статья

Процессы и команды Artisan в Laravel