# Dependabot auto-merge × GitHub Actions 自動化ガイド：fetch-metadata で patch/minor だけ安全に自動マージする

> Dependabot のPRを GitHub Actions で安全に自動マージする実装ガイド。公式ドキュメント（2026年6月時点）に忠実に、dependabot/fetch-metadata@v3 の全出力、update-type による条件分岐、gh pr merge --auto、読み取り専用 GITHUB_TOKEN と Dependabot シークレットの token モデル、pull_request と pull_request_target の使い分け、必須チェックとブランチ保護で安全弁を作る方法までを、コピペできる実コードで解説します。

- 公開日: 2026-06-28
- 著者: 友田 陽大
- タグ: Dependabot, GitHub Actions, CI/CD, DevSecOps, 自動化, セキュリティ
- URL: https://tomodahinata.com/blog/dependabot-auto-merge-github-actions-automation-guide
- カテゴリ: Dependabot・依存関係の自動更新
- 総合ガイド: https://tomodahinata.com/blog/dependabot-production-guide

## 要点

- auto-merge の鉄則は『patch/minor だけ自動、major は人間』。dependabot/fetch-metadata@v3 の update-type 出力で条件分岐し、gh pr merge --auto で必須チェック通過後にマージを予約する
- Dependabot がトリガする pull_request ワークフローの GITHUB_TOKEN は既定で読み取り専用。auto-merge には workflow 側で permissions（contents: write / pull-requests: write）を明示する
- Dependabot のワークフローは通常 Actions シークレットにアクセスできない。秘密が要るなら Dependabot シークレットストアを使う。pull_request_target で untrusted コードを checkout&実行する危険パターンは避ける
- auto-merge の安全弁は CI（必須ステータスチェック）とブランチ保護。テスト・型・lint・ビルドを required にして初めて、無人マージが『安全な自動化』になる
- fetch-metadata は update-type / dependency-type / dependency-group / compatibility-score など14の出力を持つ。これらでグループPR・本番/開発依存・互換スコアに応じた繊細な自動マージ方針を組める

---

Dependabot を入れると、次に必ず欲しくなるのが **auto-merge** です。`@types/node` のパッチを毎回手でマージするのは時間の無駄——けれど**何でも自動マージすると、破壊的変更を無人で本番に流し込む**事故になります。正解は **「壊れる確率が低いものだけ（patch/minor）を、CI 通過を条件に自動マージし、major は人間がレビューする」** という分業です。

この記事は[Dependabot 本番運用ガイド](/blog/dependabot-production-guide)の各論として、**GitHub Actions による安全な auto-merge** を実装レベルで解説します。ここはセキュリティの落とし穴が多いので、**token モデルとイベントトリガ**を特に丁寧に扱います。

> **この記事のルール**：アクション名・出力・トークン挙動は **GitHub 公式ドキュメントと `dependabot/fetch-metadata` の README（2026年6月時点）** に基づきます。auto-merge はセキュリティに直結するため、本番投入前に必ず[公式の自動化ガイド](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/automating-dependabot-with-github-actions)で最新を確認してください。**`GITHUB_TOKEN` 以外の秘密はワークフローにハードコードしない**でください。

---

## 1. 全体像：auto-merge は「予約」である

GitHub の auto-merge は「**今すぐマージ**」ではなく「**必須チェックがすべて green になったらマージする**」という**予約**です。だから auto-merge を有効化しても、**テストが落ちればマージされません**。この性質が安全性の核です。

```text
Dependabot がPRを開く
   └─▶ ワークフロー起動（actor が dependabot[bot] か検査）
          └─▶ fetch-metadata で update-type 等を取得
                 └─▶ patch/minor なら gh pr merge --auto を実行（=予約）
                        └─▶ 必須チェック（テスト/型/lint/ビルド）が green
                               └─▶ 自動マージ ✅   （赤なら止まる ⛔）
```

前提として、リポジトリ設定で **「Allow auto-merge」** を有効化しておきます（Settings → General → Pull Requests）。

---

## 2. 最小実装：patch/minor を自動マージ

まずは動く最小形。**`pull_request` イベント**で起動し、**ワークフロー側で書き込み権限を明示**するのがポイントです。

