【Git】コミット時のコードフォーマット、テストの自動化について
こちらは、Mavs Advent Calendar2023の14日目の記事です!🍗
ハコザキです
PrettierやESlintなどのコードフォーマットやテストコードの実行のタイミングはプロジェクトによって様々です。
PR時にCI/CDで実行させる方法もあれば、
コードフォーマットはローカル、テストコードの実行はPR時に実行、
テスト成功しない限りマージできないようにするルール などがあると思います。
GitHub ActionsやBitbucketパイプライン、
AWS CodePipelineなどのCI/CDサービスを使えば、
ログが見やすくなったり、Slackなどと連携し通知設定を行うことができます。
しかし大規模になると料金が発生する恐れや、移行時に多少ですが手間になります..!
※ GitHub Actionsはパブリックリポジトリであれば無料、
プライベートリポジトリでも月当たりの無料枠が設けられています。(無料枠 + 従量課金)
GitHub Actions の課金について – GitHub Docs
※ BitbucketパイプラインはFreeユーザーで月50分までは無料です。
Bitbucket Pipelines – 継続的デリバリー | Bitbucket
今回はNuxt3のプロジェクトにhusky + lint-stagedを導入し、
pre-commit時に差分あるファイルのコードフォーマット実行やテストコードの実行を行い
Lintエラーがゼロ かつ テスト通過 のみコミットできるような環境を構築してみたいと思います!!
準備
Nuxt3 環境構築
Nuxt3 + Vitest + Prettier + ESLint につきましては、こちらのリポジトリをもとに進めます。
https://github.com/p-t-a-p-1/nuxt3-vuetify-starter
詳しい構築方法は以下の記事で紹介しております。
【Nuxt3】Vuetify3 + Vitestで単体テスト実行環境を構築
今回はこの環境を使用した上で進みたいと思います。
まずはhusky, lint-stagedについてご紹介します。
huskyとは
huskyとは、コミットやプッシュといった特定のGit操作時に、
任意の処理を実行することができるツールです。
コミットメッセージのlintやテストの実行、コードの lintなどを行うことができます。
husky実行時に、Lintエラーなど処理が途中で止まることがあれば
コミットやプッシュなどのGit操作は正しく行われないため、
コードの品質をある程度保つことができます。
( = 処理を通過したコードのみGit操作が可能になる)
husky公式ドキュメント
公式ドキュメントに🐶の絵文字があったため、
シベリアン・ハスキーもなにかしら関係があるのかもしれません..(?)

lint-stagedとは
huskyとあわせてよく使用されるlint-stagedですが、
こちらはGit操作によって、ステージング環境にあるファイルに対してのみ
任意のアクションをするためのライブラリです。
ESLintやPrettierなどについては、毎回全ファイルチェックする必要はなく
追加・変更が発生したファイルに対してのみ実行させればよいです。
huskyの導入
実際にプロジェクトにhuskyを導入していきます。
※ 今回パッケージマネージャにpnpmを使用しています
pnpm dlx husky-init && pnpm install
上記コマンドを実行すると、このように .husky
フォルダが生成されます。

.husky/pre-commit
ファイル内は以下のようになっていると思います。
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm test
初期状態では、git commitコマンド実行後、
commit処理が走る直前でnpm test
が実行されるようになってます。
動作確認として、.husky/pre-commit
を以下のように編集し、適当に文字列出力してみます
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
echo '🐶\nhusky実行\n🐶'
Git操作を行い、huskyの動作確認を行います。
以下のようにgit commit時にこの用に文字列が表示されていればokです!
git commit -m "add husky設定追加"
🐶
husky実行
🐶
[main 3a541f7] add husky設定追加
GUIからのGit操作
CUI操作の場合は上記のように動作しますが、VSCodeやSourceTreeなどGUIでのGit操作の際は、
PATHを通してあげる必要があります。
今回はVolta等のパッケージマネージャにあわせてPATHを指定します。
パッケージマネージャを使用していない場合はNodeのパスを指定することで動作します。
以下はVoltaの例です。
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
export VOLTA_HOME="$HOME/.volta"
export PATH="$VOLTA_HOME/bin:$PATH"
echo '🐶\nhusky実行\n🐶'
.huskyrcというファイルを作成し以下のように分けても動作します。
export VOLTA_HOME="$HOME/.volta"
export PATH="$VOLTA_HOME/bin:$PATH"
lint-staged導入しESLint + Prettierの実行
lint-stagedも導入します。
pnpm i -D lint-staged
続いて、package.jsonに以下を追記します。
...,
"lint-staged": {
"*.{js,ts,vue}": [
"pnpm run lint",
"pnpm run format"
]
}
.husky/pre-commit
を以下のように追記します。
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
export VOLTA_HOME="$HOME/.volta"
export PATH="$VOLTA_HOME/bin:$PATH"
echo '🐶\nhusky実行\n🐶'
echo 'ESLint & Prettier実行'
npx lint-staged
これでlint-stagedが実行された際、
対象ファイルにESLint + Prettierでのコードフォーマットを実行することができました。
このようにあえてLintエラーが表示されているファイルをコミットした場合は、
エラーが発生しコミットできなくなります。

Vitestによるテストの自動実行
ESLint + Prettierでコードフォーマットを行った後、
全テストファイルの実行を行いたいと思います。
.husky/pre-commit
に以下を追記します。
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
export VOLTA_HOME="$HOME/.volta"
export PATH="$VOLTA_HOME/bin:$PATH"
echo '🐶\nhusky実行\n🐶'
echo 'ESLint & Prettier実行'
npx lint-staged
# 追記
echo 'Vitest実行'
pnpm run test run
npm スクリプトのテスト実行コマンドを追加しました。
run を追加することで1回のみ実行するようになります。
Lintと同様、テスト失敗の場合はコミットできないようになっているか確認したいと思います。

以下のようにhuskyによるpre-commitフックが途中で止まり
コミットされていないことが確認できました!!
ELIFECYCLE Test failed. See above for more details.
husky - pre-commit hook exited with code 1 (error)
おわり
今回は、追加・変更が発生したファイルに対してはESLint + Prettierのコードフォーマットの実行、
またすべてのテストファイルに対してテストの実行ができるような環境の構築方法についてご紹介しました。
プロジェクトによっては外部サービスを使わず、
このようにローカルで完結させてしまう方法もあると思います。
今回はコードフォーマットとテストコードの実行の設定についてご紹介しましたが、
時間があればcommitlintを使用したコミットメッセージのLint方法もご紹介したいと思います!!