|
| 1 | +# Add auto-merge GitHub Actions workflow |
| 2 | + |
| 3 | +## Goal |
| 4 | + |
| 5 | +Add a workflow that automatically enables auto-merge on PRs from trusted bots |
| 6 | +(Dependabot and Scala Steward) for non-major version bumps, mirroring the |
| 7 | +pattern used in `wvlet/uni/.github/workflows/auto-merge.yml`. |
| 8 | + |
| 9 | +## Context |
| 10 | + |
| 11 | +- Recent PR history shows the repo regularly receives many bot PRs: |
| 12 | + - `dependabot[bot]` — for GitHub Actions version bumps |
| 13 | + - `scala-steward` — for Scala/sbt/Java library updates |
| 14 | +- These currently require manual merge from the maintainer. |
| 15 | +- Repo settings already allow auto-merge (`allow_auto_merge: true`) and squash |
| 16 | + is the default merge method. |
| 17 | +- CI passes branch-protection checks on PRs; once a PR is approved and CI is |
| 18 | + green, GitHub will merge it automatically. |
| 19 | + |
| 20 | +## Differences from wvlet/uni |
| 21 | + |
| 22 | +- **No GitHub App token.** wvlet/uni uses a GitHub App (`APP_ID` + |
| 23 | + `APP_PRIVATE_KEY`) to bypass the read-only `GITHUB_TOKEN` that GitHub |
| 24 | + hands to `pull_request` workflows triggered by Dependabot. msgpack/msgpack-java |
| 25 | + doesn't have that App configured, so this workflow uses |
| 26 | + `on: pull_request_target` instead — that event runs in the base-branch |
| 27 | + context where the workflow's declared `permissions:` block actually grants |
| 28 | + write access to `GITHUB_TOKEN`. We never check out PR head code, so the |
| 29 | + usual `pull_request_target` injection risk does not apply. |
| 30 | +- **Scala Steward actor is `scala-steward`**, not wvlet/uni's |
| 31 | + `scala-steward-wvlet[bot]` or `xerial-bot` (visible in `gh pr list`). |
| 32 | +- **Filter on `github.event.pull_request.user.login`**, not `github.actor`, |
| 33 | + because under `pull_request_target` the latter can resolve to the merger |
| 34 | + rather than the PR author. |
| 35 | + |
| 36 | +## Plan |
| 37 | + |
| 38 | +1. Add `.github/workflows/auto-merge.yml` with two jobs: |
| 39 | + - **auto-merge-dependabot**: triggers when `github.actor == 'dependabot[bot]'`, |
| 40 | + uses `dependabot/fetch-metadata@v3` to read the update type, and runs |
| 41 | + `gh pr merge --squash --auto` only when the update is **not** |
| 42 | + `version-update:semver-major`. |
| 43 | + - **auto-merge-scala-steward**: triggers when `github.actor == 'scala-steward'` |
| 44 | + and runs `gh pr merge --squash --auto` for all such PRs (Scala Steward |
| 45 | + does not surface a structured "major" signal the way Dependabot's |
| 46 | + fetch-metadata action does, so we rely on Scala Steward's own |
| 47 | + `pullRequests.allowedUpdates` config — already filtered upstream — and |
| 48 | + skip if the PR has a `semver-major` label). |
| 49 | +2. Set workflow-level `permissions` to the minimum required: |
| 50 | + `contents: write` and `pull-requests: write`. |
| 51 | +3. Use `GITHUB_TOKEN` directly via `env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}`. |
| 52 | + |
| 53 | +## Out of scope |
| 54 | + |
| 55 | +- Setting up a GitHub App for elevated bot identity. |
| 56 | +- Auto-approving PRs (a human approval may still be required by branch |
| 57 | + protection — auto-merge will simply wait for it). |
| 58 | +- Changing branch protection rules. |
| 59 | + |
| 60 | +## Validation |
| 61 | + |
| 62 | +- Lint the YAML by checking the file parses (visual review + actionlint if |
| 63 | + available). |
| 64 | +- After merge, watch the next dependabot/scala-steward PR to confirm |
| 65 | + auto-merge gets enabled. |
0 commit comments