広告

commitlint+commitizenでコミット履歴をきれいに保つ方法

2021年12月25日

チーム開発の経験がある方であれば、コードレビューの際、コミットメッセージを見てもどこをどう変更したのか分からず、結局ソースコードを見るハメになった経験はあるかもしれません。

また、コミットメッセージのルールを設定しても、タイプミスや、不注意などによってルールを逸脱してしまうこともあり、レビュアにさらなる負担を強いることになります。

この記事では、このような分かりづらいコミットで構成されたマージリクエストをレビューする苦痛を解消するのに役立つOSS(オープンソースソフトウェア)をご紹介します。

この記事でできるようになること

  • 対話形式でメッセージを入力するだけで、ルールに沿った形式でコミットできる
  • ルールに適合しているメッセージのみ、コミットさせられる
  • conventional commits、gitmojiやなどのルールに変更できる

ルールに沿ったコミットメッセージだけコミットさせる

commitlintとhuskyを使用して、コミット時にメッセージの形式をチェックするためのフックを設定します。

また、今回はコミットメッセージのルールとして、下記のような、gitmojiを使ったconventional commitsを採用します。

gitmoji <subject>(scope): message

commitlintとhuskyとは?

commitlintはコミットルールを遵守させるためのOSSです。似たようなOSSは他にもありますが、ドキュメントもしっかり作られており、パッケージスコアも申し分なく、ライセンスもMITであることから、調べた中では最もオススメできるパッケージです。

続いて、huskyはgit hookを簡単に使えるようにしたもので、angularやwebpackなどにも採用されている人気パッケージです。commitlintが公式に推奨していることもあり、こちらも採用します。

導入手順

まず、commitlintと一緒に共有設定のパッケージをインストールします。

公式のドキュメントではconventional commitsで記述されていますが、今回はgitmojiを使うため、commitlint-config-gitmojiを使用します。

npm install -D @commitlint/cli commitlint-config-gitmoji

yarn add --dev @commitlint/cli commitlint-config-gitmoji

インストールし終えたら、gitmojiを使うための設定ファイルを作成します。

echo "module.exports = {extends: ['gitmoji']}" > commitlint.config.js

続いて、公式のドキュメントを参考にhuskyを導入します。

# Install Husky v6
npm install husky --save-dev
# or
yarn add husky --dev

# Active hooks
npx husky install
# or
yarn husky install

# Add hook
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'
# or
yarn husky add .husky/commit-msg 'yarn commitlint --edit $1'

フックを設定し終えたら、ルールに合致しない形式でコミットしてみて、下記のようにエラーが発生していれば成功です。

⧗   input: test
✖   Your commit should start with gitmoji code,please check the emoji code on https://gitmoji.dev/. [start-with-gitmoji]
✖   subject may not be empty [subject-empty]
✖   type may not be empty [type-empty]

✖   found 3 problems, 0 warnings
ⓘ   Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

公式のドキュメントにもありますが、nvmなどのnodeバージョンマネージャを利用している場合、npx: command not foundというようなエラーが発生する場合は、下記のようにパスを通すことでエラーを解消できます。

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
​
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
npx --no -- commitlint --edit
​

ルールの変更方法

commitlintのルールを変更する際は、commitlintの公式ドキュメントを参考に、commitlint.config.jsを作成します。

今回はヘッダー長を最大100文字とし、subjectの種類を拡張します。デフォルトでは、fixや、featなどの特定の単語しかsubjectに設定できないためconfig security upgrade plus minusをsubjectに追加します。

module.exports = {
  extends: ['gitmoji'],
    rules: {
      'header-max-length': [0, 'always', 100],
      'type-enum': [2, 'always',
       ['feat', 'fix', 'test', 'refactor', 'style', 'docs', 
        'perf', 'config', 'security', 'upgrade', 'plus', 'minus'
               ],
    ],},
}

対話形式でコミットメッセージを入力できるようにする

commitlint+huskyで十分な気もしますが、たまにしか使わないsubjectやgitmojiは忘れがちなので、対話形式でメッセージを入力できるcommitizenも併用して使い分けるのがオススメです。

commitizenとは

commitizenは、CLIでコミットする際に、対話形式でメッセージを入力することで、ルールに沿った形式でコミットメッセージを記述できるOSSです。

通常のコミットに比べると多少手間がかかりますが、「この変更のsubjectってなんだっけ?」みたいなときに、テンプレートを確認する手間が省けるのが嬉しいところです。commitlint同様、アダプターを導入すれば、emojiや独自のテンプレートなどのルールに変更できます。

commitizenの導入

commitizenと同時に、設定をカスタマイズするためのcz-customizableをインストールします。

npm i -D commitizen cz-customizable

yarn add --dev commitizen cz-customizable

次に、package.jsonにcommitzenの設定を追加し、cz-customizableを参照させます。

{
  ...
    "config": {
    "commitizen": {
      "path": "cz-customizable"
    }
  },
  ...
}

ルールの変更方法

続いて、ルールに変更を加えるため.cz-config.jsを作成します。gitmojiについては、公式ページを参照してください。

なお、さきほど紹介したcommitlint-config-gitmojiなどのconfig系のパッケージは人気度が低く、メンテナンスも十分されていない場合が多いため、少し注意が必要です。

module.exports = {
  types: [
    { name: 'feat \t✨ New feature', value: ':sparkles: feat' },
    { name: 'fix \t🐛 Bug fix', value: ':bug: fix' },
    { name: 'test \t✅ Add, update, or pass tests', value: ':white_check_mark: test' },
    { name: 'refactor \t♻️ Refactor code', value: ':recycle: refactor' },
    { name: 'wrench \t🔧 Add or update configuration', value: ':wrench: config' },
    { name: 'style \t💄 Add or update the UI and style files', value: ':lipstick: style' },
    { name: 'docs \t📝 Change Documentation', value: ':memo: docs' },
    { name: 'perf \t⚡ Improves performance', value: ':zap: perf' },
    { name: 'security \t🔒 Fix or prevent security issue', value: ':lock: security' },
    { name: 'upgrade \t⬆ Upgrade dependency', value: ':arrow_up: upgrade' },
    { name: 'plus \t➕ New dependency', value: ':heavy_plus_sign: plus' },
    { name: 'minus \t➖ Remove dependency', value: ':heavy-minus-sign: minus' },
  ],
  skipQuestions: ['body', 'footer'],
  scopes: ['api', 'ui'],
  allowCustomScopes: true,
  subjectLimit: 100,
}

試しにnpx czを実行してみると、対話形式で入力できることが確認できます。

最後にgit commitでcommitizenが使えるようにフックを追加したら完了です。

npx husky add .husky/prepare-commit-msg "exec < /dev/tty && node_modules/.bin/cz --hook || true"

まとめ

ここまでで、コミット時のメッセージ形式のチェックと、対話形式でコミットメッセージを入力させる方法についてご紹介しました。

私のチームでも導入してみたところ、ルールの逸脱やタイプミスの多かったメンバーにルールを遵守させることができ、私の負担を軽減できました。

半日程度あれば導入できる上、コミット履歴をキレイに保てるというメリットも有るため、試しに使ってみてはいかがでしょうか?