feat: release workflow RC versioning and publish reliability#164
feat: release workflow RC versioning and publish reliability#164
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe release workflow's RC/versioning flow was rewritten to derive the base version from the package.json on the PR head branch (when present) instead of using git-describe. The job fetches PR details and PR head branch, reads and validates package.json version from that branch, and sets an RC like {next_version}-rc.{run_number}. RC creation is restricted to main. Build steps are hardened (set -euo pipefail, --allow-same-version), publish first checks npm for existing versions and skips if already published, and final publish uses provenance and explicit prerelease flags. Additional env vars expose RELEASE_CREATED, RELEASE_VERSION, and PR_HEAD_BRANCH. Sequence Diagram(s)sequenceDiagram
participant Runner as GitHub Actions Runner
participant GH as GitHub API
participant Git as Git Repository
participant NPM as npm Registry
Runner->>GH: Determine context (refs, PR info)
GH-->>Runner: PR details (including head branch) / repo refs
alt PR_HEAD_BRANCH present and not on main
Runner->>Git: fetch PR head branch
Git-->>Runner: package.json from PR branch
Runner->>Runner: validate NEXT_VERSION (semver)
Runner->>Runner: set VERSION = NEXT_VERSION-rc.{run_number}
else Not PR or main branch
Runner->>Git: read package.json from main
Git-->>Runner: base version
Runner->>Runner: compute VERSION (release or rc rules)
end
Runner->>Runner: Build (set -euo pipefail, npm version --allow-same-version)
Runner->>NPM: query for VERSION
alt VERSION exists on npm
NPM-->>Runner: version found
Runner->>Runner: skip publish
else VERSION not found
Runner->>NPM: npm publish --provenance (with prerelease if set)
NPM-->>Runner: publish result
end
Runner->>GH: create release (set RELEASE_CREATED, RELEASE_VERSION)
GH-->>Runner: release created/updated
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/release.yml:
- Around line 103-109: The publish guard currently swallows all errors by using
`2>/dev/null || true` when assigning EXISTING from `npm view`, so update the
`EXISTING=$(npm view "@supabase/ssr@${{ steps.version.outputs.version }}" ...)`
logic to capture the command exit status and stderr, detect a genuine "not
found" (404/Not Found) response versus other failures, and only treat 404 as
“version missing”; for other non-zero exits (auth/network/registry errors) print
the captured stderr and exit non-zero to fail the workflow immediately.
Concretely, run `npm view` and save its stdout/stderr and exit code, set
`EXISTING` from stdout when exit code is 0, if exit code != 0 check stderr for
404/Not Found (treat as empty EXISTING), otherwise echo the stderr for
diagnostics and exit 1 before reaching `npm publish --provenance --tag ${{
steps.version.outputs.tag }}`.
ℹ️ Review info
Configuration used: Central YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Cache: Disabled due to Reviews > Disable Cache setting
Disabled knowledge base sources:
- Linear integration is disabled
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
.github/workflows/release.yml
There was a problem hiding this comment.
♻️ Duplicate comments (1)
.github/workflows/release.yml (1)
116-122:⚠️ Potential issue | 🟠 MajorDo not swallow non-404
npm viewfailures in publish guard.
At Line 116,2>/dev/null || truecollapses auth/network/registry errors into the same path as “version not found”. That hides the real failure mode and can lead to a misleading publish failure later.Suggested fix
- EXISTING=$(npm view "@supabase/ssr@${{ steps.version.outputs.version }}" version 2>/dev/null || true) - if [ -n "$EXISTING" ]; then + PKG="@supabase/ssr@${{ steps.version.outputs.version }}" + ERR_FILE="$(mktemp)" + if EXISTING=$(npm view "$PKG" version 2>"$ERR_FILE"); then echo "Version ${{ steps.version.outputs.version }} already published on npm, skipping." exit 0 + elif grep -qE 'E404|404 Not Found' "$ERR_FILE"; then + : # not published yet; continue + else + echo "npm lookup failed for $PKG" >&2 + cat "$ERR_FILE" >&2 + exit 1 fi🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/release.yml around lines 116 - 122, The publish guard currently silences all errors by using `2>/dev/null || true` when running `npm view "@supabase/ssr@${{ steps.version.outputs.version }}" version`, which conflates “not found” with auth/network/registry failures; change the logic around the `npm view` call (the EXISTING check) to capture the command exit code and stderr separately, treat a successful (exit code 0) run as the version existing (set `EXISTING`), treat a 404/not-found error explicitly as “not existing” and continue, but for any other non-zero exit code (auth/network/registry errors) fail the workflow with a clear error message instead of proceeding to `npm publish`; update the step that defines `EXISTING` to implement this explicit error handling rather than swallowing stderr.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In @.github/workflows/release.yml:
- Around line 116-122: The publish guard currently silences all errors by using
`2>/dev/null || true` when running `npm view "@supabase/ssr@${{
steps.version.outputs.version }}" version`, which conflates “not found” with
auth/network/registry failures; change the logic around the `npm view` call (the
EXISTING check) to capture the command exit code and stderr separately, treat a
successful (exit code 0) run as the version existing (set `EXISTING`), treat a
404/not-found error explicitly as “not existing” and continue, but for any other
non-zero exit code (auth/network/registry errors) fail the workflow with a clear
error message instead of proceeding to `npm publish`; update the step that
defines `EXISTING` to implement this explicit error handling rather than
swallowing stderr.
ℹ️ Review info
Configuration used: Central YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Cache: Disabled due to Reviews > Disable Cache setting
Disabled knowledge base sources:
- Linear integration is disabled
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
.github/workflows/ci.yml.github/workflows/conventional-commits.yml.github/workflows/release.yml
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.github/workflows/release.yml (1)
133-142: Make RC pre-release creation idempotent for reruns.
gh release createfails when the tag/release already exists. Without idempotency, reruns of the workflow will fail at this step if the RC release was partially created in a prior attempt.♻️ Proposed refactor
- name: Create GitHub pre-release if: ${{ steps.version.outputs.tag == 'rc' }} env: GH_TOKEN: ${{ steps.generate-token.outputs.token }} run: | set -euo pipefail - gh release create "v${{ steps.version.outputs.version }}" \ - --title "v${{ steps.version.outputs.version }}" \ - --generate-notes \ - --prerelease + TAG="v${{ steps.version.outputs.version }}" + if gh release view "$TAG" >/dev/null 2>&1; then + echo "GitHub release $TAG already exists, skipping." + else + gh release create "$TAG" \ + --title "$TAG" \ + --generate-notes \ + --prerelease + fi🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/release.yml around lines 133 - 142, The Create GitHub pre-release step is not idempotent because gh release create fails if the tag/release already exists; change the step that currently runs gh release create "v${{ steps.version.outputs.version }}" to first check for an existing release (using gh release view "v${{ steps.version.outputs.version }}" or equivalent) and if it exists run gh release edit "v${{ steps.version.outputs.version }}" --title "v${{ steps.version.outputs.version }}" --generate-notes --prerelease, otherwise run gh release create as before; keep the step name ("Create GitHub pre-release"), the GH_TOKEN env and use steps.version.outputs.version to locate the release.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.github/workflows/release.yml:
- Around line 133-142: The Create GitHub pre-release step is not idempotent
because gh release create fails if the tag/release already exists; change the
step that currently runs gh release create "v${{ steps.version.outputs.version
}}" to first check for an existing release (using gh release view "v${{
steps.version.outputs.version }}" or equivalent) and if it exists run gh release
edit "v${{ steps.version.outputs.version }}" --title "v${{
steps.version.outputs.version }}" --generate-notes --prerelease, otherwise run
gh release create as before; keep the step name ("Create GitHub pre-release"),
the GH_TOKEN env and use steps.version.outputs.version to locate the release.
ℹ️ Review info
Configuration used: Central YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Cache: Disabled due to Reviews > Disable Cache setting
Disabled knowledge base sources:
- Linear integration is disabled
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
.github/workflows/ci.yml.github/workflows/conventional-commits.yml.github/workflows/release.yml
## [0.9.0](v0.8.1...v0.9.0) (2026-03-02) ### Features * release workflow RC versioning and publish reliability ([#164](#164)) ([81e68f4](81e68f4)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: supabase-releaser[bot] <223506987+supabase-releaser[bot]@users.noreply.github.com>
The release workflow had three issues:
npm versionfailed with "Version not changed" when release-please had already updatedpackage.jsonto the release version. Fixed by adding--allow-same-version.RC version always predicted a minor bump (e.g. 0.9.0-rc.N) regardless of whether the next release is a patch. Fixed by reading
package.jsondirectly from the release-please PR branch instead of parsing the PR title or guessing from git history. RC numbering now usesgithub.run_numberinstead ofgit describe(which was unreliable with no remote tags).Re-running a failed stable release workflow would error with "cannot publish over a previously published version". Fixed by checking npm before publishing and skipping if the version already exists.