Спустя примерно 2 года использования git hooks на базе Husky.NET захотелось внести изменения в их работу
Сперва пара слов как это работало раньше:
1. На pre-commit hook вызывается dotnet format, dotnet build и dotnet test
2. На commit hook проверяется соответствие сообщения коммита к conventional commits
Так было сделано чтобы каждый коммит был рабочим: и билдился и проходили тесты. Очень полезно, если в команде принято использовать git merge для слияния веток.
У меня в команде применяется только git rebase и squash commits при принятии PR. И сквош как раз лишал смысла делать каждый из коммитов "рабочим", так как история коммитов по сути переписывается.
К тому же оформление каждого коммита занимает много времени из-за запуска форматирования, билда и тестов.
И особенно досадно, когда прошли форматирования, билды и тесты, но ты просто ошибься в тексте коммита и надо все запускать сначала.
Сам Husky.NET шикарный инструмент, но есть ряд ограничений которые не позволяли сделать его использование по-настоящему удобным.
Что дают переосмысленные git hooks теперь:
1. После вызова команды git commit сразу же запускается хук prepare-commit-msg
Он берет номер задачи в формате Jira из названия ветки и добавляет в коммит. А если не задан тип коммита (fix/feat/perf etc), то добавляет и его в виде "chore".
К примеру был коммит с сообщением xx в ветке SSTV-123. Тогда текст сообщения коммита будет chore(SSTV-123): xx
Если коммит был feat: xx, то станет feat(SSTV-123): xx
2. В commit-msg хуке выполняется валидация что тип коммита задан, что номер задачи из текущего проекта (префикс) и в целом длина коммита не превышает 90 символов и нет лишних пробелов или точки в конце
3. Когда разработчик нажимает отправить в удаленный репозиторий, то в pre-push хуке проверяется, были ли изменения в *.cs файлах среди всех еще не запушенных коммитов в этой ветке.
Если такие есть - они форматируются, выполняется dotnet build и dotnet test.
Именно этот пункт не получится сделать через Husky.NET т.к. он заточен только под текущие изменения до фиксации коммита.
Далее если после форматирования появились изменения, то автоматически будет создан коммит "chore: auto formatting".
Следом запускается dotnet test. Если в тестах используются снепшот тесты, то они могут измениться. В таком случае пуш не пройдет т.к. нужно проверить почему они были изменены и закоммитить только если соответствуют новой логике.
Если хочется сделать пуш и при этом есть незакомиченные изменения - будет тоже самое. Здесь я пока не придумал как красиво поддержать оба сценария.
Полезные ссылки:
* Про написание снепшот тестов с помощью библиотеки Verify
* Подробнее про прошлый подход с Husky.NET
* Код с новым подходом
Сперва пара слов как это работало раньше:
1. На pre-commit hook вызывается dotnet format, dotnet build и dotnet test
2. На commit hook проверяется соответствие сообщения коммита к conventional commits
Так было сделано чтобы каждый коммит был рабочим: и билдился и проходили тесты. Очень полезно, если в команде принято использовать git merge для слияния веток.
У меня в команде применяется только git rebase и squash commits при принятии PR. И сквош как раз лишал смысла делать каждый из коммитов "рабочим", так как история коммитов по сути переписывается.
К тому же оформление каждого коммита занимает много времени из-за запуска форматирования, билда и тестов.
И особенно досадно, когда прошли форматирования, билды и тесты, но ты просто ошибься в тексте коммита и надо все запускать сначала.
Сам Husky.NET шикарный инструмент, но есть ряд ограничений которые не позволяли сделать его использование по-настоящему удобным.
Что дают переосмысленные git hooks теперь:
1. После вызова команды git commit сразу же запускается хук prepare-commit-msg
Он берет номер задачи в формате Jira из названия ветки и добавляет в коммит. А если не задан тип коммита (fix/feat/perf etc), то добавляет и его в виде "chore".
К примеру был коммит с сообщением xx в ветке SSTV-123. Тогда текст сообщения коммита будет chore(SSTV-123): xx
Если коммит был feat: xx, то станет feat(SSTV-123): xx
2. В commit-msg хуке выполняется валидация что тип коммита задан, что номер задачи из текущего проекта (префикс) и в целом длина коммита не превышает 90 символов и нет лишних пробелов или точки в конце
3. Когда разработчик нажимает отправить в удаленный репозиторий, то в pre-push хуке проверяется, были ли изменения в *.cs файлах среди всех еще не запушенных коммитов в этой ветке.
Если такие есть - они форматируются, выполняется dotnet build и dotnet test.
Именно этот пункт не получится сделать через Husky.NET т.к. он заточен только под текущие изменения до фиксации коммита.
Далее если после форматирования появились изменения, то автоматически будет создан коммит "chore: auto formatting".
Следом запускается dotnet test. Если в тестах используются снепшот тесты, то они могут измениться. В таком случае пуш не пройдет т.к. нужно проверить почему они были изменены и закоммитить только если соответствуют новой логике.
Если хочется сделать пуш и при этом есть незакомиченные изменения - будет тоже самое. Здесь я пока не придумал как красиво поддержать оба сценария.
Полезные ссылки:
* Про написание снепшот тестов с помощью библиотеки Verify
* Подробнее про прошлый подход с Husky.NET
* Код с новым подходом