Skip to content

fix(fleet-merge): enforce the author trust it documents, and be able to merge at all - #643

Merged
rubenvdlinde merged 1 commit into
mainfrom
fix/fleet-merge-can-actually-merge
Aug 30, 2026
Merged

fix(fleet-merge): enforce the author trust it documents, and be able to merge at all#643
rubenvdlinde merged 1 commit into
mainfrom
fix/fleet-merge-can-actually-merge

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Two bugs that cancelled each other out, so the Friday routine ran on schedule, reported success, and merged nothing — for weeks.

1. It could never merge

Development Branch Protection sets required_approving_review_count: 1 and grants bypass to OrganizationAdmin only. The workflow called gh pr merge --squash with no --admin, so GitHub refused every attempt. Evidence from the 2026-08-28 run (DRY_RUN: false):

3 merged/would-merge, 46 skipped.
VERDICT: zaakafhandelapp | #499 | merge refused by GitHub — left open
VERDICT: zaakafhandelapp | #495 | merge refused by GitHub — left open
VERDICT: versioniq        | #258 | merge refused by GitHub — left open

2. The author was read but never tested

The header has always said it refuses "PRs whose author is not trusted for unattended merge". Nothing enforced it — author was parsed and then only interpolated into a status line. Fixing (1) alone would have started merging functional work with no review. That is why both are in one change.

Dependency bumps are the class that is safe unattended: the diff is a version number, and the gates judging it are the ones a human reviewer would read. Everything else keeps its review.

'dependabot[bot]' is quoted deliberately — unquoted, the brackets are a case character class matching dependabott, not the literal login. Exercised directly:

ok    app/dependabot          -> TRUSTED
ok    dependabot[bot]         -> TRUSTED
ok    rubenvdlinde            -> refused
ok    app/github-actions      -> refused
ok    dependabott (glob trap) -> refused
ok    (empty author)          -> refused

3. The refusal reason is now kept

The old branch discarded stderr, so "refused by GitHub" named no cause and read as an ordinary conflict — which is precisely why this went undiagnosed. A refusal we cannot read is one we will misattribute.

Verified: YAML parses; bash -n clean on both run: blocks extracted from the parsed YAML (a YAML parse says nothing about the shell inside it).

…to merge

Two bugs that cancelled out, so the routine ran green weekly and merged
nothing.

1. --admin was never passed. Development Branch Protection requires 1
   approving review and grants bypass to OrganizationAdmin only, so a
   plain squash could not merge. The 2026-08-28 run: 3 merged/would-merge,
   46 skipped, every real attempt 'merge refused by GitHub'.

2. The author was read and never tested, despite the header promising to
   refuse authors not trusted for unattended merge. Fixing only (1) would
   have started merging functional work without review.

Also keeps the refusal text. The old branch discarded it, which is why
'refused by GitHub' named no reason and the cause went undiagnosed.
@rubenvdlinde

Copy link
Copy Markdown
Contributor Author

Agreed on both defects — I reached the same --admin diagnosis independently and have closed my #645 in favour of this, which is strictly better: it keeps the refusal text instead of discarding it, and the unenforced author check is the more serious of the two.

One consequence worth deciding deliberately rather than inheriting, on the same 2026-08-28 run (33163749650):

Refusal author Count
app/github-actionschore(release): *-unstable.* 18
other 2

18 of the 20 refusals were release version bumps, and the trusted list here does not include them. Before this PR they were attempted and refused; after it they will be skipped as untrusted. Either way they do not merge — so the --admin fix alone does not drain that 18.

That matters because those bumps are not cosmetic. They land by being merged:

92c7fa93  chore(release): 1.1.9-unstable.20260829214947 (#3085)
a0819e30  chore(release): 1.1.8-unstable.20260829125656 (#3044)

openregister's development currently reads 1.1.9-unstable.20260829214947, while 1.1.10-unstable (#3092) was superseded and closed unmerged — that bump was discarded, not deferred.

I am not arguing they should be blanket-trusted: app/github-actions is a broad identity that also opens PRs carrying real code. But a narrow allowance — that author and a chore(release): title, which the release workflow already constrains to appinfo/info.xml plus openapi.json and hard-fails outside that allow-list — would be as tight as the dependabot case and would close the loop this PR otherwise leaves open.

Happy either way; flagging it so it is a choice and not an oversight. Your call, since this is your PR.

@rubenvdlinde
rubenvdlinde merged commit 2b19e27 into main Aug 30, 2026
39 checks passed
@rubenvdlinde
rubenvdlinde deleted the fix/fleet-merge-can-actually-merge branch August 30, 2026 08:46
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