From 665d64add150cf83e284e54b46f73c8ac76f1fcc Mon Sep 17 00:00:00 2001 From: Mitch Allen Date: Wed, 5 Aug 2026 14:16:38 -0400 Subject: [PATCH] Auto-merge low-risk Dependabot bumps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ports the workflow from random-mcp-server. Scope: all github-actions updates, plus npm/docker minor + patch. Majors always stay manual, and this session showed why — the TypeScript 5.9 -> 7.0 bump broke the build outright (TS7016) and the Node 24 -> 25 base image was declined for being non-LTS. Both needed a human. Two deliberate differences from the source workflow: - Merges with --merge, not --squash, to match this repo's history. - Tests the npm ecosystem with startsWith('npm') rather than a literal. package-ecosystem is Dependabot's internal id, not the friendly name in dependabot.yml: npm reports as `npm_and_yarn`. random-mcp-server has this bug today — it tests `== 'pip'` while its real output is `uv`, so its Python bumps never auto-merge. Auto-merge is only safe with required checks to wait on, so main is now protected requiring `test` and `docker`. enforce_admins stays off so direct version-bump pushes to main still work, and no review is required (a review requirement would stall every Dependabot PR on a solo repo). Condition verified against this session's real PRs: actions/fast-uri/ cucumber auto-merge; the TypeScript and Node majors stay manual. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/dependabot-auto-merge.yml | 45 +++++++++++++++++++++ CLAUDE.md | 9 +++++ 2 files changed, 54 insertions(+) create mode 100644 .github/workflows/dependabot-auto-merge.yml diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml new file mode 100644 index 0000000..f0b9e8c --- /dev/null +++ b/.github/workflows/dependabot-auto-merge.yml @@ -0,0 +1,45 @@ +name: dependabot-auto-merge +# Auto-merges low-risk Dependabot PRs once the required CI checks pass. +# Native auto-merge waits for the branch-protection checks on main (test + +# docker), so a bump only lands if the workflows still go green. Scope: +# - github-actions: all updates (CI-only, low blast radius). +# - npm / docker: minor + patch only — major bumps stay manual for review. +# +# Majors are excluded on purpose, and recent history shows why: the TypeScript +# 5.9 -> 7.0 bump broke the build outright (TS7016), and the Node 24 -> 25 +# base-image bump was declined for being a non-LTS release. Both needed a human. +# +# Merges with --merge rather than --squash to match this repo's history. +# +# NB: package-ecosystem is Dependabot's internal identifier, not the friendly +# name from dependabot.yml — npm reports as `npm_and_yarn` and Actions as +# `github_actions` (they match the dependabot// branch prefix). A +# literal `== 'npm'` would silently never match, which is exactly the trap the +# sibling random-mcp-server repo fell into: it tests `== 'pip'` while the real +# output there is `uv`, so its Python bumps never auto-merge. Hence startsWith. +on: pull_request + +permissions: + contents: write + pull-requests: write + +jobs: + auto-merge: + runs-on: ubuntu-latest + if: github.actor == 'dependabot[bot]' + steps: + - name: Fetch Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@v3 + + - name: Enable auto-merge for in-scope updates + if: >- + startsWith(steps.metadata.outputs.package-ecosystem, 'github') + || ( (steps.metadata.outputs.package-ecosystem == 'docker' + || startsWith(steps.metadata.outputs.package-ecosystem, 'npm')) + && (steps.metadata.outputs.update-type == 'version-update:semver-minor' + || steps.metadata.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 }} diff --git a/CLAUDE.md b/CLAUDE.md index 846716e..fca6bd2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -53,6 +53,15 @@ Run `gh issue list` for the current state. github-actions. `@types/*` and other minor/patch npm bumps are **grouped** into single PRs; majors stay individual so each gets its own review. Security updates are independent of this file and arrive regardless. +- **Low-risk Dependabot PRs auto-merge** via + `.github/workflows/dependabot-auto-merge.yml`: all github-actions updates, + plus npm/docker **minor and patch**. Majors always stay manual — the + TypeScript 5.9 → 7.0 bump broke the build and the Node 24 → 25 base image was + declined, and both needed a human. This relies on branch protection: `main` + requires the `test` and `docker` checks, which is what native auto-merge + waits for. Without required checks, auto-merge would land PRs *without* CI + gating them. `enforce_admins` is off, so direct version-bump pushes to `main` + still work. - **Transitive CVEs are pinned via `overrides`,** not by adding direct dependencies — see the `overrides` block in `package.json` (`js-yaml`, `qs`, `brace-expansion`). When a follow-up advisory lands for something already