ci(release): document and pin the release-PR red check as GitHub's GITHUB_TOKEN approval gate - #169
Merged
Conversation
…THUB_TOKEN approval gate
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Every connect-java release PR shows a red
Build Pull Requestcheck that can never go green. ThisPR documents what that check actually is above the
on:block ofpullrequest.yml, states the rulethat follows from it, and pins both with an offline contract test. No workflow behaviour changes, no
paths/filter change, no release cut (ci:prefix, workflow + test sources only).Mechanism (settled on geyserlite, card
t_3d60edd7; re-verified read-only here)The red check is GitHub's approval gate for pull requests created with
GITHUB_TOKEN, not abroken job and not a trigger-filter artefact:
connect-java evidence (2026-09-27, read-only)
Gated runs of this workflow (
event=pull_request, actorgithub-actions[bot], branchrelease-please--branches--main--components--connect-java, 0 jobs,conclusion=failureafter therelease PR merges):
622af57fbddb305cOn release PR #167's head
622af57fthe API shows exactly the two shapes side by side:98357508591—GitHub Actions,status=completed,conclusion=failure,latest_check_runs_count=0(the gated run: it never executes, so it can never go green);98357509913—success, 2 check runsbuild (17)andbuild (21)from run36324299434, the
workflow_dispatchrun
release-please.ymldispatched for the release branch (dispatched events are exempt from the gate).Supporting facts:
GET /repos/minekube/connect-java/branches/main/protection→ 404 "Branch not protected", so norequired checks exist today: the deadlock trap is latent, not live.
paths:filter, so it matches every pull request — the release PRon purpose. That is why the gated run exists at all: a workflow whose trigger does not match gets
no run whatsoever (a docs-only PR produces zero runs). A filter that skipped the release PR's own
files (
.release-please-manifest.json,CHANGELOG.md— that is the whole file set, observed onchore(main): release 0.15.13 #165 and chore(main): release 0.15.14 #167) would only turn an accepted red check into a missing one.
32509901978 (head
7ec291f7,the head that merged) did execute green — and it reports
run_attempt=2withtriggering_actor=robinbraemer: a human with write access approved the gated run from the pullrequest page, which is the documented manual remedy. The never-approved sibling
32509874033stayed at 0 jobs on the previous headbddb305c. So the gate holds acrossgeyserlite/gate/connect-java/vialite without exception; the approved attempt is what produced the
build (17)/build (21)check runs for the merged head.Changes
.github/workflows/pullrequest.yml— acceptance note above theon:block: what the redcheck is, that this workflow matches release PRs on purpose, the 0.15.7 approval evidence, and the
rule that follows —
Build Pull Request(or anyBuild Pull Request / …) must never be addedto
main's required status checks, because the gated run reports no check run at all. The onlycontexts a release PR can satisfy are the native
build (17)/build (21)check runs of thedispatched build.
.github/workflows/release-please.yml— a comment on the release-PR validation step tying thedispatch to that accepted red check (the dispatched run is the evidence the step audits).
core/src/test/java/com/minekube/connect/release/ReleaseBranchCheckContractTest.java(new) —the offline contract that keeps the note honest, in the shape of geyserlite's
go/release_check_contract_test.go: workflow name isBuild Pull Request; the gated workflowstill matches the release PR's file set; it is the only workflow a
pull_requestevent reaches(the control that a non-matching trigger yields no run at all); the release-please action still
receives no
token:; nothing is mirrored into branch protection (the connect-java form of"only
lint-testis mirrored"); and the only contexts a release PR reports are exactlybuild (17)+build (21), derived from the workflow's own job name and matrix. Plus apathsmatcher table and a raw-text pin on the note itself, so deleting or hollowing it out reds a test
instead of silently losing the reasoning.
core/src/test/java/com/minekube/connect/release/ReleasePleaseCheckAuditTest.java— one addedtest: the release PR is validated through the checks of the run release-please dispatches, never
through a context named after the gated workflow.
No behaviour change: the merge step, its
--merge --match-head-commitsemantics and the auto-mergepath (pinned by #166/#168) are untouched, and the phantom is deliberately not "fixed" by a
filter change.
RED → GREEN
The note pin was run against the unfixed workflows first:
After adding the note (functionality unchanged) the same suite is green, and the contract guard has
teeth — 8 weakening mutations are each rejected with a
release-branch-check contract:reason:A matching
pathsfilter (e.g.core/**+CHANGELOG.md) is explicitly accepted, so the guardforces a re-decision on the facts that matter rather than on every future edit.
Verification
./gradlew build(JDK 21, same command CI runs) — BUILD SUCCESSFUL, 442 tests / 91 classes,0 failures, 0 skipped.
:core:test --tests '*Release*Test*'— 62 tests incom.minekube.connect.release, green(including the untouched
ReleasePleasePayloadTest,ReleaseWorkflowShellBoundaryTest,ReleaseAssetVerificationTest, Hangar/Modrinth/repair contracts).actionlint .github/workflows/pullrequest.yml .github/workflows/release-please.yml— clean.core/build.gradle.ktsalready declares the whole.github/workflowsdirectory as atasks.testinput, so these edits re-run the suite instead of being served from Gradle's cache.
Left to Robin (deliberately not done here)
release-please open its PR with a GitHub App/PAT token instead of
GITHUB_TOKEN— a credentialchange across all four repos, filed as a blocked decision card by
t_3d60edd7.GITHUB_TOKENhas no administrationpermission); the read-ready recipe lives in the skill reference.