From 4163655fe32fc7ed66f3f782abfd16ba877076b1 Mon Sep 17 00:00:00 2001 From: Claude Code Bot Date: Sat, 18 Apr 2026 16:23:32 -0700 Subject: [PATCH] docs: add Phase 5 (dependabot auto-merge) to rollout playbook Captures the last piece of the 2026-04-18 v2 rollout: the Dependabot auto-merge workflow pattern (narrow scope, pull_request_target + actor gate + patch/minor filter) and the deployment via Contents API. Also adds two pitfalls observed during Phase 5: - Private+free-tier repos silently reject allow_auto_merge PATCH. Only paid or public repos accept. Workaround: manual UI toggle or upgrade. - Enabling Dependabot on a long-dormant fleet surfaces backlog (100+ PRs in our case). Expected; subsequent weeks stay quiet. Doc-only change. Skipped by v2.0.1 doc-only classifier. --- docs/plans/2026-04-18-v2-rollout-playbook.md | 40 ++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/docs/plans/2026-04-18-v2-rollout-playbook.md b/docs/plans/2026-04-18-v2-rollout-playbook.md index 510544d..415a7dd 100644 --- a/docs/plans/2026-04-18-v2-rollout-playbook.md +++ b/docs/plans/2026-04-18-v2-rollout-playbook.md @@ -70,6 +70,43 @@ updates: After this, new versions of the source repo auto-PR themselves to consumers within a week. No more manual batch migrations. +### Phase 5 — Auto-merge Dependabot PRs (optional but strongly recommended) + +Enabling Dependabot without auto-merge produces a backlog problem: the first fleet-wide scan revealed 100+ pending dependency updates that had accumulated over months. Manually merging each is painful. + +Solution: a narrow-scope auto-merge workflow in every consumer that fires **only** for Dependabot PRs, **only** for patch + minor bumps (majors still require manual review). + +Two steps per repo: + +- **5a — Enable `allow_auto_merge: true`** via `PATCH /repos/{owner}/{repo}`. Idempotent. +- **5b — Install `.github/workflows/dependabot-auto-merge.yml`** via Contents API: + +```yaml +name: Dependabot Auto-Merge +on: + pull_request_target: + types: [opened, synchronize, reopened] +permissions: + contents: write + pull-requests: write +jobs: + auto-merge: + if: github.actor == 'dependabot[bot]' + runs-on: ubuntu-latest + steps: + - uses: dependabot/fetch-metadata@v2 + id: metadata + - if: steps.metadata.outputs.update-type == 'version-update:semver-patch' || steps.metadata.outputs.update-type == 'version-update:semver-minor' + env: + PR_URL: ${{ github.event.pull_request.html_url }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh pr review --approve "$PR_URL" + gh pr merge --auto --squash --delete-branch "$PR_URL" +``` + +Safety: `pull_request_target` runs the base-branch version of the workflow (PR can't bypass itself); `github.actor` is set by GitHub (not spoofable); the `update-type` check bounds the blast radius to patch + minor. + ## Pitfalls encountered | Pitfall | How we found it | How we handled it | @@ -80,6 +117,8 @@ After this, new versions of the source repo auto-PR themselves to consumers with | `claude-code-action` refuses to run when caller workflow changes | Phase 1 bellwethers failed with "exceeded turn limit" after 30s | Phase 4a ships a skip for the specific failure mode | | Unanchored `VERDICT: X` grep false-matches review prose | PR #47 self-review's text quoted the grep pattern | Anchor to line start/end in the Check verdict step | | Content-adjacent config files in "doc-only" allowlist | Local reviewer flagged CODEOWNERS, dependabot.yml | Explicit NON-DOC exclusion for security-adjacent meta files | +| `allow_auto_merge: true` silently rejected on some repos | Phase 5 PATCH returned 200 OK but the field stayed `false` | **Private + GitHub Free tier repos can't enable auto-merge.** Only paid (Pro/Team) or public repos accept the setting. Either upgrade the repo, make it public, or skip auto-merge there. User enables manually via UI (Settings → General → Pull Requests) as workaround. | +| Enabling Dependabot exposes backlog | Fleet-wide Dependabot turn-on produced 100+ PRs on day 1 | Expected — it's catching months of drift. Bulk-enable `--auto` on the backlog (`gh pr merge --auto` in a loop) or merge through them manually. Subsequent weeks stay quiet. | ## Timings observed @@ -90,6 +129,7 @@ After this, new versions of the source repo auto-PR themselves to consumers with | Phase 2 (23 repo batch) | 23 admin direct-pushes | 30 seconds | | Phase 3 (4 renames) | 8 API calls (create + delete per repo) | 15 seconds | | Phase 4 (27 pins + 27 dependabot.yml) | 54 admin direct-pushes | 45 seconds | +| Phase 5 (27 auto-merge workflows + 27 PATCH calls) | 54 API calls | 30 seconds | The PR-flow phases dominate. The admin batch phases are nearly free.