Как улучшить процесс обмена программным кодом? Как при работе с git оставлять понятные сообщения к коммитам и получать дополнительный эффект для процесса производства кода, а в сообщении рассказать о семантике изменений в коде: исправлении дефекта, новых функциях, влияниях на сборку и документацию?
Когда я был разработчиком, у меня возникла дилемма о том, что писать в сообщениях к коммитам. С одной стороны, нет смысла описывать то, что видно в диффе кода; повторять в каждом сообщении заголовок тикета тоже глупо, если коммитов много. В граф гита смотрят другие участники и им хорошо бы понимать прямо из дерева о внесенных изменениях. Тогда я попробовал Соглашение о коммитах.
Наша команда третий год работает по Соглашению. Правила работы распространяются на всех, кто работает с кодовой базой: бекендеров, фронтов, системных инженеров, спецов по качеству, системных аналитиков.
Соглашение говорит о том, как писать сообщения к коммитам.
Минимальная структура сообщения такая:
<тип>: <описание>
Выглядит примерно так:
feat!: обязательное поле цвет глаз в форме
Восклицательный знак перед двоеточием в примере – тоже часть соглашения. Это указатель на то, что в коде сломана обратная совместимость.
Мы в проекте используем такие типы:
Ошибок с выбором типа не избежать. Но рука набивается быстро.
Поверх типизированного графа коммитов можно придумать ряд автоматизаций.
И первое, что напрашивается – версионирование компонентов системы.
В мире материальных объектов все просто и чаще всего подойдет инкрементальное
версионирование (АйФон 12, 13, 14 ... 42).
В подсистемах и сервисах, работающих в интеграционной среде, чаще всего используют семантическое версионирование (СемВер), чтобы показать класс вносимых изменений.
Структура Cемвера такая:
vМАЖОР. МИНОР. ПАТЧ
Пример:
v9.4.12
Разберем каждый разряд слева направо.
МАЖОР
9 — в компоненте было девять ломающих совместимость изменений, мажоров.
Пример в физическом мире: у футболки зашиваем один рукав – руку через него уже не
просунуть.
МИНОР
4 — столько фич завезли в 9 мажорной версии.
Пример в физическом мире: к нашей футболке пришили карман.
ПАТЧ
12 — количество патчей (багов или прочих мелких дополнений, не влияющих на
исполняемую часть кода) после добавления последней фичи.
Пример в физическом мире: поставили заплатку на футболку.
При увеличении (бампе) разряда — обнуляем все разряды правее текущего.
Для нашего примера при выпуске мажора версия будет выглядеть так: v10.0.0
Версионирование на эмоджи:
v1.0.0 — исходное состояние.
v1.0.1 — пропатчили.
v1.1.0 — добавили фичу.
v2.0.0 — сломали обратную совместимость.
Мы автоматизировали выпуск версий по СемВер на основе сообщений к коммитам, выпущенным по Cоглашению.
Код попадает в главную ветку — выпускаем версию.
Задачу выпуска у нас решает standard-version. Официально этот пакет в статусе deprecated, но работает, как часики.
Для устранения вероятности ошибок и опечаток в сообщениях хорошо иметь помощника — линтер, который бы проверял сообщение к коммиту по правилам, заданным в проекте.
Мы используем commitlint.
Библиотеку необходимо запускать на хуке commit-msg (как это сделать – описано в документации пакета). Там она валидирует сообщение и, в случае неконвенциональности, в консоли сообщает об ошибках и не завершает коммит.
Исправляем ошибки — коммит готов!
Второй соблазн по автоматизации после версионирования — формирование перечня изменений в приложении или компонентах — ченджлога.
Мы формируем ченджлог между двумя последними версиями компонента и сохраняем его в артефакты Гитлаба.
Инструменты для формирования лога в ассортименте, да и в конце концов можно самому написать простой шел-скрипт.
Но я, как сорока, подслушал в подкасте Радио-Т библиотеку git-cliff, принес «яркую монету» в проект — так с ней и живем.
Ключевые плюшки Клиффа:
[changelog]
header = "Changelog"
body = """
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | upper_first }}
{% for commit in commits %}
- {{ commit.message | upper_first }}
{% endfor %}
{% endfor %}
"""
trim = true
footer = ""
postprocessors = [{ pattern = "foo", replace = "bar"}]
Уверен, что в 100% продуктовых команд есть общий чат, а то и не один.
Мы живем в мессенджере «Телеграм». Туда же помимо доставки на окружения компонентов отправляем ченджлог.
Пример сообщения о релизе в продуктовом чате:
Соглашение о коммитах однозначно добавит в ваши репозитории порядка, если раньше там царила анархия.
Разработчики научатся декомпозировать код на основе типов изменений, получат возможность задуматься о классе изменений, что особенно критично при мажорных правках.
Релизные процессы можно автоматизировать (выпуск версий, формирование лога изменений).
Граф коммитов станет более понятным для участников процесса.
Наличие в проекте Соглашения о коммитах — хороший задел и, скорее всего, порядок в репозиториях вам гарантирован, если применить несколько полезных автоматизаций поверх него. Но не стоит идеализировать процесс — незарегистрированых мажорных версий не избежать, человеческий фактор остается.
Спросите про «ягоду на десерте»? Пожалуйста: мы обобщаем изменения в версии приложения, но уже — для конечного пользователя. Для этого мы используем тулинг на основе больших языковых моделей.