Существует некий проект на JavaScript/Node.js. Проект не публикуется в npm registry, исходный ход находится на GitHub.
Есть ветка master и feature-ветки с различным функционалом. И каждый раз происходит следующий рутиный процесс:
- Feature-ветка готова к слиянию.
- Правится версия в package.json. От характера изменений определяется какая версия по semantic versioning должна измениться.
- Добавляется текст в CHANGELOG.md. Берется git log ветки и смотрится, что необходимо отобразить в логе, а что можно и игнорировать.
- Обновляется package-lock.json. Ну тут стандартно, npm i, которой обновит версию в лок-файле.
- Создается Pull Request (PR).
- PR проверяется ответственным лицом. Code review. Принимается.
- Создается Release в GitHub. В описании релиза пишутся изменения, которые попали в changelog.
- Публикуется Release и создается тэг.
Каждый релиз, заставляет делать одно и то же. От однообразности работы, иногда можно забыть поменять версию в package.json или полениться changelog написать. Или наделать ошибок в markdown файлах.
Естественно, как и любому хорошему разработчику, хотелось бы избавиться от ручного процесса.
Для поднятия версии в package.json например есть утилита npm-version. Ей можно указать, какую версию необходимо поднять. Но это почти то же самое, что отредактировать самому package.json.
Для генерации changelog, есть много утилит, которые позволяют выдернуть git log, и добавить в начало CHANGELOG.md правильный markdown. Проблема только в том, что не хотелось бы чтобы все коммиты попадали в changelog. Но можно сгенерировать, а потом подправить – это будет быстрей, чем печатать изменения с нуля.
PR можно создать через GitHub API например. Да и Release можно вполне также. А тэг можно создать локально и запушить в репозиторий.
Но все это уже придумано и автоматизировано. Но обо всем по порядку.
Conventional Commits
Как гласит слоган на сайте спецификации: "A specification for adding human and machine readable meaning to commit messages", а если по-русски: "Спецификация о том, как правильно писать сообщения коммитов, чтобы они были понятны людям и машинам".
И вот в чем вся соль данной спецификации: предлагается всем объединиться и писать сообщения к коммитам следующего содержания:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Все что в квадратных скобках указывать необязательно. Type – это тип коммита. Типов существует несколько, но самые популярные – это fix (bugfix) и feat (feature).
Самый короткий вариант правильного коммита будет выглядеть так:
feat: Добавлена OAuth авторизация
В рамках этой статьи – это все, что вам необходимо знать о conventional commits.
Release please (RP)
Разработчикам Google тоже надоело писать changelog, поэтому они психанули и создали вот такую вещь. Теперь, чтобы не заниматься всей рутиной, описанной в начале статьи, достаточно оформить коммиты по conventional commits и принять один раз RPR, он же Release Pull Request.
И вот как это работает:
- Feature-ветка готова к слиянию.
- Создается Pull Request (PR).
- PR проверяется ответственным лицом. Code Review. Принимается.
- RP создает новую ветку от master.
- RP парсит все коммиты в master, которые были с момента последнего релиза.
- RP определяет характер изменений для поднятия версии.
feat = minor
fix = patch
Если в подвале коммит-сообщения есть сочетание слов "BREAKING CHANGE", тогда это будет major. Тоже самое произойдет, если на конце типа коммита поставить знак !, например feat!.
После того, как тип изменений определен, автоматически меняется версия в package.json и package-lock.json - RP на основе истории коммитов, формирует текст в начало CHANGELOG.md, в определенном формате, где есть номер версии, дата и текст из коммитов, которые разделяются на секции:
feat – Features
fix – Bugfixes
chore – Miscellaneous
Ну и конечно же все это можно настроить под себя. - RP создает RPR (Release Pull Request). В нем содержаться все изменения, которые выше. Обычно три файла: package.json, package-lock.json и CHANGELOG.md
- Ответственное лицо принимает RPR.
- RP создает GitHub Release, заполняя в нем уже сформированный до этого changelog из п. 7, а также указывает в виде тэга новую версию из п. 6. И после всего этого автоматически публикует релиз.
Как видите, наше дело теперь правильно сообщения к коммитам писать и кнопки под PR жать. Но и здесь нужна дисциплина, а если её нет, то надо её привить.
Commitizen & commitlint
Commitizen – еще один помощник в нашем нелегком деле. Это небольшая утилита, которая позволяет делать коммиты в интерактивном режиме.
Все для того, чтобы не запутаться с форматом написания сообщений к коммитам.
А для тех, кому не нравится нечто подобное, могут писать руками, но при этом валидировать коммиты через commitlint. Он легко настраивается через git hook commit-msg. А так как commit-msg только локальный хук, то распространить его в проект нам поможет husky.js.
Также существуют плагины commitizen для большинства популярных IDE.
Итог
Чтобы все это настроить, нужно совсем немного времени.
Для release-please существует github action, в котором достаточно указать последний коммит откуда начинать парсить историю и коммит последнего релиза.
commitlint и husky.js – это просто npm-пакеты.
Приложите к этому прямые руки, немного активности серого вещества и это позволит вам сэкономить драгоценное время, которое можно потратить на что-то более полезное ;)