ci: automate releases with release-please and npm trusted publishing - #1
Conversation
📝 WalkthroughWalkthroughThe change adds release-please metadata and a GitHub Actions release workflow. Releases run from ChangesRelease automation
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant GitHubActions
participant releasePlease
participant BuildTooling
participant npmRegistry
GitHubActions->>releasePlease: prepare release on main
releasePlease-->>GitHubActions: return release status and tag
GitHubActions->>BuildTooling: install tools, build package, run tests
BuildTooling-->>GitHubActions: return build and test results
GitHubActions->>npmRegistry: publish tagged package with OIDC
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
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: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/ci.yml:
- Around line 5-7: Add workflow-level concurrency configuration in the CI
workflow so runs for the same pull request share a group and newer commits
cancel superseded runs; preserve existing branch triggers and enable
cancellation of in-progress runs.
In @.github/workflows/release.yml:
- Around line 55-57: Update the checkout step using the actions/checkout
configuration to disable persisting the GitHub token in Git configuration by
setting persist-credentials to false, while preserving the existing tag ref.
- Around line 72-83: Pin the release toolchain versions in the Bun setup,
NODE_VERSION configuration, and npm installation command: replace bun-version
latest, the floating Node version 24, and npm@latest with exact reviewed
versions. Ensure all three versions are explicitly maintained in NODE_VERSION or
the npm install command so release behavior changes only through repository
updates.
- Line 85: Update the release workflow’s dependency installation step from plain
`bun install` to frozen-lockfile mode, using `bun ci` or `bun install
--frozen-lockfile`, so it fails when package.json and bun.lock are out of sync.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: c90978c5-95b7-4f7c-b108-1e3673f9ad32
📒 Files selected for processing (4)
.github/workflows/ci.yml.github/workflows/release.yml.release-please-manifest.jsonrelease-please-config.json
| - name: Ensure npm supports trusted publishing | ||
| run: npm install -g npm@latest | ||
|
|
||
| - run: bun install |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo "Committed Bun lockfiles:"
fd -HI -t f '^(bun\.lock|bun\.lockb)$' . -E .git -E node_modules || true
echo "Release install configuration:"
rg -n -C 2 'bun install|bun-version' .github/workflows/release.ymlRepository: oxidezap/whatsapp-rust-bridge
Length of output: 618
🌐 Web query:
Bun install locked dependency verification frozen-lockfile documentation
💡 Result:
The --frozen-lockfile flag in Bun is used to ensure reproducible installations by strictly enforcing that the project's dependencies match the existing lockfile [1][2]. Key behaviors and details: - Enforcement: When --frozen-lockfile is used, Bun installs the exact versions specified in the bun.lock file [1][3]. If the project's package.json file disagrees with the lockfile (e.g., due to added, removed, or modified dependencies), Bun will exit with an error [1][2][4]. - CI/CD Usage: The command bun ci is equivalent to running bun install --frozen-lockfile [1][2]. It is the recommended approach for continuous integration environments to ensure the installed environment exactly matches the committed lockfile [1]. - Prerequisites: For these commands to function, the bun.lock file must be committed to version control [1][2]. - Evolution and Fixes: Recent updates have improved the accuracy of the frozen-lockfile check [5][4]. Bun now correctly fails in edge cases where package.json changes (such as adding a direct dependency that was previously only a transitive one) might have previously allowed the installation to proceed [4]. In summary, --frozen-lockfile acts as a guardrail against dependency drift, ensuring that the dependency tree remains immutable during installation unless the lockfile is explicitly updated [1][4].
Citations:
- 1: https://bun.sh/docs/pm/cli/install
- 2: https://bun.com/docs/pm/cli/install
- 3: https://github.com/oven-sh/bun/blob/main/docs/pm/cli/install.mdx
- 4: install: fail --frozen-lockfile on manifest drift and fix the spurious lockfile re-saves behind it oven-sh/bun#33632
- 5: bun install --frozen-lockfile does not exit with error when it should oven-sh/bun#13823
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo "Workflow install context:"
sed -n '68,92p' .github/workflows/release.yml | cat -n -v
echo "Other bun install usages:"
rg -n -C 1 '\bbun (ci|install)( --frozen-lockfile)?\b|frozen-lockfile' .github . --glob '!node_modules/**' || trueRepository: oxidezap/whatsapp-rust-bridge
Length of output: 1644
Enable frozen lockfile mode for the release install.
The release workflow has bun.lock, but .github/workflows/release.yml:85 runs plain bun install. Use bun ci or bun install --frozen-lockfile so the build fails when package.json and bun.lock are out of sync instead of resolving a new dependency graph before publishing.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml at line 85, Update the release workflow’s
dependency installation step from plain `bun install` to frozen-lockfile mode,
using `bun ci` or `bun install --frozen-lockfile`, so it fails when package.json
and bun.lock are out of sync.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: aa038d5174
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @@ -0,0 +1,3 @@ | |||
| { | |||
| ".": "0.6.0" | |||
There was a problem hiding this comment.
Set a commit baseline for the first automated release
Because the repository has no v0.6.0 release tag for the manual release at c78ad1d—only older prerelease tags—setting the manifest version alone does not tell release-please where the 0.6.0 history ends. On its first run, it can therefore traverse older commits and immediately propose a version bump and changelog containing work already shipped in 0.6.0. Add bootstrap-sha: c78ad1dbdac07ff8f5ac2c1504c6e83752cf8ea3 (documented as the starting point for commit history) or create the matching release tag before enabling this workflow.
Useful? React with 👍 / 👎.
aa038d5 to
3212020
Compare
|
Applied the review findings. Pinned npm (
Not applied: the PAT for release PR checks. GitHub does suppress workflow triggers for Worth noting this PR still shows no CI: |
9fd6577 to
4a7b5dc
Compare
|
Second round applied.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4a7b5dcc0f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| - id: release | ||
| uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0 | ||
| with: | ||
| token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }} |
There was a problem hiding this comment.
Do not fall back to GITHUB_TOKEN for the release PR
When RELEASE_APP_CLIENT_ID is unset and main requires the CI check, this fallback creates the release PR with GITHUB_TOKEN, but the resulting pull_request event cannot start .github/workflows/ci.yml. GitHub documents that events triggered by GITHUB_TOKEN do not create new workflow runs except for workflow_dispatch and repository_dispatch (GitHub Actions documentation); consequently, there is no approval-pending run to click and the release PR remains blocked. Require the App credentials or use another credential capable of triggering the required checks.
Useful? React with 👍 / 👎.
|
|
||
| # No NODE_AUTH_TOKEN and no --provenance: trusted publishing authenticates | ||
| # over OIDC and attaches provenance on its own. | ||
| - run: npm publish --ignore-scripts |
There was a problem hiding this comment.
Run the tarball guard before publishing
When a build change accidentally adds pkg/ content or duplicate large files to the tarball, --ignore-scripts suppresses package lifecycle scripts (npm configuration documentation), so the existing prepack command and its scripts/check-pack.ts publish guard never run. A normal manual npm publish previously executed that guard, whereas this workflow can now publish the malformed package; explicitly invoke the check after the build or allow the relevant lifecycle script to run.
Useful? React with 👍 / 👎.
4a7b5dc to
6577538
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
|
Third round. The check-pack finding was a real bug I introduced — appliedRight, and specific: I had added the equivalent explicit call in the sibling PR and missed it here. Now invoked directly after the build, before publish. Verified it runs standalone: Also applied
Not appliedThe |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 65775385e6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| branches: [main] | ||
| pull_request: | ||
| branches: [master] | ||
| branches: [main] |
There was a problem hiding this comment.
Restore the benchmark inputs before enabling main CI
For every PR against main, this newly enabled workflow reaches the existing Run Benchmarks with Node.js 24 step, whose bench:node script invokes benches/binary.ts, signal.ts, curve.ts, and crypto.ts; a repo-wide file search finds no benches/ directory or generated equivalents, and node --expose-gc benches/binary.ts exits with MODULE_NOT_FOUND. Consequently, every otherwise-successful CI run fails at the benchmark step, so restore or remove these benchmark targets before switching the trigger.
AGENTS.md reference: AGENTS.md:L7-L9
Useful? React with 👍 / 👎.
Version bumps and publishes were manual, and dist/ is gitignored while being the only thing `files` ships — so the published tarball was whatever a maintainer's disk happened to hold. The publish job now builds the wasm package from source on a GitHub runner and ships that. release-please keeps a release PR up to date from the conventional commits already in use here. Merging it tags the release, and only that tag triggers a publish, so the bump stays reviewable rather than firing on every merge to main. The publish job authenticates over OIDC instead of a stored token, which npm has offered as trusted publishing since it went GA. Provenance attestations come along automatically, so no --provenance flag. Actions are pinned to commit SHAs because this workflow is the publish path. CI also still triggered on master, which stopped being the default branch when the repository moved to the oxidezap org, so no workflow ran for a pull request against main.
|
Applied — and this one was the most valuable finding of the whole PR, because it is a failure this PR itself would have introduced. Verified: Removed the benchmark step and renamed the job to match, with a comment recording why. Not touching |
6577538 to
647018d
Compare
The round trip compared bytes fields by length, and every bytes sample was empty, so a codec that kept the tag and replaced the payload passed. Each field now runs a second sample carrying a value the schema cannot supply by accident, and bytes are compared element by element. Reverting the comparison and writing a same-length payload from a bytes encoder produces: ADVSignedDeviceIdentity.details (#1): wrote {1,127,255}, read back {0,0,0}. The empty sample stays: it is what proves explicit presence.
Releases here are manual today, and
dist/is gitignored while being the only thingfilesships — so the published tarball is whatever the maintainer's disk happened to hold at publish time. The publish job now builds the wasm package from source on a GitHub runner and ships that.How it works
release-pleasekeeps a release PR up to date from the conventional commits already used in this repo. Merging that PR tags the release, and only that tag triggers a publish — the version bump stays reviewable instead of firing on every merge tomain.The publish job authenticates to npm over OIDC (trusted publishing) rather than a stored token. Provenance attestations are attached automatically, so no
--provenanceflag and noNODE_AUTH_TOKENanywhere.Also fixes: CI was not running
CI still triggered on
master, which stopped being the default branch when the repository moved to the oxidezap org. No workflow runs for a pull request againstmain— including this one until it lands. Retargeted tomain.Choices worth flagging
ci.ymlstill usesdtolnay/rust-toolchain@master, a moving branch ref; left alone here to keep this PR to the release path.npm-publishenvironment — already created on the repo. Add required reviewers there to gate releases; the same name scopes the OIDC trust on npm.wasm-opttook ~4 min locally, and a cold Rust cache on a runner is slower.Required before this can publish
One-time trusted publisher setup on npmjs.com for
@oxidezap/whatsapp-rust-bridge, naming this repository,release.yml, and thenpm-publishenvironment. Until that exists the publish step fails — nothing else in CI is affected.The manifest pins
0.6.0, matching what is onmainand on npm. The three oldv1.0.0-alpha.*tags predate the current line and are ignored, since the manifest is the source of truth.Summary by cubic
Automates releases with
release-pleaseandnpmtrusted publishing; builds the wasm package on GitHub runners for consistent tarballs. CI now runs onmainand cancels superseded runs.New Features
release-pleasekeeps a release PR; only the merged tag publishes. Optional GitHub App token avoids “Approve and run”; falls back toGITHUB_TOKEN.npmvia OIDC with provenance; noNODE_AUTH_TOKEN.wasm-pack,bun); publish rebuildsdist/with pinnednpm@11.19.0.feat/fix/perfcommits release; usefix(deps)for dependency bumps.Migration
npmfor@oxidezap/whatsapp-rust-bridgewith this repo,release.yml, and thenpm-publishenvironment.Written for commit 647018d. Summary will update on new commits.