Repository navigation
ci(release): fix recurring release failures since the v3 cut (CLI-2913) - #7465
Conversation
- Skip next's test and release when next has no commits beyond develop, since semantic-release cannot tell a next tag from a beta tag on the same commit (semantic-release#4073); refuse such a next dispatch. - Rebuild the backfill's channel notes per commit from this channel's tags, and floor its release type at the tag's own version so forced maintenance versions get notes. - Pin setup-cli v3.2.0 in the smoke test, wait per runner for npm to serve the version and platform package, and assert the npm install path; add a forced GitHub-release fallback job. - Raise the platform-package wait to 30 minutes. - Make develop/next plans wait for main's in-flight publish job. - Drop the issues permission propose-release-notes cannot get. Closes CLI-2913, CLI-2914, CLI-2915, CLI-2916, CLI-2917
CLI benchmark (Lightweight Commands): no changes foundCommit
API calls: unchanged for all 7 commands. Binary size: 134.0 MB, unchanged. Details: timing ranges, API calls per command, slowest phasesTiming ranges
API calls per command
Slowest phasesNo command moved beyond noise, so there are no phase deltas. Comment |
There was a problem hiding this comment.
Superseded by a newer AI review
🤖 AI Review
Verified all five findings against the checked-out code and trusted conventions: four confirmed and one refuted. No findings overlap. Focused checks reproduced the prerelease comparison errors and polling-budget overrun; workflow sequencing was verified statically.
Findings
| Severity | Location | Category | Sources | Claim |
|---|---|---|---|---|
| 🟠 MAJOR | .github/workflows/release.yml:95 |
release-sequencing |
codex | The cached ahead check allows a next release to proceed after a major cut has advanced develop to the candidate commit. |
| 🟡 MINOR | .github/workflows/release.yml:130 |
reliability |
claude | The 60-minute stable-release wait can expire while main's release is progressing within its allowed timeouts, failing the prerelease plan and requiring a manual rerun. |
| 🟡 MINOR | .github/scripts/wait-for-npm-version.sh:19 |
timeout-handling |
codex | An npm probe can exceed the script's default 15-minute polling budget and potentially exhaust the smoke job's timeout. |
| 🟡 MINOR | apps/cli/scripts/release-channels.ts:69 |
correctness |
codex | releaseTypeBetween returns patch for prerelease downgrades, contrary to its documented requirement to return null when the target version is not later. |
Refuted findings (kept for transparency, not posted as review comments)
apps/cli/scripts/backfill-release-notes.e2e.test.ts:112(style): The Bun executable guard throws a plain Error inside Effect.gen instead of following the repository's claimed requirement to use an explicit Effect failure or defect.
Refuted: The trusted Effect guidance requires tagged errors for expected typed failures, but does not require every test prerequisite failure to be typed. Trusted tests already use this identical guard. A throw inside Effect.gen becomes a defect, as the suggested Effect.die would; no distinct failure-handling problem was identified.
Stats
Claude findings: 2 · Codex findings: 3 · Confirmed: 4 · Refuted: 1 · Uncertain: 0
Models: claude-opus-5-5 + gpt-6.1-sol · Trigger: auto · Workflow run
This review runs once per PR. A maintainer can request another with a /ai-review comment.
- Re-check that next is ahead of develop after the tests and the stable wait, so a major cut in between cannot tag a shared commit. - Wait up to 120 minutes for main's publish job. - Bound each npm probe and stop probing once the budget is spent. - Return no release type for equal or earlier prerelease versions.
|
/ai-review |
There was a problem hiding this comment.
🤖 AI Review
Reviewed all four findings against the surrounding code and trusted conventions. Confirmed two minor issues: failed GitHub API polls abort release planning, and interrupted tests leave subprocesses running. The 2.x package-compatibility claim remains uncertain without published package history; the PR-description mismatch remains uncertain because the description was not supplied. No findings overlap.
Findings
| Severity | Location | Category | Sources | Claim |
|---|---|---|---|---|
| 🟡 MINOR | .github/workflows/setup-cli-smoke-test.yml:71 |
ci-robustness |
claude | The unconditional platform-package wait would make manual smoke tests of 2.x versions without @supabase/cli-* packages time out, and could affect backports to v2.x. |
| 🟡 MINOR | .github/workflows/release.yml:132 |
error-handling |
claude | A failed GitHub API poll immediately aborts the stable-release wait and fails release planning instead of retrying within its 120-minute budget. |
| 🟡 MINOR | apps/cli/scripts/backfill-release-notes.e2e.test.ts:27 |
resource-cleanup |
codex | The new subprocess helper leaves its child running when the test effect is interrupted, including on timeout. |
| ⚪ NIT | .github/workflows/release.yml:130 |
documentation |
claude | The PR description reportedly promises a 60-minute stable-release wait, while the implementation and release documentation specify 120 minutes. |
Stats
Claude findings: 3 · Codex findings: 1 · Confirmed: 2 · Refuted: 0 · Uncertain: 2
Models: claude-opus-5-5 + gpt-6.1-sol · Trigger: manual · Workflow run
This review runs once per PR. A maintainer can request another with a /ai-review comment.
…2.x (#7507) Cherry-picks #7467 and #7465 onto `v2.x`, as the maintenance line needs both before its next release. - **#7467:** attests every GitHub Release asset with build provenance. `attestations: write` is granted to the `publish` job and to the `release.yml` and `release-smoke-test.yml` callers. The smoke test conflicted, so the permission goes in its top-level block. - **#7465:** the platform-package wait polls for up to 30 minutes with a 60-minute `publish` job timeout. `backfill-release-notes` drops other channels' prerelease tags, rebuilds one channel note per tagged commit from tag names, and forces the release type implied by the tag's own version so a forced maintenance version still gets notes. `v2.x`'s script is plain async, so those changes are ported by hand rather than merged. Left out of #7465 because `v2.x` has no `next` channel and its `release.yml` only runs as a maintenance dispatch: the `next-ahead` gate, the in-flight stable release wait, the setup-cli v3 smoke test changes (`v2.x` covers v1 and v2 only, so `wait-for-npm-version.sh` would be unused) and the matching docs. `propose-release-notes.yml` already requests no `issues: read`, so there is nothing to remove. --------- Co-authored-by: Julien Goux <hi@jgoux.dev>
Most
Releaseruns since the v3 cut have failed, and thenextchannel has quietly stopped releasing. There are four separate causes, plus two smaller release-notes failures.nextanddeveloptag the same commits. Between majorsnexthas no commits of its own, so the sync fast-forwards it ontodevelopand every fix or feature releases on both channels from one SHA. semantic-release reads channel notes per commit and gives every tag on a commit the first note (semantic-release#4073), sov3.1.0-next.1reads as a beta release. Everynextrun since has recomputed 3.1.0-next.1, published nothing and gone green. The same shared commits break beta's release-notes backfill: its note seeding looked for notes on the annotated tag object (which never has one), force-wrote a note for every tag, and on a shared commit thenextnote won, so backfillingv3.1.0-beta.2computedv3.1.0-beta.1.next-aheadjob comparesnextwithdevelop. Anextpush with no commits beyonddevelopskipsTest nextand the release, and achannel=nextdispatch in that state is refused up front. The plan checks again after the tests and the stable-release wait, so a major cut landing in between can't makenexttag a commitdevelopalso tags. Once a breaking change lands,nextreleases from its own commits again. Until thensupabase@nextstays on 3.1.0-next.1 andsupabase@betacarries the newest code.The setup-cli v3 smoke test races npm. setup-cli v3 installs through npm. npm lists a new version a few minutes after publish, and the registry CDN then caches each packument for five minutes, separately per region and per
Acceptheader. One run failed with a 404 several seconds after npm had already recorded the publish. A single wait job on one runner can't cover the macOS, Windows and Alpine runners, so:.github/scripts/wait-for-npm-version.sh, which pollsnpm viewand the abbreviated packument from that runner for bothsupabaseand the runner's platform package, for up to 15 minutes.install-sourceisnpm. One extra ubuntu job forces the fallback and checks it still works.The platform-package wait is too short.
publish.tswaits for every platform package to become installable before publishing the umbrella. That has taken anywhere from 6 to more than 15 minutes, and two releases timed out at the 15-minute limit. The ceiling is now 30 minutes and thepublishjob timeout 60. It's a poll, so a quick npm costs nothing extra.A beta planned during a stable release misses the stable tag.
mainpushes its tag only after the npm publish, so adeveloppush in that window computed a stale beta version (3.0.0-beta.18was planned while 3.0.0 was publishing). Thedevelopandnextplans now wait, for up to 120 minutes, until thepublishjob of any in-flightReleaserun onmainhas finished. A shared concurrency group would have let a pendingdeveloprun cancel a pendingmainrelease.A forced maintenance version gets no release notes. The 2.122.1 maintenance release was dispatched with an explicit
version, and its only commits wereci:commits, so the backfill's semantic-release dry run computed no release and left the GitHub release body empty. The backfill now gives semantic-release an extra commit analyzer that returns the release type implied by the tag's own version, so commit analysis still wins when it computes more and a forced version still gets its notes.Proposing release notes fails to mint a token.
propose-release-notes.ymlasked for anissues: readpermission the releaser app doesn't have, so token creation returned 422. The request is dropped; the notes agent reads public issues without it.This supersedes #7439. These are release-infra paths, so
v2.xneeds the setup-cli, platform-wait, backfill and propose-release-notes changes before its next maintenance release;v2.xhas nonextchannel, so thenext-aheadgate doesn't apply there.Closes CLI-2913, CLI-2914, CLI-2915, CLI-2916, CLI-2917
🤖 Generated with Claude Code