Skip to content

ci: make the Dependabot heal workflow actually finish the job - #85

Merged
Theauxm merged 1 commit into
mainfrom
ci/dependabot-self-heal
Sep 17, 2026
Merged

Theauxm merged 1 commit into
mainfrom
ci/dependabot-self-heal

Conversation

@Theauxm

@Theauxm Theauxm commented Sep 17, 2026

Copy link
Copy Markdown
Member

The heal workflow has never landed a commit. On #84 it regenerated the lockfile correctly and was then rejected outright:

GH013: Repository rule violations found for refs/heads/dependabot/nuget/...

  • Changes must be made through a pull request.
  • Commits must have verified signatures.

A plain git commit in a runner has no signing key. It now writes through the createCommitOnBranch GraphQL mutation instead, which GitHub signs itself, so the heal lands Verified like Dependabot's own commits and no signing key has to exist in CI. The org ruleset still has to stop requiring a pull request on dependabot/** for the write to be allowed at all; the signature rule can stay.

It keeps authenticating with GITHUB_TOKEN rather than moving to an App token or a PAT. Either of those would avoid the approval click described below, but both mean a long-lived credential in Dependabot secrets, and an App private key never expires and can mint write tokens for every repo it is installed on. GITHUB_TOKEN stores nothing. The trade is one "Approve and run" press per healed PR, on a visit already being made to merge it.

Beyond the write: Dependabot rewrites project files on a grouped bump. When the transitive graph resolves one package at different versions across projects, it adds <PackageReference ... VersionOverride="..."> to projects that never referenced it, several pinned to the version being bumped away from. Nothing reverted those, so lockfiles regenerated on top of the injection. The revert is re-derived with git in the committing job rather than trusted from the patch, so the job that runs dependency code still hands over nothing but lockfiles.

The regenerating restore now passes -p:NuGetAudit=false. Directory.Build.props promotes NU1901-NU1904 to errors, so an advisory anywhere in the graph aborted the regeneration, which is precisely the state a security bump arrives in. The PR build still audits.

On the config side, csharpier and PublicApiGenerator are ignored. Each has to move in one commit with the artefact it invalidates -- the repo-wide format and the PublicApi baseline -- which a bot PR cannot do, so it just leaves the check failing every time. Roslyn moves to its own group so that when its bump does need a human it does not take the rest of the week's updates with it, and the PR limit drops to three.

The heal workflow has never landed a commit. On #84 it regenerated the lockfile
correctly and was then rejected outright:

  GH013: Repository rule violations found for refs/heads/dependabot/nuget/...
  - Changes must be made through a pull request.
  - Commits must have verified signatures.

A plain `git commit` in a runner has no signing key. It now writes through the
createCommitOnBranch GraphQL mutation instead, which GitHub signs itself, so the
heal lands Verified like Dependabot's own commits and no signing key has to
exist in CI. The org ruleset still has to stop requiring a pull request on
dependabot/** for the write to be allowed at all; the signature rule can stay.

It keeps authenticating with GITHUB_TOKEN rather than moving to an App token or
a PAT. Either of those would avoid the approval click described below, but both
mean a long-lived credential in Dependabot secrets, and an App private key never
expires and can mint write tokens for every repo it is installed on.
GITHUB_TOKEN stores nothing. The trade is one "Approve and run" press per healed
PR, on a visit already being made to merge it.

Beyond the write: Dependabot rewrites project files on a grouped bump. When the
transitive graph resolves one package at different versions across projects, it
adds <PackageReference ... VersionOverride="..."> to projects that never
referenced it, several pinned to the version being bumped away from. Nothing
reverted those, so lockfiles regenerated on top of the injection. The revert is
re-derived with git in the committing job rather than trusted from the patch, so
the job that runs dependency code still hands over nothing but lockfiles.

The regenerating restore now passes -p:NuGetAudit=false. Directory.Build.props
promotes NU1901-NU1904 to errors, so an advisory anywhere in the graph aborted
the regeneration, which is precisely the state a security bump arrives in. The
PR build still audits.

On the config side, csharpier and PublicApiGenerator are ignored. Each has to
move in one commit with the artefact it invalidates -- the repo-wide format and
the PublicApi baseline -- which a bot PR cannot do, so it just leaves the check
failing every time. Roslyn moves to its own group so that when its bump does
need a human it does not take the rest of the week's updates with it, and the PR
limit drops to three.
@codecov

codecov Bot commented Sep 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@Theauxm
Theauxm merged commit adb61cb into main Sep 17, 2026
6 of 8 checks passed
@Theauxm
Theauxm deleted the ci/dependabot-self-heal branch September 17, 2026 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant