Skip to content

Release readiness: what must happen to cut the first tag since v0.5.1220 #8342

Description

@proggeramlug

Goal

Cut the first Perry release since v0.5.1220. Cargo.toml is at 0.5.1512 — roughly 290 commits have landed untagged.

This ticket is self-contained: it states what the release gate mechanically requires, what is red today, what work closes the gap, and how to execute the release once green. No other context needed.


1. What "release-ready" mechanically means

release-packages.yml is dispatched with cut_release: true on a branch pinned at the release-candidate commit. Its await-tests job then:

  1. dispatches test.yml with tier=full on that ref, and
  2. waits for a run whose full-suite-gate job succeeded on that SHA, and
  3. waits for simctl-tests.yml.

Two consequences people keep tripping on:

  • A green PR-tier (pr-gate) or post-merge sweep (main-gate) run on the same SHA does NOT count. Only the full tier carries the release-grade suites.
  • Nothing in the full tier carries continue-on-error any more (ci: restructure CI into PR gate / main sweep / full suite tiers #8187). One red suite blocks the tag. There is no "publish past it" path short of consciously re-adding a job-level continue-on-error: true with an issue number.

Only after that does it tag vX.Y.Z from Cargo.toml, create the GitHub Release, and publish. Tag-LAST — the tag is an output of a green run, not an input.

The full tier

lint, check, warnings, cargo test --workspace, the gap suite (8-shard auto-optimize mode, not the PR tier's prebuilt fast mode), gc-stress, Windows x64 + ARM64, compiler-output-regression, repsel-census, harmonyos-smoke, security-audit, binary-size, parity, compile-smoke, doc-tests (macOS + Windows), the package smokes (drizzle-mysql-smoke, ink-link-smoke, effect-basic-smoke), native-abi-evidence-packet. Benchmark regressions hard-fail on release tags.

parity has its own contract: clear the threshold in test-parity/threshold.json (aggregate ≥ 83%) and add no new / stale known_failures.json entries. The second half is the binding one.


2. Where we actually are

The full tier had been effectively unmeasured for six weeks (tag-gated + continue-on-error before #8187; the one unsharded parity attempt died at GitHub's 6-hour job cap). Since it started reporting, every full-tier run has failed.

Latest nightly (7441e1f73, run 32099242562), still in flight, already red on:

Job Notes
warnings recurring — -D warnings, so any new lint is a build failure
cargo-test
gc-stress
compiler-output-regression
effect-basic-smoke
doc-tests (macos-14)

parity shards were still queued at the time of writing.

The dominant debt is #8271: the first complete parity run since 2026-07-04 found 93 new unlisted parity failures + 27 compile failures + 16 crashes, at 90.7% aggregate, against a then-9-entry known_failures.json. That file now has 123 entries, so a large share has been registered — #8271 is still open and is the single biggest item on this ticket.


3. Why this needs a merge freeze

This is the part that has repeatedly defeated a "just fix the list" approach, and it is measurable:

Therefore: pin a release-candidate branch off main and land only release-blocking fixes on it. Do not chase green on a moving main.


4. The work

A. Parity debt — #8271 (biggest, mostly triage not debugging)

Every remaining unlisted failure must either be fixed or registered in known_failures.json with an issue number (the provenance policy from #797), and the 3 stale entries removed. #8271 groups them into families, several of which look like one shared cause, so the number of distinct bugs is far below the failure count:

  • npm-package parity (~15: lodash / moment / dayjs / date-fns / uuid / nanoid / validator / commander / cron / dotenv / decimal / lru_cache / argon2) — "smells like one shared import/oracle change, worth bisecting as a family"
  • perry-tui / ink-compat (~15) — Compile ink (React-based TUI framework) end-to-end via perry.compilePackages #348's area
  • jwt/jose link family (js_jwt_sign_dyn)
  • Linux-gtk4 UI compile failures (~15) — fixtures never skip-listed for a host without the toolchain

Bisect each family before fixing individuals.

B. Recurring gate failures

warnings, cargo-test, gc-stress, compiler-output-regression, effect-basic-smoke, doc-tests (macos-14). These need per-run triage; each has been a different root cause across runs, so treat the job name as a symptom, not an issue.

C. Never-yet-green surfaces

simctl-tests.yml is a release gate and I have seen no evidence of a recent green run. binary-size and the benchmark hard-fail arm are also release-only paths. Verify these actually pass before assuming they do — a job that never ran is not a job that passes.


5. Execution, once the candidate is green

  1. Pin a release-candidate branch at the chosen commit.
  2. Land only blocker fixes on it; re-dispatch test.yml with tier=full on that ref after each.
  3. When full-suite-gate succeeds on that SHA and simctl-tests.yml is green, dispatch release-packages.yml with cut_release: true on that branch.
  4. It gates on tests, builds every leg, then creates the tag from Cargo.toml, the GitHub Release, and publishes. Changelog fragments in changelog.d/ fold into the release notes at tag time.

Do not push a tag by hand. The tag is the output of the gate.


Definition of done

Verification note

gh pr checks reports cancelled jobs as fail, and the fan-in job reports failure when its shards are cancelled. Several "red" gates during this effort were cancellations, not test failures. Always confirm a job's own conclusion before treating it as a blocker — and confirm a test actually ran (grep for a positive ... ok, not for the absence of FAILED); a cancelled run silently looks like a passing one.

Metadata

Metadata

Assignees

No one assigned

    Labels

    releaseRelease tracking issues

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions