Поднялся вопрос стандартизации коммитов в команде. До этого были такие правила, мы пишем номер задачи и через тире описание того, что было сделано кратко. Номер задачи берется из номера issue. Например: #1 - реализован функционал сборки прода
. Но, это надоело и стало как-то неудобно, когда у нас есть четкое деление задач на фиксы, фичи и так далее.
Нашли Conventional Commits и попробовали его на тестовом репозитории, понравилось. Решили внедрить это в команду, но столкнулись с тем, что люди не всегда делают коммиты правильно, а значит нужна какая-то валидация.
В нашей команде принято по максимуму IDE и его возможности. То есть, коммиты мы делаем не через консоль, а через встроенные утилиты. Поэтому, сразу пошли искать плагины, которые есть в PHPStorm и нашли вот эти 2 важных плагина: Conventional Commit и Git Commit Template. После их установки видим новые кнопки в окне коммита:
Первая - это от плагина Git Commit Template, а остальные от Conventional Commits. Если рассмотреть каждую из низ, то открываются следующие окна:
Они очень походи, выбирайте сами то, что вам больше нравится. Результат обоих окно будет коммитом в нужном формате. Но, после создания коммита вы можете его руками изменить, что опять же может привести к нарушению стиля и правил коммитов. Здесь уже мы решили через npm
поставить специальный хук, который будет перед созданием коммита проверять его.
Для решения задачи валидации нужно установить пакет @commitlint/cli
и husky
. Первый проверяет коммиты, а второй реализует клиентские хуки для git
. Но тут мы столкнулись с проблемой проверки, так как у нас node стоит через nvm и PHPStorm отказывается это принимать, хотя в конфигах самого PHPStorm ссылки корректные. Возможно, тут кто-то еще не знает про это, но это уже не важно, так как мы решили данную проблему через скрипты npm.
В секцию scripts package.json
нужно добавить установку самого husky и добавление хука на commit-msg
в git:
{
"scripts": {
...
"prepare": "husky install && npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}'"
}
}
Эта часть реализует то, что было написано выше, но проблема с проверкой версии ноды при коммите через PHPStorm не решилась, хотя через терминал все работает корректно.
Долго читая документацию и разбирая скрипты, я понял, что в скрипте (создается после выполнения скрипт в prepare) .husky/_/husky.sh
есть код:
if [ -f ~/.huskyrc ]; then
debug "sourcing ~/.huskyrc"
. ~/.huskyrc
fi
Он проверяет наличие файла .huskyrc в домашнем разделе пользователя UNIX систем. Если он есть, то смотрит то, что там написано. Как раз в этом файле можно явно указать где лежит node в системе.
Для автоматизации процесса для UNIX системы мы обновили секцию prepare и добавили туда создание этого файла в домашнюю директорию пользователя:
{
"scripts": {
...
"prepare": "husky install && npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}' && echo \"export PATH=\\\"$(dirname $(which node)):\\$PATH\\\"\" > ~/.huskyrc\n"
},
}
Соответственно, создался файл с содержимым (версия ноды может быть другой у вас):
export PATH="/home/ТУТ_ПОЛЬЗОВАТЕЛЬ_UNIX/.nvm/versions/node/v14.20.1/bin:$PATH"
После чего тестируем. Создаем кривой коммит сами: git commit -m "error
" - получаем ответ:
Теперь, все работает, но хотелось бы немного ограничить разработчиков и "заставить" писать коммиты по правилам. Помните, мы подключали commitlint/cli? Так вот эта штука регламентирует правила. Подробнее про правила можно прочитать тут.
Чтобы правила заработали, создаем в корне проекта файл .commitlintrc.js с содержимым:
module.exports = {
rules: {
// Тело коммита должно начинаться с пустой строки
'body-leading-blank': [2, 'always'],
// Нижний колонтитул коммита должен начинаться с пустой строки
'footer-leading-blank': [2, 'always'],
// Максимальная длина заголовка 72 символа
'header-max-length': [2, 'always', 72],
// Область всегда только в нижнем регистре
'scope-case': [2, 'always', 'lower-case'],
// Описание не может быть пустым
'subject-empty': [2, 'never'],
// Описание не должно заканчиваться '.'
'subject-full-stop': [2, 'never', '.'],
// Тип всегда только в нижнем регистре
'type-case': [2, 'always', 'lower-case'],
// Тип не может быть пустым
'type-empty': [2, 'never'],
// Перечислим все возможные варианты коммитов
'type-enum': [
2,
'always',
[
'build',
'ci',
'docs',
'feat',
'fix',
'perf',
'refactor',
'revert',
'style',
'test',
],
],
},
};
После чего делаем будут дополнительные правила проверки каждой секции. Секции можно посмотреть на сайте Conventional Commits в разделе Summary.
Подытожим. С помощью этих плагинов и подходов удалось стандартизировать коммиты, сделать проверку правильности коммитов, решить вопрос с NVM установкой, автоматизировать реализацию данных компонентов.
Комментарии (6)
pOmelchenko
21.12.2022 21:29Я правильно понимаю, что оно коммитит все изменения, а не только то что я хочу (выбрать файл, выбрать строки)?
mepihin Автор
22.12.2022 13:06Вы можете сделать коммит так, как вам удобно. Ведь, коммит делается после того, как вы добавили файлы.
ggo
22.12.2022 10:00Но, это надоело и стало как-то неудобно, когда у нас есть четкое деление задач на фиксы, фичи и так далее.
А зачем вам деление на фиксы, фичи и так далее? Вот вы видите эти коммиты раздельно, и что?
вопрос с подкавыркой ;)
mepihin Автор
22.12.2022 13:08Ну да, еще с какой подкавыркой. В общем случае, захотелось как-то стандартизировать решение это. А деление на типы коммитов поможет определить кто, что и сколько делал. С другой стороны, можно поставить тэги на задачу, мол БАГ/ФИЧА и так далее, но тут я даже не знаю. Лично мне было бы круто видеть в истории гита не только то, что за задача была, а что именно человек делал, чтобы не лезть в хаб/лаб.
UMenyaNeudobnieVoprosiki
И после всех этих манипуляций и страданий в истории изменений в IDE, а ещё лучше через
git shortlog --no-merges HEAD --not ${prev_release}
вам показывает что? Я просто когда вижу все эти конвеншнл [fix] #1234 fix for prev fix вместо нормального человекочитаемого текста - всегда хочу спросить у автора, а делал то ты что?Стараюсь писать нормальный тайтл с номером задачи в конце и этого более чем хватает. В тушку могу пояснений написать. Оно отлично читается и в IDE (даже если все боковые расхлопушки максимально узкие), и как выхлоп для release notes, и в
git log --oneline
, а номер задачи отлично превращается в ссылку на гитлабе или, например, в GitExtensions, которая поведёт напрямую в трекер одним кликом.А можно добавить в алиас немного магии
report = "!me=$(git config user.email); git log --all --author-date-order --since=1 --reverse --no-merges --pretty=time --date=format:'%Y-%m-%d %H:%M:%S' --author=\"$me\""
и
git report
будет вам помогать даже время трекать по таскамmepihin Автор
Соглашусь с вами. Лично мне данный (о чем я говорит) "шаблон" коммитов нравится и кажется достаточно информативным. Вместо scope, как описано в правилах, можно писать номер задачи: