Skip to content
Published on

現代のコードレビューとMergeパイプライン — PR・Merge Queue・Stacked PRs・Monorepo・AI Review・Trunk-Based・Husky・Semgrep 深掘りガイド (2025)

Authors

コードレビューは仕事の半分だ — なぜほとんど語られないのか

エンジニアが1日に3〜5件のPRをレビューするとしよう。週5日、年50週で年間1,000件に達する。新機能を作る時間より他人のコードを読んで判断して提案する時間の方が多いかもしれない。それなのに、コードレビューについて驚くほど語られていない。「レビューが怖くてPRを大きくする」「承認されず2週間寝かせた」「レビューアが見落としたバグで障害」「AIレビューが自動スパム」— 毎日起きている。

2025年はその風景が激変している。Cursor・Copilot Review・CodeRabbit・Greptileといった AI レビューアが「一次レビューは機械」時代を開き、Graphite・Sapling・Jujutsu が Stacked PRs を主流ワークフローに押し上げ、Merge Queue は GitHub の標準機能になった。Monorepo ツール (Nx・Turborepo・Moon・Bazel・Buck2) も世代交代した。Trunk-based Development は「理想」から「デフォルト」に移った。

本稿は2025年のコードレビューと Merge パイプラインを徹底解剖する。

Platform EngineeringObservability の続編。プラットフォームが「セルフサービス提供」なら、コードレビューは「コード変更の品質ゲート」である。

第1部. PRの社会学 — ブロッカーにならない方法

1.1 レビューが辛い本当の理由

  • サイズが大きすぎる — 1,000行のPRは誰も正しく見られない
  • 文脈不足 — なぜこの変更が必要か本文に書かれていない
  • 感情が乗る — 「こうしてはいけません」は攻撃に読める
  • 非同期の往復 — 1往復24時間 → 1週間放置

1.2 良いPRの4要素

  1. 小さい単位 — 400行以下推奨 (欠陥検出効率が最大)
  2. 単一の変更 — リファクタリングと機能を混ぜない
  3. 本文に文脈 — 何を・なぜ・どうテストしたか
  4. Self-review から — 作成者が自分でコメントしてから開く

1.3 良いレビューアの4原則 (Google Code Review Guide)

  • 作者の意図を理解して評価 — 完璧より「以前より良いか」
  • 原則ベースのコメント — 「I prefer」でなく「このコードベース規約で」
  • 質問から始める — 断定でなく「これは意図的?」
  • Blocking と Nit の区別nit:, question:, blocking: 接頭辞

1.4 Conventional Comments

ブロッキング意図と強度を接頭辞で表示し、感情を排除。

praise: テストケースが丁寧です
nitpick: 名前がもっと明確に - userId -> userIdentifier
suggestion: util に抽出すると再利用しやすいです
issue: この状態で race condition の可能性 - TOCTOU
thought: A/B テストが必要かも?
question: retry 回数が3の理由はありますか?

第2部. Code Owner とレビューア割当

2.1 CODEOWNERS ファイル

