ci: split release validation into a job matrix - #13
Merged
Conversation
The release workflow ran every lane serially in one `validate` job, so one runner linked every package, backend, and provider permutation into a single `target/`. Disabling debug info bought headroom but left the structural cause: `scripts/check-ai-provider-lanes.sh` alone relinks the whole graphql-orm-ai test binary set seven times in that directory. Decompose release validation the way CI already is - workspace integrity, neutral packages, ORM, alternate features, AI GraphQL naming, AI PostgreSQL parity, router, router MSRV - and fan the AI provider lanes across a matrix so each provider feature gets its own runner and its own `target/`. The lane set comes from `--list` in the lane runner rather than being restated in YAML, so a new provider cannot be silently dropped from the release matrix. Every command the single job ran still runs, with the lockfile fixed. The one exception is the catalogue/tool-profiles rustdoc lane, which the job ran twice with identical flags and now runs once inside the superset neutral-package lane. A `validate` fan-in job requires every lane to have succeeded, and asserts it explicitly so a future condition on a lane cannot quietly narrow what an immutable release was verified against. Tagging, attestation, and publication are unchanged and depend on that fan-in. The identity proof keeps the protected `release` environment on the workflow's entry job, so one human approval still gates the run before any lane compiles anything, and the publication job depends on it. The disk reclaim step becomes a local composite action and is used where compiling still fills a runner: the provider lanes and the optional router artifact build. Documentation impact: documentation updated. The release runbook now states that validation is parallel jobs that each own their `target/`, and the testing guide documents the `--list` lane enumeration. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Summary
Restructures
.github/workflows/release.ymlso its validation runs as a job matrix mirroringci.yml, instead of one serialvalidatejob that relinked every AI provider feature combination into a singletarget/and exhausted the runner disk (the structural fix deliberately left open after ce14eb0's debug-info mitigations).guardproves source identity and carries thereleaseenvironment approval, so a human still approves before anything compiles and exactly once per run.workspace-integrity,neutral-packages,orm,ai-provider-lanes×7 providers,ai-graphql-naming,ai-postgres-parity,alternate-features,router,router-msrv), each on its own runner with its owntarget/.scripts/check-ai-provider-lanes.sh --list, so the lane set cannot drift from the script.validatefans in andjq-asserts every lane reportedsuccess, guarding against a futureif:silently skipping one.releasepublish steps are byte-identical to before..github/actions/reclaim-runner-diskreplaces the duplicatedsudo rm -rfblock.Every shell line of the previous
validatejob was diffed against the new workflow programmatically: three intended deltas (per-runner provider argument;router-msrvvia pinneddtolnay/rust-toolchaininstead ofcargo +1.90.0, equivalent since norust-toolchain.tomlexists; one duplicated rustdoc invocation run once). Nothing else dropped.Documentation impact
docs/operations/release/process.mdanddocs/development/testing.mdupdated to describe the new job shape.CHANGELOG.mdnot touched, matching precedent for workflow-only changes.python3 scripts/check-documentation.pypasses.Verification
actionlint(clean),shellcheckon the lanes script (clean), YAML parse of both workflows and the composite action, a scriptedneeds-graph check,scripts/check-package-release-policy.sh ce14eb08(passes; no crate sources touched).Not locally verifiable: GitHub Actions cannot run here. The first real
workflow_dispatchmust confirm the seven-leg matrix expands and passes without disk exhaustion, the environment prompts exactly once atguard, the local composite action resolves, and tag visibility inreleasematches the old single job.Review note
environment: releasesits onguardonly. This preserves approve-before-compile with a single prompt, but the deployment record attaches toguardrather than the publish job. Publish uses onlygithub.token+ OIDC, so nothing depends on environment secrets; moving the key is a one-line change if gating publication is preferred.🤖 Generated with Claude Code