コミットメッセージを自動で最適化するツールcommitzenの導入方法

### 統一感のない適当なコミットメッセージから抜けろ

チーム開発時の適当なコミットメッセージを書いてしまうことありませんか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3303371/efd377b8-1df5-4eef-5bf9-8f6880c1eaf6.png)

:::note warn
統一性のない適当なコミットメッセージ
:::

コミットメッセージのフォーマットを統一するためには、"Conventional Commits"という規約が有効です

https://www.conventionalcommits.org/ja/v1.0.0/

簡単に言うとこう言うフォーマットにしましょうと言うもの
```
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
```

# 今回はこのフォーマットに自動でcommitしてくれるツールを導入する方法をお伝えします

ぜひ統一感のあるコミットメッセージを開発で使いGit生活を役立ててください

## 自動でコミットメッセージが規約に沿っているかをチェックするツール

まずはフォーマッターを入れます

https://commitlint.js.org/#/
```shell
npm install --save-dev @commitlint/cli @commitlint/config-conventional
```
package.json内に追記↓
```json
 "commitlint": {
   "extends": [
       "@commitlint/config-conventional"
   ]
}
```


```shell
git commit -m "規約に沿っていないコミットメッセージ"
```
実際に規約に沿っていないメッセージを入れると教えてくれます
```shell

 %  npx commitlint --from=HEAD~1                                                                                                                        [firebase]
⧗   input: 規約に沿っていないコミットメッセージ
✖   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
```

## commit時に自動でチェックをする
毎回やるのは面倒くさいので自動でチェックしてもらいましょう

https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%83%95%E3%83%83%E3%82%AF

今回はこちらを使います

https://typicode.github.io/husky/

インストールをして
```shell
npm install husky --save-dev
```
実行
```shell
npx husky init
```

※scripts の prepare は特殊で、npm install の前に自動で実行されます。
```shell
npx husky-init && npm install
```
```shell
npx husky add .husky/commit-msg  'npx --no -- commitlint --edit ${1}' 
```
これでコミット時に自動チェック

:::note alert
この時出力される./husky/pre-commitファイルは削除しましょう
エラーの原因です
:::

## プロンプトから実行する

https://commitizen.github.io/cz-cli/

インストール
```shell
npm install --save-dev commitizen
```

```shell
npx commitizen init cz-conventional-changelog --save-dev --save-exact
```
package.jsonに追記↓

```json
  "scripts": {
     "commit": "cz", 
   #面倒臭い人は"commit": "git add . && cz && git push"
   }
```
下記コマンドで実行可能
```shell
npm run commit 
```

### 実際に使ってみる

```
% npm run commit 
? Select the type of change that you're committing: fix: A bug fix
　　# コミットの種類を選択してください

  feat:     A new feature   #新しい機能 
> fix:      A bug fix   #バグ修正
  docs:     Documentation only changes   #ドキュメンテーションのみの変更
  style:    Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)   #コードの意味に影響を与えない変更（空白、フォーマット、セミコロンの不足など）
  refactor: A code change that neither fixes a bug nor adds a feature   #バグを修正せず、新しい機能を追加しないコードの変更
  perf:     A code change that improves performance   #パフォーマンスを向上させるコードの変更
  test:     Adding missing tests or correcting existing tests   #不足しているテストの追加または既存のテストの修正
  build:    Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)   #ビルドシステムまたは外部の依存関係に影響を与える変更（例: gulp、broccoli、npm） 
  ci:       Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)   #CI構成ファイルおよびスクリプトへの変更（例: Travis、Circle、BrowserStack、SauceLabs）
  chore:    Other changes that don't modify src or test files   #ソースまたはテストファイルを変更しないその他の変更
  revert:   Reverts a previous commit   #以前のコミットを元に戻す
  
? What is the scope of this change (e.g. component or file name): (press enter to skip)   
# 変更のスコープは何ですか（例: コンポーネントまたはファイル名）: (Enter キーを押してスキップ)*Enter推奨

? Write a short, imperative tense description of the change (max 95 chars):
 (16) git commit 時にも適応
 # 変更の簡潔で命令的な説明を入力してください（最大 95 文字）:*必須

? Provide a longer description of the change: (press enter to skip)
 # 変更の詳細を提供してください（Enter キーを押してスキップ）＊Enter推奨

? Are there any breaking changes? No
# 重大な変更がありますか？

? Does this change affect any open issues? No
# この変更は既存の問題に影響しますか？
```

### 適当なコミットメッセージを入力すると
```shell
git commit -m "test"                                                                                                                                      
⧗   input: test
✖   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 exited with code 1 (error)
```
きちんとエラーが発生します

### コミットメッセージをテンプレート化してより良いチーム開発を！

参考文献

https://zenn.dev/risu729/articles/latest-husky-lint-staged

https://zenn.dev/horitaka/articles/commit-message-rules