What happened
Renovate's auto-merged PRs are landing on main before their checks finish, and failing builds have already gone in.
reqstool/reqstool-client, three consecutive PRs:
| PR |
merged at |
build completed |
build result |
| #450 |
00:01:35 |
00:02:54 |
failure |
| #449 |
01:03:56 |
01:05:01 |
failure |
| #448 |
01:03:51 |
01:04:57 |
failure |
#450 was merged four seconds after renovate-approve[bot] approved it — while build still had 79 seconds to run. The merge did not race CI; it never waited for it.
Why
Three settings that are individually defensible and collectively remove every gate:
protect-main requires no status checks. rules on the live ruleset are deletion, non_fast_forward, pull_request, required_linear_history — there is no required_status_checks rule, in safe-settings/suborgs/all.yml or anywhere else.
- Renovate holds a ruleset bypass —
actor_id: 2740, actor_type: Integration, bypass_mode: pull_request — so the pull_request rule does not apply to its PRs either.
platformAutomerge: true in the shared preset, with automerge: true on minor and patch.
GitHub's auto-merge waits for required checks and required reviews. With no checks required and the review bypassed, "mergeable" is true the moment the PR opens, so it merges immediately. build is not required, so nothing waits for it.
Fix
Two changes, in order of how much they buy:
platformAutomerge: false (reqstool/.github#TBD). Renovate then merges the PR itself on its next run, and its own automerge waits for the branch to be green outright — every check, not just the required subset. This is the change that stops the bleeding, and it does not depend on any per-repo knowledge of check names.
- Drop Renovate's ruleset bypass (reqstool/.github-private#TBD). It is no longer needed:
renovate-approve[bot] supplies the approving review the pull_request rule wants — it did so on #450. Keeping the bypass means that any check made required in future silently would not apply to Renovate's PRs, which is the same failure again with more steps.
Not fixed here
protect-main still requires no status checks, so a human PR can also be merged red. Fixing that properly means per-repo required contexts — build in reqstool-client is not the context name in every repo — which is safe-settings/repos/<repo>.yml work, one file per repo, and each context must have run on a real PR before it is required or it blocks every PR on that repo. Worth a separate issue.
Also
reqstool-client's main has taken three failing builds. Worth checking whether it is currently green before anything else is cut from it.
Compare: skillsgateway reached the same conclusion from the other direction — it requires seven checks and gives Renovate no bypass, and its preset uses platformAutomerge: false for exactly the reason above.
What happened
Renovate's auto-merged PRs are landing on
mainbefore their checks finish, and failing builds have already gone in.reqstool/reqstool-client, three consecutive PRs:buildcompletedbuildresult#450 was merged four seconds after
renovate-approve[bot]approved it — whilebuildstill had 79 seconds to run. The merge did not race CI; it never waited for it.Why
Three settings that are individually defensible and collectively remove every gate:
protect-mainrequires no status checks.ruleson the live ruleset aredeletion,non_fast_forward,pull_request,required_linear_history— there is norequired_status_checksrule, insafe-settings/suborgs/all.ymlor anywhere else.actor_id: 2740,actor_type: Integration,bypass_mode: pull_request— so thepull_requestrule does not apply to its PRs either.platformAutomerge: truein the shared preset, withautomerge: trueon minor and patch.GitHub's auto-merge waits for required checks and required reviews. With no checks required and the review bypassed, "mergeable" is true the moment the PR opens, so it merges immediately.
buildis not required, so nothing waits for it.Fix
Two changes, in order of how much they buy:
platformAutomerge: false(reqstool/.github#TBD). Renovate then merges the PR itself on its next run, and its own automerge waits for the branch to be green outright — every check, not just the required subset. This is the change that stops the bleeding, and it does not depend on any per-repo knowledge of check names.renovate-approve[bot]supplies the approving review thepull_requestrule wants — it did so on #450. Keeping the bypass means that any check made required in future silently would not apply to Renovate's PRs, which is the same failure again with more steps.Not fixed here
protect-mainstill requires no status checks, so a human PR can also be merged red. Fixing that properly means per-repo required contexts —buildinreqstool-clientis not the context name in every repo — which issafe-settings/repos/<repo>.ymlwork, one file per repo, and each context must have run on a real PR before it is required or it blocks every PR on that repo. Worth a separate issue.Also
reqstool-client'smainhas taken three failing builds. Worth checking whether it is currently green before anything else is cut from it.Compare:
skillsgatewayreached the same conclusion from the other direction — it requires seven checks and gives Renovate no bypass, and its preset usesplatformAutomerge: falsefor exactly the reason above.