Featured image of post Gitフックによる自動化:コード品質を超えて Featured image of post Gitフックによる自動化:コード品質を超えて

Gitフックによる自動化:コード品質を超えて

Gitフックによる自動化の包括的ガイド:pre-commit、pre-push、commit-msg、husky、lint-staged、カスタムスクリプト、共有フック、CI同等性まで。

はじめに

Gitフックは、Gitライフサイクルの特定の時点で自動実行されるスクリプトです。多くの開発者はコードフォーマットやリンティングだけに利用していますが、その可能性はワークフロー自動化、プロジェクト管理、チームコラボレーションへと広がります。本記事では、Gitフックを活用した包括的な自動化戦略を解説します。

Gitフックの基礎

Gitフックは各リポジトリの .git/hooks/ ディレクトリに配置されます。bash、Python、Node.js、Rubyなど、任意の言語で記述可能な実行可能スクリプトです。フックはクライアントサイドフック(pre-commit、pre-push、commit-msg)とサーバーサイドフック(pre-receive、update、post-receive)に分類されます。

コミット時のフック実行順序は pre-commitcommit-msgpost-commit です。プッシュ時は pre-push(クライアント)→ pre-receiveupdatepost-receive(サーバー)の順に実行されます。

Huskyによるフック管理

.git/hooks/ に手動でスクリプトを配置する方法は、そのディレクトリがGit管理外であるためチーム共有に適しません。Huskyはフックをリポジトリ内で管理し、チーム全体で共有できるようにします。

Husky v9+のインストール:

npx husky init

.husky/ ディレクトリにフックスクリプトを作成します:

# .husky/pre-commit
npx lint-staged

CI環境では HUSKY=0 でフックをスキップできます:

HUSKY=0 git push

lint-stagedとの連携

lint-stagedはステージングされたファイルのみに対してリンターを実行し、高速なチェックを実現します:

{
  "lint-staged": {
    "*.{ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.{css,scss}": ["stylelint --fix", "prettier --write"]
  }
}

Pre-Commitフック:第一防衛線

Pre-commitフックは各コミット前に実行され、高速なローカルチェックに適しています。

チェック種別ツール目的
リンティングESLint, stylelintコードスタイルの統一
フォーマットPrettier, dprint一貫した自動整形
型チェックTypeScript --noEmit型エラーの早期発見
シークレット検出secretlint, truffleHog認証情報の漏洩防止
ファイル検証カスタムスクリプト巨大ファイルやTODOのブロック

包括的なpre-commit設定例:

# .husky/pre-commit
npx lint-staged
npx tsc --noEmit
npx secretlint "**/*"

パフォーマンスは重要です。pre-commitフックは5秒以内に完了するよう設計し、開発の流れを妨げないようにしましょう。


Pre-Pushフック:CIのセーフティネット

Pre-pushフックはコードがリモートリポジトリに到達する前に実行され、より時間のかかる検証に適しています:

# .husky/pre-push
npm test
npm run build
npm audit

ブランチ名の検証で命名規則を強制します:

#!/bin/sh
branch=$(git rev-parse --abbrev-ref HEAD)
if ! echo "$branch" | grep -qE '^(feature|bugfix|hotfix)/[A-Z]+-[0-9]+-'; then
  echo "エラー: ブランチ名は feature/ABC-123-形式に従ってください"
  exit 1
fi

commitlintによるコミットメッセージ検証

Conventional Commits形式の強制により、一貫性のある解析可能な履歴を実現します:

# .husky/commit-msg
npx --no -- commitlint --edit $1

commitlintの設定:

module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'subject-max-length': [2, 'always', 50],
    'body-max-line-length': [2, 'always', 72],
  },
};

CI同等性戦略

フックとCIが同一のチェックを実行することが最も堅牢なパターンです。共有スクリプトを抽出し、両方の環境から呼び出します:

#!/bin/sh
# scripts/validate.sh - フックとCIの両方から呼び出される
npm run lint
npm run typecheck
npm test

ローカルフックは警告や自動修正を行い、CIは厳格に強制するという段階的アプローチが効果的です。


結論

Gitフックはコードフォーマットを超えた強力な自動化レイヤーです。Huskyとlint-stagedの組み合わせがほとんどのプロジェクトで推奨されるベースラインです。Pre-pushフックはCIに到達する前のセーフティネットを提供し、commitlintはクリーンなコミット履歴を保証します。最終目標は、自動化が反復的なチェックを処理し、開発者がロジックと設計に集中できる環境を実現することです。