commitlint + husky でConventional Commitを強制する
gitのコミットメッセージを標準化して、CHANGELOGとかReleaseメッセージ作成の自動化を目指してます。 この目論見の最大の障壁が「みんなが指定したフォーマットの通りにコミットメッセージを書いてくれるかどうか」 […]
目次
gitのコミットメッセージを標準化して、CHANGELOGとかReleaseメッセージ作成の自動化を目指してます。
この目論見の最大の障壁が「みんなが指定したフォーマットの通りにコミットメッセージを書いてくれるかどうか」という点です。
「やってね」と言って守ってもらえたらGitHubでブランチをプロテクトしたりする必要もないわけですよね。
なのでコミットメッセージをリントして、従うことを強制する方法をさらってみました。
インストール
commitlintのCLIとconfigをインストールします。また、git commit時のフックを使うため、huskyも入れましょう。
$ yarn add -D @commitlint/cli @commitlint/config-conventional husky
セットアップ
リントツールですので、設定ファイルを作ります。
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
カスタマイズできそうですが、とりあえず今はデフォルトに従っておきましょう。
直近のコミットメッセージで試してみる
まずは実際に動くところを確認してみようということで、最後のコミットメッセージに対してリントを実行してみます。
// Conventional Commitに「従っていない」コミットを作る
$ touch dummy
$ git add dummy && git commit -m "foo: bar"
$ ./node_modules/.bin/commitlint --from HEAD~1 --to HEAD --verbose
⧗ input: foo: bar
✖ type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test] [type-enum]
✖ found 1 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
コミットメッセージ「foo: bar」がルールに従っていないという内容が表示されました。
これをCIやpre-commitフックに適用すればよさそうですね。
git commit時のリントをオンにする
pre-commitでcommitlintを実行するには、huskyを利用します。
$ vim .huskyrc
{
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
}
この状態でgit commitを実行すると、コミットメッセージに対するリントが実行されます。
$ git rm dummy
$ git commit -m "remove dummy file"
husky > commit-msg (node v10.5.0)
⧗ input: remove dummy file
✖ subject may not be empty [subject-empty]
✖ type may not be empty [type-empty]
✖ found 2 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
husky > commit-msg hook failed (add --no-verify to bypass)
今度もエラーが出ました。これで少なくともCLIからのgit commitに関しては、ルールに従うことを必須条件にできそうです。
$ git commit -m "chore: update config"
husky > commit-msg (node v10.5.0)
[master a8d4f4b] chore: update config
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 dummy
ルールに従っていれば、このようにスムーズにコミットしてくれます。
CI上で実行する
Travis CI限定ですが、CI上で実行できるライブラリも存在します。
$ npm install --save-dev @commitlint/travis-cli
$ vim travis.yml
language: node_js
script:
- commitlint-travis
ちなみにこのツール、環境変数をがっつりチェックしてきますので、Circle CIやローカル環境で実行することは難しそうです。
$ npx @commitlint/travis-cli
Error: @commitlint/travis-cli is intended to be used on Travis CI
ざっとコードをみる限り、以下の環境変数を自前で再現する必要がありました。
- CI
- TRAVIS
- TRAVIS_COMMIT
- TRAVIS_COMMIT_RANGE
- TRAVIS_EVENT_TYPE
- TRAVIS_REPO_SLUG
- TRAVIS_PULL_REQUEST_SLUG
おわりに
エラー時のメッセージで、「このようにメッセージを書いてください」と案内がありますので、慣れること自体はあまり難しくなさそうです。
ただし、1個人の判断で突然導入すると間違いなくチーム内で揉めます。なので「CIでチェックはするが、ブロックはしない」や「使い方の周知期間をもうける」などの準備をした上で導入することをオススメします。
個人のプロジェクトで、Conventional Commitに慣れるために入れるところからやるのが一番かもしれません。