ci: run on pull_request and add the "CI passed" aggregator - #4
Merged
Conversation
The `main` ruleset (created 2026-07-29) requires a status check named "CI passed". No workflow in this repo produced it, and the only workflow here had no `pull_request` trigger at all — so nothing ran on a PR and the required check could never arrive. Every pull request was permanently unmergeable. It went unnoticed because both merged PRs (#1, #2) landed on 2026-06-29, a month before the ruleset existed; #3 is the first PR to meet the rule. "CI passed" is doppler's aggregator job name, so the ruleset appears to have been copied from doppler's without the workflow that makes the name true. Two changes: - `pull_request` trigger, with NO path filter. The required check must report on every PR, so the job has to run on every PR — a path filter would skip it on an unrelated change and reproduce the same deadlock. - a `ci-passed` job named "CI passed", gating on every other job, mirroring doppler's ci.yml aggregator so the org has one shape. `if: always()` so it still reports when a dependency fails, rather than being skipped and leaving a red PR indistinguishable from an unmergeable one. This workflow runs on its own PR (pull_request events use the merge ref), so the fix is self-bootstrapping: the PR that adds the check is the first to be gated by it.
hunterdsp
added a commit
to just-buildit/just-buildit.github.io
that referenced
this pull request
Jul 31, 2026
…s it Two defects found while validating this repo against the process it now documents. **1. Every PR here is unmergeable.** The `main` ruleset requires a status check named `CI passed`, and the only workflow (`mirror.yml`) has no `pull_request` trigger and reports no such check — so the required check can never arrive. The single merge path is an org-admin bypass, which is a required check that gates nothing: this project's own thesis pointed at its own infrastructure. That matters more here than anywhere else, because canonical `standard.mk` lives in this repo, so *every future change to the standard* has to come through a PR that cannot merge. Same shape, and same fix, as just-buildit/.github#4. Self-bootstrapping: `pull_request` workflows run from the merge ref, so the PR adding this check is the first one gated by it. **2. The new README contradicted the standard on where local targets live.** It said repo-only targets "go in `local.mk`", but `standard.mk`'s own comment says "in the Makefile or local.mk", the plan's criterion 1 explicitly permits "config + genuinely local targets" in the Makefile, and the reference adopter puts all 26 of its own targets there and passes every gate. Corrected to say what actually matters: naming them in `LOCAL_TARGETS`. **The CI is not a rubber stamp.** A broken publish here does not fail here — it fails in every adopter at once, the moment they re-vendor, because their `make lint` fetches this file with no cache. So the job checks the three things that would cost that: * the file still fails CLEANLY with the config surface unset (asserting on the message, since a syntax error and a deliberate `$(error)` look alike to make); * every feature group still defines its targets, with all nine flags on (>=38); * its own gates pass on a clean tree AND fail on a sabotaged one — a ghost-check that cannot catch a rule-less `.PHONY` is exactly the failure this standard exists to prevent. Plus, on `main` only, that Pages serves what is committed — the drift gate's question asked from the other side. All four verified locally against the published file before committing: the unset-config case errors naming `TEST_CMD`, all-flags-on lists 40 targets, the clean tree passes both gates, and the sabotaged tree fails naming `ghosty`.
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.
Fixes the deadlock found while reviewing #3: every pull request to this repo
is currently unmergeable.
The problem
The required check cannot be reported on a pull request, so the merge box waits
on something that will never arrive.
It looked fine because both merged PRs (#1, #2) landed 2026-06-29, and the
ruleset was created 2026-07-29 — every merge in this repo predates the rule
by a month. #3 is simply the first PR to meet it.
CI passedis doppler's aggregator job name(
doppler/.github/workflows/ci.yml:620), so the ruleset looks copied fromdoppler's without the workflow that makes the name true.
The fix
pull_requesttrigger, with no path filter — deliberately. The requiredcheck must report on every PR, so the job must run on every PR. A path
filter would skip it on an unrelated change and reproduce exactly the same
deadlock, just less often and more confusingly.
ci-passedjob named "CI passed", gating on every other job in thefile, mirroring doppler's aggregator so the org has one shape.
if: always()so it still reports when a dependency fails — skipped would makea red PR indistinguishable from an unmergeable one.
Self-bootstrapping
pull_requestevents run workflows from the merge ref, so this workflow runson its own PR. The PR that adds the required check is the first to be gated by
it — no chicken-and-egg, and no admin override needed here or on #3 afterwards.
Verification
push, pull_request, schedule, workflow_dispatch;jobs are
checkandci-passed; the aggregator'sname:is exactlyCI passed, matching the ruleset string.CI passedappears here, thefix works.
Note the irony for the plan in #3: this is the same drift class one level up —
a config copied into a second repo without the thing it depends on, unnoticed
until it fires.
🤖 Generated with Claude Code
https://claude.ai/code/session_01XeNc2g4pM4Sq2Dhds5zT6j