ops: make the drift check see rulesets, not just branch protection (#36)

The check reported branch protection fully green while a repository ruleset on
the same branch required two status checks that no workflow produces —
'Build, Lint & Test' and 'All checks passed', names left behind when the jobs
were renamed. Nothing could merge without --admin, and the report said
everything was fine.

That is the worst shape a check can take: confident and blind. A branch can be
governed by classic protection and a ruleset at once, independently, and the
stricter wins. Reading one and calling it the answer is how a broken gate stays
invisible for months while the team learns to route around it.

--check now reads active rulesets too, and compares each required check against
what recent pull requests actually report. A rule waiting on a check that never
arrives does not slow a branch — it closes it.

Sampling uses recent PR heads rather than main's head, because the aggregate
gate only runs on pull_request; sampling main would report it as never seen and
manufacture the opposite false alarm.
This commit is contained in:
SatoshiQaziMuhammed
2026-08-01 21:04:26 -07:00
committed by GitHub
parent 39b71a428e
commit b289bbc0ae
2 changed files with 70 additions and 0 deletions
+14
View File
@@ -131,6 +131,20 @@ Get `<ENV_ID>` from `gh api repos/:owner/:repo/actions/runs/<RUN_ID>/pending_dep
This came up on 2026-07-31: a stale run sat in `waiting` and blocked the deploy
of the run behind it until it was rejected.
### Two layers, one branch
A branch can be governed by classic protection **and** a repository ruleset at
the same time, independently, and the stricter of the two wins. That is how
`main` here spent months unmergeable without anyone knowing why: classic
protection asked for `CI Gate ✅`, while a ruleset on the same branch asked for
`Build, Lint & Test` and `All checks passed` — two names no workflow has
produced since the jobs were renamed. Every merge went through `--admin`, and
the habit read as "review is slow" rather than "the gate is broken".
`--check` now reports both, and flags a required check that nothing reports.
A rule demanding a check that never arrives does not slow a branch down; it
closes it, silently, and the drift report will say everything is fine.
### Reviewer
`REVIEWER_ID` is a numeric user id rather than a login, because the API takes ids