```yaml
# .github/workflows/dependabot-auto-merge.yml
name: Dependabot auto-merge
on: pull_request

permissions:
  contents: write          # マージに必要
  pull-requests: write     # PR操作に必要

jobs:
  auto-merge:
    runs-on: ubuntu-latest
    # Dependabot 以外のPRでは何もしない（必須のガード）
    if: github.actor == 'dependabot[bot]'
    steps:
      - name: Fetch Dependabot metadata
        id: meta
        uses: dependabot/fetch-metadata@v3
        with:
          github-token: "${{ secrets.GITHUB_TOKEN }}"

      - name: Enable auto-merge for patch & minor
        if: |
          steps.meta.outputs.update-type == 'version-update:semver-patch' ||
          steps.meta.outputs.update-type == 'version-update:semver-minor'
        run: gh pr merge --auto --merge "$PR_URL"
        env:
          PR_URL: ${{ github.event.pull_request.html_url }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

3つの要点：

1. **`if: github.actor == 'dependabot[bot]'`** — Dependabot 以外のPRで動かさないガード。**これを省くと第三者のPRにも反応して危険**です。
2. **`permissions:` の明示** — Dependabot がトリガする `pull_request` ワークフローの `GITHUB_TOKEN` は**既定で読み取り専用**。auto-merge には `contents: write` と `pull-requests: write` を明示的に与えます（後述）。
3. **`update-type` での条件分岐** — `version-update:semver-patch` / `semver-minor` のみ。major（`semver-major`）は意図的に除外し、人間に回します。

---

## 3. token モデル：ここがセキュリティの肝

auto-merge で事故る大半は**トークンの理解不足**です。公式の挙動を正確に押さえます。

- **Dependabot がトリガする `pull_request` ワークフローの `GITHUB_TOKEN` は、既定で読み取り専用**。そして**通常の Actions シークレットにアクセスできません**。これは**侵害された依存が、CI 経由で秘密情報を盗み出すのを防ぐ**ための設計です。
- 書き込みが必要なら、**ワークフロー内で `permissions:` を宣言**して必要な範囲だけ昇格します（Dependabot の `pull_request` イベントでは、ワークフローで宣言した権限が尊重されます）。
- ワークフローで**秘密が必要**な場合（例：プライベートリソースへアクセスするテスト）は、**Dependabot シークレットストア**（Settings → Secrets and variables → **Dependabot**）に置きます。**Actions シークレットとは別物**です。

> 覚え方：「Dependabot のPRで動く CI は、**初期状態が読み取り専用 & 秘密なし**」。だから auto-merge は `permissions` の明示が要り、秘密は Dependabot 専用ストアに置く。この2点を外すと「権限がない」「シークレットが空」で詰まります。

### 3.1 pull_request か pull_request_target か

`dependabot/fetch-metadata` の README には `pull_request_target` を使う例もありますが、**安全側の既定は `pull_request`** です。理由：

- **`pull_request_target` は、ベースリポジトリの文脈で読み書き可能なトークンを持って動く**。ここで**PRのコード（=更新された依存を含む）を `actions/checkout` して実行**すると、**侵害された依存が write 権限つきトークンや秘密に触れる**経路ができます。
- 一方、**メタデータ取得 + `gh pr merge --auto`（=コードを実行しない操作）だけ**なら、`pull_request` + 明示的 `permissions` で十分に目的を達成でき、より安全です。

結論：**ビルドや任意コード実行を伴わない auto-merge は `pull_request` を使う。** どうしても `pull_request_target` が必要なら、**PR の head を checkout して実行しない**こと、信頼境界を理解した上で使うこと。

> マージキューを使う場合：組み込みの `GITHUB_TOKEN` ではキューにPRを追加できません。**PAT か GitHub App トークン**でワークフローを認証する必要があります（公式注記）。

---

## 4. fetch-metadata の全出力で「繊細な方針」を作る

`dependabot/fetch-metadata@v3` は14の出力を持ちます。これを使うと「patch/minor だけ」より**繊細な自動マージ方針**を組めます。

| 出力 | 用途の例 |
| --- | --- |
| `update-type` | `version-update:semver-patch/minor/major` で粒度判定 |
| `dependency-type` | `direct:production` / `direct:development` / `indirect` |
| `dependency-names` | 特定パッケージ（例 `rails`）に限定 |
| `dependency-group` | グループPR（groups設定）かどうかで分岐 |
| `package-ecosystem` | エコシステム別ポリシー（github-actions は自動など） |
| `directory` | モノレポのディレクトリ別ポリシー |
| `previous-version` / `new-version` | バージョン差分でログ・判断 |
| `compatibility-score` | 互換スコアでしきい値判定 |
| `alert-state` / `ghsa-id` / `cvss` | セキュリティ更新を別扱い |
| `maintainer-changes` | メンテナ変更があれば人間レビューに回す |
| `target-branch` | 対象ブランチ別ポリシー |
| `updated-dependencies-json` | 機械処理用の生データ |

### 4.1 実戦例：開発依存はminorまで、本番依存はpatchのみ自動

```yaml
      - name: Auto-merge policy
        # 開発依存は patch/minor を自動、本番の direct 依存は patch のみ自動
        if: |
          (steps.meta.outputs.dependency-type == 'direct:development' &&
            (steps.meta.outputs.update-type == 'version-update:semver-patch' ||
             steps.meta.outputs.update-type == 'version-update:semver-minor')) ||
          (steps.meta.outputs.dependency-type == 'direct:production' &&
            steps.meta.outputs.update-type == 'version-update:semver-patch')
        run: gh pr merge --auto --merge "$PR_URL"
        env:
          PR_URL: ${{ github.event.pull_request.html_url }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

設計思想：**本番に近いほど慎重に**。`direct:production` の minor は人間レビュー、`direct:development`（テスト・ビルドツール）はもう少し緩める——という「リスクに比例した自動化」です。

### 4.2 メンテナ交代は必ず人間が見る

```yaml
      - name: Flag maintainer changes for human review
        if: steps.meta.outputs.maintainer-changes == 'true'
        run: gh pr comment "$PR_URL" --body "⚠️ メンテナ変更あり。サプライチェーン観点で人間レビュー必須。"
        env:
          PR_URL: ${{ github.event.pull_request.html_url }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

**メンテナの交代は、依存乗っ取り（hijack）の兆候**になり得ます。`maintainer-changes` を見て自動マージから除外し、人間の目を入れるのは安価で効果的な防御です。

---

## 5. 安全弁を作る：必須チェック × ブランチ保護

auto-merge は「green ならマージ」。つまり**「何を green の条件にするか」が安全性そのもの**です。安全弁がない auto-merge は、ただのロシアンルーレットです。

### 5.1 Dependabot PR でも本物の CI を回す

```yaml
# .github/workflows/ci.yml（Dependabot PR でも走る通常CI）
name: CI
on: pull_request

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "22"
          cache: "npm"
      - run: npm ci
      - run: npm run lint
      - run: npm run typecheck
      - run: npm test
      - run: npm run build
```

> 注意：このCIは**更新後の依存を `npm ci` で入れて実行**します。`pull_request` で動く Dependabot のCIは**読み取り専用トークン・秘密なし**なので、万一悪性依存が紛れても被害を最小化できます。**秘密が必要な統合テストを Dependabot PR で走らせない**設計にすると、より堅牢です。

### 5.2 ブランチ保護で必須化する

`main` のブランチ保護（または Rulesets）で次を設定：

- **Require status checks to pass before merging** に `lint` / `typecheck` / `test` / `build` を**必須登録**。
- **Require branches to be up to date before merging**（任意。`rebase-strategy` と相談）。
- これで `gh pr merge --auto` は**必須チェックが全部 green になるまでマージしません**＝安全弁が効く。

「auto-merge を入れる前に、まず**信頼できる必須チェック**を用意する」——順序を逆にしないでください。

---

## 6. グループPR・cooldown との併用

[設定完全ガイド](/blog/dependabot-yml-configuration-complete-guide)で作った `groups` / `cooldown` と auto-merge は綺麗に噛み合います。

- **groups で patch/minor を1PRに束ね → そのグループPRを auto-merge**：レビュー対象が「major と中身のある更新」だけに減ります。`dependency-group` 出力でグループPRを判定できます。
- **cooldown で出たての版を寝かせる → 寝かせ終わって出てきたものを auto-merge**：回帰リスクを下げてから自動取り込み。

```yaml
      - name: Auto-merge grouped patch/minor PRs
        if: |
          steps.meta.outputs.dependency-group != '' &&
          steps.meta.outputs.update-type != 'version-update:semver-major'
        run: gh pr merge --auto --squash "$PR_URL"
        env:
          PR_URL: ${{ github.event.pull_request.html_url }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

（`--squash` でグループPRの履歴を1コミットに畳む、など運用に合わせて選択。）

---

## 7. アンチパターン集

- ❌ **`if: github.actor` ガードなし** → 第三者PRに反応。必須ガードを必ず入れる。
- ❌ **major も auto-merge** → 破壊的変更を無人で本番へ。patch/minor 限定が鉄則。
- ❌ **必須チェック未設定で auto-merge** → 安全弁がない。ブランチ保護とセット。
- ❌ **`pull_request_target` でPRコードを checkout & 実行** → write トークン/秘密が悪性依存に触れる経路。コード実行を伴わないなら `pull_request`。
- ❌ **Actions シークレットに依存** → Dependabot のCIは触れない。Dependabot シークレットストアを使う。
- ❌ **`permissions` を全体で `write-all`** → 最小権限違反。`contents` / `pull-requests` だけに絞る。

---

## 8. FAQ

**Q. auto-merge したのにマージされません。**
A. `--auto` は「必須チェックが green になったら」マージします。チェックが pending/失敗、または「Allow auto-merge」やブランチ保護の必須チェックが未設定だと進みません。

**Q. `Resource not accessible by integration` エラーが出ます。**
A. Dependabot の `pull_request` ワークフローは既定で読み取り専用です。ワークフローに `permissions: { contents: write, pull-requests: write }` を明示してください。

**Q. major も含めて全部自動にしたいのですが。**
A. 推奨しません。破壊的変更を無人で取り込むリスクに見合いません。major は `fetch-metadata` の `update-type` で除外し、人間レビューに回してください。

**Q. マージキューを使っています。**
A. 組み込み `GITHUB_TOKEN` ではキューに追加できないため、PAT か GitHub App トークンでワークフローを認証してください。

**Q. セキュリティ更新も auto-merge してよいですか？**
A. CI（特にテスト）が十分なら patch のセキュリティ更新は自動マージの効果が大きいです。ただし `alert-state` / `cvss` を見て**重大なものは人間が確認**する方針も検討してください。脆弱性対応の全体像は[アラート・セキュリティ更新ガイド](/blog/dependabot-security-updates-alerts-vulnerability-management-guide)へ。
