diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b6b0f7ea..14189ec7 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,8 +6,11 @@ updates: - package-ecosystem: nuget directory: / schedule: - interval: weekly - day: monday + # Monthly, not weekly — batches a month of bumps into one wave instead of four, + # so the PR volume (one per group) lands 12×/year not 52×. Patch/minor auto-merge + # (see .github/workflows/dependabot-auto-merge.yml) clears the routine ones without + # a human; only majors wait for a person. + interval: monthly open-pull-requests-limit: 5 labels: - dependencies @@ -62,6 +65,16 @@ updates: # paths still behave. Add majors back to the ignore list as they ship # breaking changes; remove when a dedicated migration PR has landed. ignore: + # Aspire minor/patch bumps can't land as a lone dependabot PR: dependabot updates the + # Aspire.Hosting.* PackageVersions but CANNOT touch the Aspire.AppHost.Sdk pin in + # NextAurora.AppHost.csproj (an MSBuild SDK ref, not a NuGet PackageReference), so the + # SDK/runtime skew fails at build/startup (CLAUDE.md "Aspire SDK and runtime packages + # must match"). Aspire bumps also drag MessagePack (via StreamJsonRpc), colliding with + # the security pin. So Aspire is a DELIBERATE, coordinated bump (Hosting packages + SDK + + # MessagePack, build-verified), not a weekly auto-PR. Ignore minor/patch; a major still + # shows up (it needs a migration PR anyway). Precedent: #189 closed for exactly this. + - dependency-name: "Aspire.*" + update-types: ["version-update:semver-minor", "version-update:semver-patch"] # WolverineFx majors are deferred pending a dedicated migration PR — a # major can break host startup or the saga/outbox/concurrency paths, and # shouldn't land as an unreviewed weekly bump. The 5→6 migration already @@ -70,6 +83,11 @@ updates: # `wolverine` group above keeps the whole family in step). - dependency-name: "WolverineFx*" update-types: ["version-update:semver-major"] + # NSubstitute 6.0 tightened Arg.Is predicate nullability (CS8602 under + # TreatWarningsAsErrors); a test-mock major isn't worth a code change on a weekly + # bump. 5.x is stable. Take 6.x deliberately if there's a reason. #192 closed for this. + - dependency-name: "NSubstitute" + update-types: ["version-update:semver-major"] - package-ecosystem: github-actions directory: / diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml new file mode 100644 index 00000000..6d3e43ba --- /dev/null +++ b/.github/workflows/dependabot-auto-merge.yml @@ -0,0 +1,50 @@ +name: Dependabot auto-merge + +# Auto-merges routine dependency bumps so version churn stops landing in a human's lap. +# Patch + minor updates: approved and set to auto-merge (GitHub merges them once every +# required check is green — the same CI gate a human would wait for). MAJOR updates are +# left alone: a major can carry breaking API changes (FluentValidation 11→12 was one this +# repo saw), so those still want a person to read the release notes. +# +# Scope: dependabot-authored PRs only. Nothing here can merge human PRs. +# +# NOTE on the review requirement: if the branch ruleset requires an approving review, +# the `gh pr review --approve` step below (run as the github-actions bot) satisfies it — +# BUT only if the org/repo setting "Allow GitHub Actions to create and approve pull +# requests" is enabled (Settings → Actions → General). If that's off, the approve step +# fails and auto-merge waits forever; either enable that setting or add `dependabot[bot]` +# to the ruleset's bypass list. + +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: meta + uses: dependabot/fetch-metadata@v2 + + - name: Approve + 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 review --approve "$PR_URL" + gh pr merge --auto --squash "$PR_URL" + env: + PR_URL: ${{ github.event.pull_request.html_url }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Flag majors for manual review + if: steps.meta.outputs.update-type == 'version-update:semver-major' + run: | + gh pr comment "$PR_URL" --body "🔎 **Major version bump — held for manual review.** \ + Auto-merge covers patch/minor only; a major can carry breaking changes (read the release \ + notes, check the saga/outbox/concurrency paths, then merge)." + env: + PR_URL: ${{ github.event.pull_request.html_url }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}