You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
CI: required status check embeds the Julia version, so a pin bump will deadlock every PR #38
The Optimus-Branch ruleset (created 2026-09-21, id 23793298) requires the status check context:
Julia 1.12.5 / ubuntu-24.04
That context string is generated from the job's matrix values, so the Julia version is part of the required check's name. The moment the pin moves — 1.12.5 → anything else — the workflow starts reporting a check called Julia 1.13.0 / ubuntu-24.04, and the context named in the ruleset is never reported at all.
A required check that never reports is not a failure; it is silence, and silence never satisfies a required status check. Every PR then sits on "Expected — Waiting for status to be reported" indefinitely, clearable only by an admin bypass.
This is latent, not live: the pin currently matches. It will fire on the next Julia bump — most likely via Dependabot or a routine toolchain update, i.e. exactly when nobody is looking at the ruleset.
The same reasoning applies to ubuntu-24.04, which is also pinned deliberately (the R apt pin targets it).
Acceptance criteria
The test job's rendered check name is version-stable — e.g. Julia tests — with the Julia and runner versions moved into the step body or kept in the matrix but excluded from the job name:.
The Optimus-Branch ruleset's required_status_checks entry is updated to the new context in the same change, so the two never disagree.
A Julia pin bump is demonstrated (locally or on a scratch branch) to still report the required context.
config/ci/ pin-coupling tests (test_install_pins.jl) still pass — the version must remain asserted somewhere, just not in the check's name.
Notes
Non-obvious constraint for whoever picks this up: do not add a path filter to the workflow carrying a required context. A paths:-filtered workflow reports nothing on a PR that misses its paths, which deadlocks the gate in the same way. This is why contracts (ui.yml, filtered to ui/**) was deliberately excluded from the ruleset.
Correction: the first attempt (#39) did not fix this, and made it live on main
#39 renamed the job to Julia tests and I reported the required check as version-stable. That was wrong, and the reason is worth recording here because it is the whole substance of this issue.
Measured on #39's own head 776e340d, after it had landed:
Julia tests (1.12.5, ubuntu-24.04) <- what GitHub actually posted
Julia tests <- what the ruleset requires
GitHub appends the matrix combination to a job's posted check name whenever the name: does not itself reference the matrix. The direction is counter-intuitive: the old name, Julia ${{ matrix.julia-version }} / ${{ matrix.os }}, was suppressing the suffix; replacing it with a static string switched the suffix on. A 1×1 matrix is still a matrix. So a fixed name made the check name less stable, not more — both pins stayed embedded, the required context Julia tests was never reported at all, and main went into precisely the deadlock described above. #39 merged only because an admin bypass was available.
The control was in the same API response the whole time: Repo hygiene (licence · format · lint · commit), a job with no matrix, posts its name: verbatim.
Why the guard I added in #39 did not catch it. It asserted !occursin("${{", name) over the YAML name: field. The consumer — the ruleset — matches the rendered check-run name. Different artefact, so it went green on a broken fix. The "bump demonstration" had the same defect: it parsed name: across three hypothetical pins and called the output "the check name". Neither could fail. ci.yml triggers only on push: branches: [main] and pull_request: branches: [main], so a branch push renders no check at all — the name is observable only on a PR, and that constraint is exactly what tempts you into asserting it "by construction".
The matrix selected exactly one combination and bought nothing, so it is removed rather than worked around. runs-on: ubuntu-24.04 and setup-julia version: "1.12.5" are literals, each keeping the reasoning that sat beside its matrix entry.
Evidence, read off #40's head 7adaeb74 via commits/<sha>/check-runs — the consumer's artefact, not the YAML:
Julia tests <- exact, no suffix
Repo hygiene (licence · format · lint · commit)
The guard now asserts both necessary conditions over every job in the file: the name interpolates nothing and the job has no strategy.matrix. Against the previous commit it fails on test alone (5 pass / 1 fail), so it discriminates rather than blanket-failing. If a matrix is ever genuinely wanted, the required context must first move to a matrix-free aggregator job — which would then need if: ${{ always() }} and an explicit needs.test.result == 'success', since a skipped job passes a required check.
#
acceptance criterion
status
1
version-stable job name
✅ posted name is exactly Julia tests
2
ruleset context updated in the same change
✅ Julia tests, unchanged and now satisfiable
3
bump demonstrated
✅ a bump moves only a literal; with no matrix there is nothing for GitHub to append
Activity
hyperpolymath commentedon Sep 21, 2026
Correction: the first attempt (#39) did not fix this, and made it live on
main#39 renamed the job to
Julia testsand I reported the required check as version-stable. That was wrong, and the reason is worth recording here because it is the whole substance of this issue.Measured on #39's own head
776e340d, after it had landed:GitHub appends the matrix combination to a job's posted check name whenever the
name:does not itself reference the matrix. The direction is counter-intuitive: the old name,Julia ${{ matrix.julia-version }} / ${{ matrix.os }}, was suppressing the suffix; replacing it with a static string switched the suffix on. A 1×1 matrix is still a matrix. So a fixed name made the check name less stable, not more — both pins stayed embedded, the required contextJulia testswas never reported at all, andmainwent into precisely the deadlock described above. #39 merged only because an admin bypass was available.The control was in the same API response the whole time:
Repo hygiene (licence · format · lint · commit), a job with no matrix, posts itsname:verbatim.Why the guard I added in #39 did not catch it. It asserted
!occursin("${{", name)over the YAMLname:field. The consumer — the ruleset — matches the rendered check-run name. Different artefact, so it went green on a broken fix. The "bump demonstration" had the same defect: it parsedname:across three hypothetical pins and called the output "the check name". Neither could fail.ci.ymltriggers only onpush: branches: [main]andpull_request: branches: [main], so a branch push renders no check at all — the name is observable only on a PR, and that constraint is exactly what tempts you into asserting it "by construction".The real fix — #40
The matrix selected exactly one combination and bought nothing, so it is removed rather than worked around.
runs-on: ubuntu-24.04and setup-juliaversion: "1.12.5"are literals, each keeping the reasoning that sat beside its matrix entry.Evidence, read off #40's head
7adaeb74viacommits/<sha>/check-runs— the consumer's artefact, not the YAML:The guard now asserts both necessary conditions over every job in the file: the name interpolates nothing and the job has no
strategy.matrix. Against the previous commit it fails ontestalone (5 pass / 1 fail), so it discriminates rather than blanket-failing. If a matrix is ever genuinely wanted, the required context must first move to a matrix-free aggregator job — which would then needif: ${{ always() }}and an explicitneeds.test.result == 'success', since a skipped job passes a required check.Julia testsJulia tests, unchanged and now satisfiabletest_install_pins.jlpassing🤖 Generated with Claude Code
https://claude.ai/code/session_01X3hgXxWm6umMgZkjYyHnnm
fix(ci): drop the 1x1 matrix so the check name is actually stable
docs: repoint the pin-web docs at the setup-julia step
docs: repoint the pin-web docs at the setup-julia step
fix(ci): give the required status check a version-stable name
fix(ci): drop the 1x1 matrix so the check name is actually stable