Skip to content

ci: split release validation into a job matrix - #13

Merged
first-assist merged 1 commit into
mainfrom
agent/ci-release-matrix
Aug 20, 2026
Merged

ci: split release validation into a job matrix#13
first-assist merged 1 commit into
mainfrom
agent/ci-release-matrix

Conversation

@first-assist

@first-assist first-assist commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

Restructures .github/workflows/release.yml so its validation runs as a job matrix mirroring ci.yml, instead of one serial validate job that relinked every AI provider feature combination into a single target/ and exhausted the runner disk (the structural fix deliberately left open after ce14eb0's debug-info mitigations).

  • guard proves source identity and carries the release environment approval, so a human still approves before anything compiles and exactly once per run.
  • Eleven parallel lanes (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 own target/.
  • The AI provider matrix is derived at run time from scripts/check-ai-provider-lanes.sh --list, so the lane set cannot drift from the script.
  • validate fans in and jq-asserts every lane reported success, guarding against a future if: silently skipping one.
  • release publish steps are byte-identical to before.
  • New composite action .github/actions/reclaim-runner-disk replaces the duplicated sudo rm -rf block.

Every shell line of the previous validate job was diffed against the new workflow programmatically: three intended deltas (per-runner provider argument; router-msrv via pinned dtolnay/rust-toolchain instead of cargo +1.90.0, equivalent since no rust-toolchain.toml exists; one duplicated rustdoc invocation run once). Nothing else dropped.

Documentation impact

  • Documentation updated
  • No documentation impact

docs/operations/release/process.md and docs/development/testing.md updated to describe the new job shape. CHANGELOG.md not touched, matching precedent for workflow-only changes. python3 scripts/check-documentation.py passes.

Verification

actionlint (clean), shellcheck on the lanes script (clean), YAML parse of both workflows and the composite action, a scripted needs-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_dispatch must confirm the seven-leg matrix expands and passes without disk exhaustion, the environment prompts exactly once at guard, the local composite action resolves, and tag visibility in release matches the old single job.

Review note

environment: release sits on guard only. This preserves approve-before-compile with a single prompt, but the deployment record attaches to guard rather than the publish job. Publish uses only github.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

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>
@first-assist first-assist reopened this Aug 20, 2026
@first-assist
first-assist merged commit b746903 into main Aug 20, 2026
32 of 36 checks passed
@first-assist
first-assist deleted the agent/ci-release-matrix branch August 20, 2026 23:52
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