Skip to content

feat(release): ready and merge, from what actually ran — no auto-merge - #107

Merged
ocots merged 1 commit into
mainfrom
feat/release-ready
Oct 19, 2026
Merged

ocots merged 1 commit into
mainfrom
feat/release-ready

Conversation

@ocots

@ocots ocots commented Oct 19, 2026

Copy link
Copy Markdown
Member

Replaces auto-merge and required checks by a check of what actually ran.

Why. A label-gated workflow runs once per label added. A run whose jobs are all skipped (the label added was another one) reports success, and GitHub shows the latest result of a check name. With required checks and auto-merge, a release PR could be merged while its real tests had failed or were still running; aggregators (ci-ok) do not help, they are skipped-and-green in those runs too.

release.jl ready --repo R --pr N reads the Actions runs and jobs of the head commit (not the checks): for each workflow, the latest run that executed jobs counts (a run with every job skipped has conclusion skipped and is ignored); it must be complete, every job passed or skipped, every job gated by a label the release needs must have run and passed (GPU: the job of the GPU label on the PR, kkt else occidata); the release gate must have passed; the PR open, not a draft, up to date with main, no conflict. A run in progress → wait.

release.jl merge --repo R --pr N --confirm runs ready again and merges with --match-head-commit (GitHub refuses if the head changed). release/v… branches only; a dry run without --confirm.

docs/conventions/required-checks.md (aggregators, auto-merge settings) is removed; release-gate.md gains The merge.

Checks:

  • ready on the real CTBase.jl#617 (merged): for each workflow it picks the run that executed jobs (e.g. CI.yml run 39146040585, not the skipped ones), accepts the skipped build-gpu job of the docs, and reports the PR merged and behind main → not ready, as expected.
  • 26 new tests on a fake GitHub: the masking trap (a failed run hidden by a later all-skipped run), a gated job skipped, the GPU fallback, no GPU label, a missing label, a run in progress, the gate or another check failing, no gate run, behind / conflicting / unknown / draft / merged, merge refused on a non-release branch or a changed head, the parsing of jobs. The suite passes on Julia 1.10, 1.12 and 1.13 locally. Mutating the choice of the run, or the gated-job rule, makes them fail.
  • actionlint and markdownlint (GEN2): clean.

🤖 Generated with Claude Code

A label-gated workflow runs once per label added, and a run whose jobs are
all skipped reports success; GitHub shows the latest result of a check name.
So required checks and auto-merge can merge a release PR while its real
tests failed or still run.

release.jl ready reads the Actions runs and jobs of the PR's head commit:
for each workflow, the latest run that executed jobs counts; it must be
complete and green, every job gated by a label the release needs must have
run and passed (one GPU runner, kkt else occidata), the release gate must
have passed; the PR open, not a draft, up to date with main, no conflict.
release.jl merge checks again and merges with --match-head-commit,
release/v branches only, with --confirm.

The page on required checks and aggregators is removed.

Tests on a fake GitHub (the masking trap, a skipped gated job, GPU fallback,
a missing label, a run in progress, the gate or another check failing, the
PR's state, merge refused, parsing); mutating the choice of the run or the
gated-job rule makes them fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ocots
ocots merged commit 5e91401 into main Oct 19, 2026
4 checks passed
@ocots
ocots deleted the feat/release-ready branch October 19, 2026 09:55
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