Git ガバナンス運用:レビュー必須・チェックルール・承認フローの作り方
チーム開発が進むにつれて、コードの品質管理や運用ルールの統一が課題になってきますよね。「誰かがレビューせずにマージしてしまった」「本番ブランチに直接コミットされた」といった問題を防ぐには、Git のガバナンス運用が欠かせません。
本記事では、GitHub や GitLab を使ったレビュー必須化、チェックルールの設定、承認フローの構築方法を段階的に解説します。これにより、チーム全体でコード品質を保ちながら、安全かつ効率的な開発フローを実現できるでしょう。
背景
Git ガバナンスとは
Git ガバナンスとは、リポジトリへのアクセス権限やブランチ保護、コードレビュープロセスなどを体系的に管理する仕組みです。 開発チームが大きくなると、各メンバーのスキルレベルや経験値にばらつきが生じ、コードの品質が不安定になりがちですね。 そこで、統一されたルールを導入することで、誰が・いつ・どのようにコードを変更するかを明確にし、品質とセキュリティを維持します。
ガバナンスが必要になる場面
以下のような状況では、ガバナンス運用の導入が特に有効です。
- 複数人で同じリポジトリを編集し、競合や意図しない変更が頻発する
- 本番環境へのデプロイ前に必ずレビューを通したいが、ルールが曖昧
- CI/CD パイプラインを導入しており、テストやビルドの成功を必須にしたい
- コンプライアンスや監査要件で、変更履歴と承認記録を残す必要がある
こうした課題を解決するために、Git プラットフォームには Branch Protection Rules や Merge Request の approval 機能など、ガバナンスを支える機能が用意されています。
下図は、ガバナンスを導入する前後の開発フローの違いを示したものです。
mermaidflowchart LR
before["ガバナンスなし"] -->|直接コミット| main1["main ブランチ"]
main1 -->|品質バラバラ| deploy1["デプロイ"]
after["ガバナンス導入"] -->|Pull Request| review["コードレビュー"]
review -->|CI チェック| checks["自動テスト/<br/>リント"]
checks -->|承認| approve["承認者の確認"]
approve -->|マージ| main2["main ブランチ"]
main2 -->|品質担保| deploy2["デプロイ"]
ガバナンスを導入することで、レビューや自動チェックを経由した安全なマージフローが実現できます。
課題
よくあるガバナンス不足の問題
ガバナンスが不十分なリポジトリでは、以下のような問題が起こりやすくなります。
直接マージによる品質低下 レビューなしで本番ブランチに直接マージされると、バグや脆弱性が混入するリスクが高まります。 特に緊急対応時など、ルールが曖昧だと「今回だけ」という例外が常態化してしまうでしょう。
チェックルールの未整備 CI/CD でテストやリントを実行していても、それらが失敗してもマージできてしまうと意味がありません。 自動チェックを「必須」として設定しないと、開発者の判断に委ねられ、品質が安定しません。
承認フローの不明確さ 誰が承認権限を持つのか、何人の承認が必要なのかが決まっていないと、レビュー待ちが長引いたり、逆に形骸化したりします。 特に組織が拡大すると、役割分担を明確にしないと混乱が生じますね。
以下の図は、ガバナンス不足で発生しうる問題の連鎖を表しています。
mermaidflowchart TD
start["ガバナンス不足"] --> issue1["直接 main へマージ"]
issue1 --> issue2["レビューなし"]
issue2 --> issue3["品質低下/<br/>バグ混入"]
issue3 --> issue4["本番障害"]
start --> issue5["CI チェック未必須化"]
issue5 --> issue6["テスト失敗でも<br/>マージ可能"]
issue6 --> issue3
start --> issue7["承認者不明確"]
issue7 --> issue8["レビュー遅延/<br/>形骸化"]
issue8 --> issue3
これらの問題を防ぐため、次章では具体的な解決策を見ていきます。
解決策
GitHub での Branch Protection Rules 設定
GitHub では、リポジトリ設定の「Branches」から保護ルールを設定できます。 これにより、main ブランチなど重要なブランチへの直接コミットを禁止し、Pull Request 経由でのみマージを許可することが可能です。
ブランチ保護ルールの有効化手順
- リポジトリの Settings ページを開く
- 左メニューから「Branches」を選択
- 「Add branch protection rule」をクリック
- 保護対象のブランチ名(例:
main)を指定 - 必要なルールにチェックを入れる
主要な設定項目は次のとおりです。
| # | 設定項目 | 説明 |
|---|---|---|
| 1 | Require a pull request before merging | マージ前に必ず Pull Request を作成 |
| 2 | Require approvals | 指定人数の承認を必須化 |
| 3 | Require status checks to pass | CI/CD チェックの成功を必須化 |
| 4 | Require conversation resolution before merging | コメントの解決を必須化 |
| 5 | Include administrators | 管理者にもルールを適用 |
レビュー必須化の設定
「Require approvals」にチェックを入れ、必要な承認者数を設定します。 たとえば「2 人の承認が必要」とすれば、最低 2 名のレビュアーが Approve しないとマージできません。
yaml# .github/CODEOWNERS ファイル例
# チーム別にレビュアーを自動割り当て
* @org/team-leads
/src/api/ @org/backend-team
/src/ui/ @org/frontend-team
上記のようにCODEOWNERSファイルを配置すると、ディレクトリごとに自動的にレビュアーが割り当てられ、承認フローがスムーズになりますね。
CI チェックの必須化
「Require status checks to pass before merging」にチェックを入れ、必須とするチェック項目を選択します。 例えば、以下のようなステータスチェックを必須化できます。
test- ユニットテストの実行lint- コードスタイルチェックbuild- ビルド成功確認security-scan- 脆弱性スキャン
以下は、GitHub Actions で実装した CI 設定の例です。
typescript// .github/workflows/ci.yml(YAML形式)
name: CI
on:
pull_request:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: yarn install --frozen-lockfile
依存関係をインストールした後、テストとリントを実行します。
typescript - name: Run tests
run: yarn test --coverage
- name: Run lint
run: yarn lint
このワークフローが成功しないと、Pull Request をマージできなくなります。
GitLab での Merge Request Approval Rules 設定
GitLab では、Merge Request(MR)に対して詳細な承認ルールを設定できます。 プロジェクト設定の「Settings > Merge requests」から、承認者数やコードオーナーの指定が可能です。
承認ルールの基本設定
- プロジェクトの「Settings」→「Merge requests」を開く
- 「Approval rules」セクションで「Add approval rule」をクリック
- ルール名、必要承認者数、承認者グループを設定
以下のような条件を組み合わせられます。
| # | 設定項目 | 説明 |
|---|---|---|
| 1 | Approvals required | 必要な承認者数(例:2 人) |
| 2 | Eligible approvers | 承認可能なユーザー/グループ |
| 3 | Code Owners | CODEOWNERS ファイルに基づく自動割り当て |
| 4 | Prevent approval by author | 作成者自身の承認を禁止 |
| 5 | Require approval from code owners | コードオーナーの承認を必須化 |
Protected Branches の設定
GitLab でも保護ブランチ機能があり、マージやプッシュの権限を細かく制御できます。
- 「Settings」→「Repository」→「Protected branches」を開く
- 保護するブランチ(例:
main)を選択 - 「Allowed to merge」「Allowed to push」を設定
ここで「Maintainers」のみにマージ権限を付与すれば、一般開発者は直接マージできなくなります。
パイプライン成功の必須化
GitLab CI/CD のパイプラインが成功することを必須にするには、「Merge checks」で以下を有効化します。
- Pipelines must succeed - すべてのジョブが成功しないとマージ不可
以下は.gitlab-ci.ymlの設定例です。
yaml# .gitlab-ci.yml
stages:
- test
- lint
- build
test:
stage: test
image: node:18
script:
- yarn install --frozen-lockfile
- yarn test --coverage
only:
- merge_requests
リントステージとビルドステージも追加します。
yamllint:
stage: lint
image: node:18
script:
- yarn install --frozen-lockfile
- yarn lint
only:
- merge_requests
build:
stage: build
image: node:18
script:
- yarn install --frozen-lockfile
- yarn build
only:
- merge_requests
これらのジョブがすべて成功しない限り、MR をマージできません。
承認フローのベストプラクティス
効果的な承認フローを構築するには、以下のポイントを押さえましょう。
役割ごとの承認者設定 シニアエンジニア、テックリード、セキュリティ担当など、役割に応じて承認者を分けると、専門性を活かしたレビューが可能になります。
承認者数の適正化 承認者が多すぎるとレビューが遅延し、少なすぎると品質が保てません。 一般的には 2〜3 名が適切で、緊急度や変更規模に応じて柔軟に調整するとよいでしょう。
自動レビュアー割り当て CODEOWNERS ファイルを活用すれば、変更箇所に応じて自動的にレビュアーが割り当てられ、手動の手間が省けます。
例外処理の明文化 緊急時のホットフィックスなど、例外的にルールを緩和する場合は、その条件と手順をドキュメント化しておきます。 「緊急対応はテックリード承認のみで可」といった明確な基準を設けることで、混乱を防げますね。
下図は、役割別承認フローの全体像を示しています。
mermaidflowchart TD
pr["Pull Request 作成"] --> auto["自動レビュアー<br/>割り当て"]
auto --> ci["CI チェック実行"]
ci -->|成功| review["コードレビュー"]
ci -->|失敗| fix["修正"]
fix --> ci
review --> dev_approve["開発者レビュー<br/>(1名以上)"]
dev_approve --> lead_approve["テックリード承認<br/>(1名)"]
lead_approve -->|承認完了| merge["マージ"]
lead_approve -->|変更要求| fix
review -->|セキュリティ関連| sec_approve["セキュリティ担当<br/>承認"]
sec_approve --> lead_approve
このように段階的なチェックを経ることで、品質とセキュリティを両立できます。
具体例
GitHub での実装例
ここでは、Next.js + TypeScript プロジェクトで GitHub のガバナンスを実装する具体例を紹介します。
リポジトリ構成
plaintextmy-nextjs-app/
├── .github/
│ ├── workflows/
│ │ └── ci.yml # CI/CD設定
│ └── CODEOWNERS # コードオーナー定義
├── src/
│ ├── api/ # バックエンドAPI
│ ├── components/ # Reactコンポーネント
│ └── pages/ # Next.jsページ
├── package.json
└── tsconfig.json
CODEOWNERS ファイル
変更箇所に応じて自動的にレビュアーを割り当てます。
plaintext# .github/CODEOWNERS
# デフォルト:すべてのファイルはテックリードがレビュー
* @org/tech-leads
# バックエンドAPIはバックエンドチームが担当
/src/api/ @org/backend-team
# フロントエンドはフロントエンドチームが担当
/src/components/ @org/frontend-team
/src/pages/ @org/frontend-team
# 設定ファイルはDevOpsチームが担当
/.github/ @org/devops-team
/package.json @org/devops-team
このファイルをリポジトリルートに配置すると、Pull Request 作成時に自動的にレビュアーが割り当てられます。
GitHub Actions CI 設定
CI/CD パイプラインで、テスト・リント・ビルドを自動実行します。
yaml# .github/workflows/ci.yml
name: CI Pipeline
on:
pull_request:
branches:
- main
- develop
jobs:
setup:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'yarn'
依存関係をインストールします。
yaml- name: Install dependencies
run: yarn install --frozen-lockfile
テストを実行し、カバレッジレポートを生成します。
yamltest:
needs: setup
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'yarn'
- run: yarn install --frozen-lockfile
- name: Run unit tests
run: yarn test --coverage
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
files: ./coverage/coverage-final.json
リントチェックを実行します。
yamllint:
needs: setup
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'yarn'
- run: yarn install --frozen-lockfile
- name: Run ESLint
run: yarn lint
- name: Run TypeScript check
run: yarn tsc --noEmit
ビルドを実行し、成果物を生成します。
yamlbuild:
needs: setup
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'yarn'
- run: yarn install --frozen-lockfile
- name: Build Next.js app
run: yarn build
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: build-output
path: .next/
すべてのジョブが成功しないと、ステータスチェックが失敗し、マージできません。
Branch Protection Rules の設定内容
GitHub のリポジトリ設定で、以下のようにブランチ保護ルールを設定します。
| # | 設定項目 | 設定値 |
|---|---|---|
| 1 | Branch name pattern | main |
| 2 | Require a pull request before merging | ✓ 有効 |
| 3 | Require approvals | 2 人以上 |
| 4 | Dismiss stale pull request approvals | ✓ 有効(新コミット時に承認リセット) |
| 5 | Require review from Code Owners | ✓ 有効 |
| 6 | Require status checks to pass | ✓ 有効 |
| 7 | Status checks | test, lint, build を必須化 |
| 8 | Require branches to be up to date | ✓ 有効 |
| 9 | Require conversation resolution | ✓ 有効 |
| 10 | Include administrators | ✓ 有効 |
この設定により、管理者を含むすべてのメンバーが、レビューと CI チェックを通過しないとマージできなくなります。
GitLab での実装例
次に、同じプロジェクトを GitLab で実装する場合の設定を見ていきましょう。
CODEOWNERS ファイル
GitLab でも同様に CODEOWNERS ファイルを使用できます。
plaintext# CODEOWNERS
# デフォルト
* @tech-leads
# バックエンド
/src/api/ @backend-team
# フロントエンド
/src/components/ @frontend-team
/src/pages/ @frontend-team
# インフラ
/.gitlab-ci.yml @devops-team
/package.json @devops-team
このファイルは、リポジトリルートまたは.gitlab/ディレクトリに配置します。
GitLab CI/CD パイプライン設定
.gitlab-ci.ymlで CI/CD パイプラインを定義します。
yaml# .gitlab-ci.yml
image: node:18
stages:
- install
- test
- lint
- build
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- .yarn/cache/
# 依存関係インストール
install:
stage: install
script:
- yarn install --frozen-lockfile
artifacts:
paths:
- node_modules/
expire_in: 1 hour
only:
- merge_requests
- main
テストステージでユニットテストとカバレッジを実行します。
yaml# テスト実行
test:
stage: test
dependencies:
- install
script:
- yarn test --coverage
coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
only:
- merge_requests
- main
リントと TypeScript チェックを実行します。
yaml# リントチェック
lint:
stage: lint
dependencies:
- install
script:
- yarn lint
- yarn tsc --noEmit
only:
- merge_requests
- main
ビルドステージで成果物を生成します。
yaml# ビルド
build:
stage: build
dependencies:
- install
script:
- yarn build
artifacts:
paths:
- .next/
expire_in: 1 week
only:
- merge_requests
- main
すべてのステージが成功することで、マージが可能になります。
Merge Request Approval Rules 設定
GitLab のプロジェクト設定で、以下のように承認ルールを構成します。
-
基本承認ルール
- ルール名:
Default Approval - 必要承認者数:2 人
- 対象ブランチ:
main - 承認可能者:
@tech-leadsグループ
- ルール名:
-
コードオーナー承認
- ルール名:
Code Owners Approval - 必要承認者数:1 人(コードオーナーから)
- 「Require approval from code owners」を有効化
- ルール名:
-
Protected Branches 設定
- ブランチ:
main - Allowed to merge:
Maintainersのみ - Allowed to push:
No one(直接プッシュ禁止) - Allowed to force push:無効
- ブランチ:
-
Merge Checks 設定
- ✓ Pipelines must succeed
- ✓ All threads must be resolved
- ✓ Status checks must pass
これにより、GitLab 上でも厳格なガバナンス運用が実現できます。
下図は、GitLab での MR フローの全体像です。
mermaidsequenceDiagram
participant Dev as 開発者
participant MR as Merge Request
participant CI as GitLab CI/CD
participant Owner as Code Owner
participant Lead as Tech Lead
participant Main as main ブランチ
Dev->>MR: MR 作成
MR->>Owner: 自動レビュアー割り当て
MR->>CI: パイプライン起動
CI->>CI: install/test/lint/build
CI-->>MR: ステータス通知
alt パイプライン失敗
CI--xMR: ❌ 失敗
MR-->>Dev: 修正依頼
Dev->>MR: 修正コミット
MR->>CI: 再実行
end
CI-->>MR: ✅ 成功
Owner->>MR: コードレビュー・承認
Lead->>MR: 最終承認
MR->>Main: マージ実行
Main-->>Dev: 完了通知
この流れにより、複数の承認ステップと CI 成功が保証されたマージが実現できます。
運用上の Tips
実際にガバナンスを運用する際には、以下の点に注意すると効果的です。
定期的なルール見直し チーム規模やプロジェクト特性の変化に応じて、承認者数やチェック項目を見直しましょう。 四半期ごとにレトロスペクティブを実施し、ルールの妥当性を確認するとよいですね。
ドキュメント化と周知 ガバナンスルールは README や CONTRIBUTING.md に明記し、新メンバーがすぐ理解できるようにします。
markdown# CONTRIBUTING.md 例
# Pull Request ガイドライン
## マージ要件
- 最低 2 名の承認が必要
- CI チェック(test, lint, build)がすべて成功
- すべてのコメントスレッドが解決済み
- main ブランチとの差分が最新
## 緊急対応
- 本番障害対応時は、テックリード 1 名の承認で可
- 対応後、24 時間以内に追加レビューを実施
承認者の負荷分散 特定の人にレビューが集中しないよう、チーム内でローテーションを組むか、サブチームごとに承認者を分けます。
自動化の推進 リント、フォーマット、セキュリティスキャンなど、自動化できる部分は積極的に CI/CD に組み込み、人的レビューの負担を減らしましょう。
まとめ
本記事では、GitHub と GitLab を使った Git ガバナンス運用の実装方法を解説しました。
要点の整理
- Branch Protection Rules(GitHub) や Protected Branches(GitLab) で、重要ブランチへの直接コミットを防止
- レビュー必須化 により、最低限の承認者数を設定し、品質を担保
- CI/CD チェックの必須化 で、テスト・リント・ビルドの成功を保証
- CODEOWNERS ファイル で、変更箇所に応じた自動レビュアー割り当て
- 承認フローの明文化 により、役割分担と例外処理を明確化
これらの仕組みを組み合わせることで、チーム全体でコード品質を維持しながら、効率的かつ安全な開発フローを構築できます。
次のステップ
ガバナンス運用を導入したら、以下のステップで継続的に改善していきましょう。
- まずは小規模なプロジェクトで試験導入し、運用上の課題を洗い出す
- チームメンバーからフィードバックを収集し、ルールを調整
- 全社的に展開し、組織標準として定着させる
- メトリクス(レビュー時間、マージ頻度、バグ検出率など)を測定し、効果を可視化
適切なガバナンス運用は、開発速度を落とすどころか、むしろ品質向上と障害減少により、長期的な生産性向上につながります。 ぜひ本記事を参考に、チームに最適なガバナンスルールを構築してみてください。
関連リンク
articleGit ガバナンス運用:レビュー必須・チェックルール・承認フローの作り方
articleGit リリース列車モデルの実践:短サイクルで安定提供するブランチ設計
articleGit エイリアス 50 連発:長コマンドを一行にする仕事術まとめ
articleGit を macOS に最適導入:Homebrew・初期設定テンプレ・credential 管理まで
articleGit の部分取得を徹底比較:sparse-checkout/partial clone/shallow の違いと使い分け
articleGit で「detached HEAD」になった時の安全復帰プレイブック
articleGitHub Copilot Workspace 速理解:仕様 → タスク分解 →PR までの“自動開発”体験
articleMySQL InnoDB 内部構造入門:Buffer Pool/Undo/Redo を俯瞰
articleMotion(旧 Framer Motion)で学ぶ物理ベースアニメ:バネ定数・減衰・質量の直感入門
articleJavaScript Web Animations API:滑らかに動く UI を設計するための基本と実践
articleGitHub Actions コンテキスト辞典:github/env/runner/secrets の使い分け最速理解
articlehtmx で管理画面 CRUD を 10 倍速に:一覧・検索・編集・バルク操作テンプレ
blogiPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
blogGoogleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
blog【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
blogGoogleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
blogPixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
blogフロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
review今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
reviewついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
review愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
review週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
review新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
review科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来