# /auth/** は security チーム必須レビュー
/auth/**                        @org/security
/packages/payments/**           @org/payments-team
/infrastructure/terraform/**    @org/platform
*.md                            @org/docs
  • GitHub・GitLab 標準対応
  • Branch protection と組み合わせて「必須承認者を自動要求」

2.2 自動レビューア選定ツール

  • Pullrequest rotation — GitHub チームラウンドロビン
  • ReviewBot, Toast — カスタムアルゴリズム(経験・負荷考慮)
  • Graphite Merge — レビューア推薦
  • 社内ツール:「変更ファイルの最近のコミッタ」を自動提案 (Facebook mention_bot 由来)

2.3 レビュー負荷の平準化

  • 1人のシニアにレビューが集中 → そのシニアが生産性ボトルネック
  • 分散: Pair reviewer 強制、ジュニア1 + シニア1
  • ダッシュボードで「オープンレビュー数」を可視化

第3部. Merge Queue — 2024〜2025 デフォルト

3.1 問題

  • PR A と B がそれぞれ main ベースで CI 通過
  • A が先に merge
  • B は新しい main で壊れる可能性 (silent semantic conflict)
  • → merge 後に CI 失敗発覚

3.2 Merge Queue の役割

  1. merge 要求をキューに入れる
  2. キュー先頭で「現在の main + この PR」をシミュレーションビルド
  3. 通ったら実 merge
  4. 失敗したら作成者に戻す

Google・Facebook が10年以上社内で使ってきた方式。2023年に GitHub ネイティブ、2024年に標準推奨。

3.3 ツール

  • GitHub Merge Queue (2023 GA) — デフォルト選択
  • Mergify — Python ルールベース、複雑なポリシー対応
  • Aviator — stacked PR + merge queue
  • Graphite — 統合製品 (Stacked PR + Merge + Code Review)
  • Bors NG / Trainium — OSS 代替

3.4 Batched Merge

大型モノレポは一度に複数 PR をバッチ処理。失敗時は二分探索 (bisect) で原因 PR を特定。Meta・Google 規模でのみ必要。

第4部. Stacked PRs — 大型変更を小さく分ける

4.1 問題

  • 大きな機能を作ると一度に2,000行溜まる
  • レビューアが見られない → 適当に承認 → バグ

4.2 解決

変更を複数 PR にスタックし、それぞれ小さく。先頭 PR が merge されると次の PR が自動で main にrebase。

main <- PR1 (スキーマ) <- PR2 (API) <- PR3 (UI)

各 PR を独立してレビュー。ただし手動スタック管理は rebase 地獄。

4.3 ツール

  • Graphite (gt) — 業界最多採用。TypeScript/Python エコシステム優勢
  • Sapling (Meta 2022 OSS) — Mercurial ベース、Meta 社内ツール
  • Jujutsu (jj) (Google 2023 OSS) — Git 互換、次世代候補として注目
  • Spr (Facebook 旧ツール) — CLI
  • ghstack (PyTorch チーム)
  • git-branchless — 個人用

4.4 Jujutsu が注目される理由

  • Git リポジトリ互換、上から被せる
  • 「first-class conflict」— merge conflict が commit 状態として残る
  • 強力な revset クエリ (jj log -r 'ancestors(@)')
  • operation log で undo が完璧
  • 2025年 Google 社内主軸化計画、外部関心が爆発

第5部. Monorepo vs Polyrepo — 2025年の結論

5.1 Monorepo が勝つとき

  • 内部依存が強い複数サービス/ライブラリ
  • 同時変更 (スキーマ + API + クライアント) が頻繁
  • 標準ツール統一が重要な組織規模

5.2 Polyrepo が勝つとき

  • サービス間独立性が本当に高い
  • チームが完全に分離
  • ビルドツール統一コストが大きすぎる

5.3 実務合意

Google/Meta は10万人 monorepo。スタートアップは「小さく始めて規模が出たら monorepo に統合」が一般的。2024〜2025のトレンドは**「サービスは monorepo、OSS ライブラリだけ別リポ」**。

5.4 Monorepo 必須条件

  1. 高速ビルドキャッシュ (Remote Cache)
  2. Affected Detection — 変更プロジェクトだけビルド/テスト
  3. Merge Queue — 大量 PR の並列 merge
  4. Code Owner 自動ルーティング
  5. 規模別 Git 管理 — partial clone, LFS, VFS

第6部. Monorepo ビルドツール — Nx・Turborepo・Moon・Bazel・Buck2・Pants・Lerna の終焉

6.1 JavaScript/TypeScript 中心

  • Nx — Nx Cloud、グラフ UI、プラグイン豊富
  • Turborepo (Vercel) — 高速、シンプル、pnpm + Next.js チーム特化
  • Moon (Rust) — 言語中立志向、Turbo の競合
  • Lerna — 公式 deprecated 後 Nx チームが引き取り維持

6.2 言語中立

  • Bazel — Google、最高性能・最高学習コスト
  • Buck2 (Meta 2023 OSS, Rust) — Bazel より高速
  • Pants (Twitter) — Python プロジェクトに特に適合
  • Please — 小型チーム
  • Earthly — Dockerfile 類似 DSL で再現可能ビルド

6.3 選択ツリー

  • 純 JS/TS monorepo, <= 50 パッケージ → Turborepo
  • JS/TS + UI チーム + プラグイン → Nx
  • 多言語 (JS/Go/Rust), 中規模 → Moon
  • 超大型、ビルドエンジニアリング投資可能 → Bazel または Buck2
  • Python 中心 → Pants

6.4 Remote Cache

全ツールの共通勝負どころ。Turborepo/Nx は Vercel/Nx Cloud、Bazel は BuildBuddy/Remote Build Execution、Buck2 は独自プロトコル。5分かかっていた CI が 30秒になった事例は大抵 Remote Cache のおかげ。

第7部. AI コードレビュー — 2024〜2025 爆発

7.1 AI が得意なこと

  • Null safety、off-by-one、未使用変数のような静的解析領域
  • 「この関数名は曖昧」のようなスタイル
  • 反復パターン認識 (「このコードベースでは X を使うのに Y を使いました」)
  • テストケース提案
  • ユニットテストカバレッジ予測

7.2 AI が苦手なこと

  • アーキテクチャレベルの判断
  • ビジネス文脈 (「この変更は顧客に意味があるか」)
  • チーム暗黙の慣習
  • セキュリティ文脈 (外部入力がどこまで信頼されているか)

7.3 ツール

  • CodeRabbit — PR に自動要約 + コメント、無料 OSS モード
  • Greptile — コードベース全体 RAG ベース context-aware レビュー
  • Ellipsis — 「PR 説明自動生成」が特に強い
  • Cursor BugBot — Cursor ユーザー向け
  • Copilot Review (GitHub 2024〜) — Copilot Enterprise
  • Qodo (Codium) — Python/JS テスト自動生成が強み
  • Sourcery — Python リファクタリング
  • Graphite AI — stacked PR レビュー

7.4 AI レビュー導入の実務 Tips

  • 一週間 PR に自動コメントのみ → チームが価値あるコメント比率を測定
  • スパム比率が5%超なら調整 (false positive はレビュー文化を汚染する)
  • AI に承認権限を渡さない — 人間レビュー必須
  • PR 要約 (summary) のみ AI で書く組織も多い (最も安全な出発点)

第8部. Trunk-based Development

8.1 定義

  • 全エンジニアが main 近くで (数時間以内の寿命) 作業
  • Long-lived feature branch 禁止
  • 機能を feature flag で隠す (LaunchDarkly/Statsig)
  • main は常に deployable

8.2 なぜ勝つのか

  • Merge conflict が減る
  • デプロイ周期が短くなる → MTTR 低下
  • Continuous Integration が意味を持つ
  • DORA elite レベル必須条件

8.3 Git Flow の死

  • nvie/gitflow (2010) は2020年作者自らが事実上 deprecated 宣言
  • GitLab Flow, GitHub Flow がよりシンプルな代替
  • 金融系エンタープライズは今も release branch を維持

8.4 Feature Flag ベース開発

  • 「デプロイ = リリース」が分離
  • A/B テスト・Gradual Rollout・Kill Switch が一つに
  • 管理されない flag が flag debt — 6ヶ月以上の flag を整理する儀式

第9部. Git 技術 — Rebase・Squash・Linear History

9.1 Merge vs Rebase 論争

  • Merge commit — 履歴保存、時系列そのまま
  • Rebase — 線形、bisect フレンドリー
  • Squash and Merge — PR 一つ = commit 一つ

9.2 チーム別ポリシー

  • Linus Torvalds / Linux カーネル: rebase 推奨、linear
  • GitHub デフォルト: Squash and Merge (最もシンプル)
  • Google: linear history, rebase 前提
  • Meta: Mercurial → Sapling, rebase ネイティブ

9.3 共有ブランチへの force-push 禁止

git rebase 後の git push --force は共有ブランチで災難。--force-with-lease で防御。GitHub は最近 Protected Branch で force-push をデフォルト遮断。

9.4 Conventional Commits

feat(auth): add passkey support
fix(payments): handle stripe timeout
refactor(db): extract repository interface
chore: bump deps
docs: update README
  • 自動 changelog 生成
  • semantic-release でバージョン bump
  • チーム規律とツールエコシステムの結合

第10部. Pre-commit / Pre-push フック — ローカルで CI を速く

10.1 フックマネージャ

  • Husky — JS エコシステム標準、Node 専用
  • lefthook — Go バイナリ、言語中立、高速
  • pre-commit (Python) — 言語中立、世界的使用
  • Soft-serve, cog — 新実験

10.2 必須フックセット

repos:
  - repo: local
    hooks:
      - id: lint
        name: eslint
        entry: pnpm lint --fix
        language: system
      - id: typecheck
        entry: pnpm typecheck
        language: system
      - id: test
        entry: pnpm test:affected
        language: system
      - id: secrets
        entry: gitleaks protect --staged
        language: system

10.3 フックが嫌われる理由と対策

  • 遅いので --no-verify で迂回 → フックは10秒以内に終わるべき
  • pnpm test:affected のような変更ファイル限定
  • staged ファイルだけ format: lint-staged
  • ビルド/テストは pre-push だけ、commit には format/lint だけ

第11部. 静的解析 — Semgrep・SonarQube・CodeQL・ESLint

11.1 Semgrep

  • 言語中立パターンマッチ (YAML ルール)
  • Supply-chain, Secrets, Security ルールセット
  • Semgrep Cloud Platform (SaaS) — 2023〜2024急成長

11.2 SonarQube / SonarCloud

  • Quality Gate、Technical Debt、Coverage
  • エンタープライズ標準
  • 「Clean as You Code」ポリシーが最近の推奨

11.3 GitHub CodeQL

  • データフローベースの脆弱性解析
  • OSS リポ無料、private 組織有料
  • SQL ライクにクエリ記述可能

11.4 ESLint・Biome・Oxlint

  • ESLint — JS/TS 標準だが遅い
  • Biome (2023 Rome fork) — Rust、linter + formatter 統合、10〜50倍速
  • Oxlint — Rust、Biome 競合、ESLint ルール互換
  • dprint — Rust、言語中立フォーマッタ

11.5 セキュリティ特化

  • gitleaks — commit 前 secret 検出
  • trufflehog — ディープスキャン
  • Syft, Grype — SBOM + 脆弱性
  • Trivy — コンテナ・IaC スキャン

第12部. CI 速度 — PR merge が10分以下であるべき理由

12.1 Compound effect

  • CI 1時間 → 開発者が context switch
  • 10分 → 「次タスク前に待てる」可能
  • 5分以下 → flow 維持

12.2 改善戦略

  • Remote Cache (Nx/Turborepo/Bazel)
  • Parallel Matrix (5シャードでテスト分割)
  • Affected-only ビルド
  • Docker layer cache
  • Warm runner (Depot, BuildJet, Namespace, Blacksmith, RunsOn) — GitHub Actions ARM/X86 + NVMe cache
  • Earthly / Docker BuildKit multi-stage

12.3 Flaky Test

  • 最悪の生産性キラー
  • リトライ機構 + 隔離追跡
  • Trunk.io flaky test detection — 30日失敗率で自動スキップ
  • Test retries は一時しのぎ、根本原因追跡が必須

第13部. 実務 — チーム規模別コードレビューパイプライン

13.1 5人チーム

  • GitHub Flow + Squash and Merge
  • CODEOWNERS 最小、必須レビューア1人
  • pre-commit フック + ESLint/Prettier
  • CI: GitHub Actions + Turborepo
  • AI レビュー: CodeRabbit free

13.2 50人チーム

  • Merge Queue 必須
  • AI レビュー有料 (CodeRabbit/Greptile)
  • 社内 Runbook: 「PR は400行以下推奨」
  • セキュリティスキャン: Semgrep CI + gitleaks
  • monorepo なら Nx + Remote Cache

13.3 500人以上

  • Graphite/Aviator で stacked PR 標準化
  • Buck2/Bazel Remote Execution
  • CodeQL + SonarQube エンタープライズ
  • Trunk-based + Feature Flag 強制
  • 専任「Dev Productivity」チーム

第14部. チェックリスト12・アンチパターン10

チェックリスト12

  1. 平均 PR サイズが 400行以下か?
  2. PR merge まで P50 24時間以下か?
  3. CODEOWNERS が最新で機能しているか?
  4. Merge Queue が付いていて semantic conflict を遮断しているか?
  5. Stacked PRs がチームの通常ワークフローか?
  6. Conventional Commits が適用されているか?
  7. pre-commit/pre-push フックが高速 (10秒以内) で有用か?
  8. Biome/Oxlint のような高速 linter に移行したか?
  9. CI が平均 10分以下で終わるか?
  10. Flaky test 検出/隔離システムがあるか?
  11. AI レビューアのスパム比率が5%以下か?
  12. Trunk-based + Feature Flag が標準か?

アンチパターン10

  1. 1,000行 PR を「レビュー済」と署名
  2. PR タイトル・本文が空
  3. Long-lived feature branch が1ヶ月以上
  4. --no-verify でフック習慣的に迂回
  5. AI レビューの承認だけで merge
  6. Merge Queue なしで同時 merge → silent conflict
  7. Flaky test を if (retryCount < 3) で覆い隠す
  8. CODEOWNERS 未管理 → 自動レビューアが幽霊アカウント
  9. チーム全体のレビューが1人のシニアに集中
  10. Rebase/Squash ポリシーがチーム内で不一致 → 履歴混乱

次回予告 — 「エンジニアリングブログの時代: 技術ライティング・RFC・ADR・Design Doc・ブログ運営・コミュニケーション」

コードレビューを語ったなら、次は技術ライティング。RFC、ADR、Design Doc、社内 Wiki、外部ブログ。文章がうまいエンジニアは影響半径が10倍。

  • Amazon 6-pager 文化 — なぜパワーポイントを禁止したか
  • Design Doc テンプレート — Google/Stripe 公開版
  • RFC プロセス — Rust・Ember・IETF 比較
  • ADR (Architecture Decision Record)
  • Internal Wiki — Notion・Confluence・Outline・GitBook
  • Engineering Blog 運営 — Stripe・Shopify・Uber・Airbnb スタイル
  • Changelog と Release Notes
  • Slack/Email 非同期コミュニケーション
  • LLM 時代のライティング — AI を道具として使いながら自分の声を保つ
  • テックインフルエンサーの経済学 — 1本の記事がキャリアを変える瞬間

コードは結局、人々の間で生き残る。次回、その生存戦略を見る。