ci: enable manual releases for pacquet and pnpm#11652
Conversation
Two related workflow changes:
**`pacquet-release-to-npm.yml`** — switch the trigger from "push to main
touching pacquet/npm/pacquet/package.json" to `workflow_dispatch` only.
The dispatch takes a `version` input (validated as semver) and patches
`pacquet/npm/pacquet/package.json` before `generate-packages.mjs` runs,
so the version is single-sourced from the manual trigger rather than
needing a separate commit to bump the manifest first. The committed
manifest now omits the `version` field entirely — it only exists at
release time inside the runner.
Dropped along the way:
- The `check` job (EndBug/version-check against unpkg) — no longer
needed when the operator types the version.
- The `Create GitHub Release` step (no draft release, no `v*.*.*`
git tag). The pacquet `v0.x.x` tag scheme collided with pnpm's
`v11.x.x`; npm is the authoritative artifact store and provenance
attestations stay attached via `--provenance` on `pnpm publish`.
- `contents: write` on the publish job (no longer creates a tag).
**`release.yml`** — add `workflow_dispatch:` alongside the existing
tag-push trigger. Lets a maintainer publish whatever versions are
currently in each `package.json` on the selected ref without first
cutting a tag. npm rejects any version already on the registry, so
re-running on an already-released tree is a no-op.
📝 WalkthroughWalkthroughRelease workflows now support manual ChangesManual npm release workflow with version dispatch
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/release.yml:
- Around line 7-12: The workflow currently allows manual dispatch via
workflow_dispatch which causes softprops/action-gh-release@v2.5.0 to pick up
github.ref_name (e.g., "main") and create a release for a branch; restrict
release creation to tag-triggered runs by removing or keeping workflow_dispatch
but adding a guard on the release job (e.g., add if: startsWith(github.ref,
'refs/tags/') or if: github.event_name == 'release' as appropriate) and ensure
the softprops/action-gh-release step uses tag_name: ${{ github.ref_name }} only
when that guard passes; update the release job condition and the
softprops/action-gh-release invocation accordingly.
🪄 Autofix (Beta)
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: CHILL
Plan: Pro Plus
Run ID: 5bb8f60c-519e-4480-8162-96816a4f0c34
📒 Files selected for processing (3)
.github/workflows/pacquet-release-to-npm.yml.github/workflows/release.ymlpacquet/npm/pacquet/package.json
💤 Files with no reviewable changes (1)
- pacquet/npm/pacquet/package.json
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Lint and Test (ubuntu-latest)
- GitHub Check: Lint and Test (macos-latest)
- GitHub Check: Lint and Test (windows-latest)
- GitHub Check: Compile & Lint
🔇 Additional comments (1)
.github/workflows/pacquet-release-to-npm.yml (1)
3-13: LGTM!Also applies to: 17-17, 123-143
Without an explicit `tag_name`, softprops/action-gh-release@v2.5.0 defaults to `github.ref_name` — `v11.x.x` on a tag push, but literally `main` on a workflow_dispatch from main. That would create a junk GitHub release tied to the branch ref. Gate the four GitHub-release-side steps (Copy Artifacts, Attest build provenance for dist/*, Generate release description, the Release action itself) on `startsWith(github.ref, 'refs/tags/')`. The three pnpm-publish steps above keep running on both triggers — npm is the authoritative artifact path; the npm-side provenance comes from `pnpm publish --provenance` and is unaffected.
Manual dispatch is for republishing internal workspace packages (libs) without cutting a full pnpm release. The CLI bundle, the @pnpm/exe wrapper, and the multi-minute exe build-artifacts step are all tied to a versioned tag — skip them on the tagless path. Now on workflow_dispatch, the release workflow runs exactly one publish step: the internal workspace packages (static token). The two trusted-publishing steps and the build-artifacts step require `startsWith(github.ref, 'refs/tags/')`.
Two related workflow changes: ### `pacquet-release-to-npm.yml`: switch to `workflow_dispatch` The trigger was "push to main touching `pacquet/npm/pacquet/package.json`" — the version came from a committed bump and the workflow auto-fired on every such commit. Switch to `workflow_dispatch` only, with a `version` input (validated as semver). The workflow patches `pacquet/npm/pacquet/package.json` before `generate-packages.mjs` runs, so the version is single-sourced from the manual trigger rather than needing a separate commit to bump the manifest first. The committed manifest now omits the `version` field entirely — it only exists at release time inside the runner. Dropped along the way: - The `check` job (EndBug/version-check against unpkg) — no longer needed when the operator types the version. - The `Create GitHub Release` step — no draft release, no `v*.*.*` git tag. The pacquet `v0.x.x` tag scheme collided with pnpm's `v11.x.x`; npm is the authoritative artifact store and provenance attestations stay attached via `--provenance` on `pnpm publish`. - `contents: write` on the publish job (no longer needs to create a tag). ### `release.yml`: add `workflow_dispatch` as a lib-only republish path Add a `workflow_dispatch:` trigger alongside the existing tag-push trigger. Tag-push behaves exactly as before. Manual dispatch becomes a fast **lib-only republish** path — useful after a version bump to one or more lib packages that doesn't warrant a full CLI release. On `workflow_dispatch` from any ref, the following are skipped (guarded with `if: startsWith(github.ref, 'refs/tags/')`): - `Publish @pnpm/exe` step — also contains the multi-minute `build-artifacts` call. - `Publish pnpm CLI` step. - `Copy Artifacts`, `Attest build provenance` (the `dist/*` attestation), `Generate release description`, `Release` (`softprops/action-gh-release`) — these are the GitHub-Release-side ceremony. Without an explicit `tag_name`, `softprops/action-gh-release@v2.5.0` defaults to `github.ref_name`, which on a manual dispatch from main would create a junk release tagged literally `main`. What still runs on `workflow_dispatch`: - `actions/checkout`, garnet scan, `pnpm/setup` - `Publish internal workspace packages (static token)` — i.e. `pn publish --filter=!pnpm --filter=!@pnpm/exe --access=public --provenance` Compilation is handled by each lib package's own `prepublishOnly: tsgo --build` hook (which `pnpm publish` runs automatically), same as the existing tag-push flow. The npm registry rejects any version already on it, so re-running on an already-released tree is a no-op — that's the safety net for accidental clicks. ## How to use **pacquet release**: Actions → Release Pacquet → Run workflow → fill in `version` (e.g. `0.2.3` or `0.2.3-rc.1`) → Run. No tag, no GitHub release. **pnpm full release**: still triggered by a `v*.*.*` tag push. Publishes @pnpm/exe + libs + CLI, attests, copies artifacts, creates a draft GitHub release. **pnpm lib-only republish**: Actions → Release → Run workflow → choose `main` → Run. Publishes just the internal workspace packages from whatever versions are currently in each `package.json`. Skips CLI, @pnpm/exe, build-artifacts, GitHub release.
Summary
Two related workflow changes:
pacquet-release-to-npm.yml: switch toworkflow_dispatchThe trigger was "push to main touching
pacquet/npm/pacquet/package.json" — the version came from a committed bump and the workflow auto-fired on every such commit. Switch toworkflow_dispatchonly, with aversioninput (validated as semver). The workflow patchespacquet/npm/pacquet/package.jsonbeforegenerate-packages.mjsruns, so the version is single-sourced from the manual trigger rather than needing a separate commit to bump the manifest first.The committed manifest now omits the
versionfield entirely — it only exists at release time inside the runner.Dropped along the way:
checkjob (EndBug/version-check against unpkg) — no longer needed when the operator types the version.Create GitHub Releasestep — no draft release, nov*.*.*git tag. The pacquetv0.x.xtag scheme collided with pnpm'sv11.x.x; npm is the authoritative artifact store and provenance attestations stay attached via--provenanceonpnpm publish.contents: writeon the publish job (no longer needs to create a tag).release.yml: addworkflow_dispatchas a lib-only republish pathAdd a
workflow_dispatch:trigger alongside the existing tag-push trigger. Tag-push behaves exactly as before. Manual dispatch becomes a fast lib-only republish path — useful after a version bump to one or more lib packages that doesn't warrant a full CLI release.On
workflow_dispatchfrom any ref, the following are skipped (guarded withif: startsWith(github.ref, 'refs/tags/')):Publish @pnpm/exestep — also contains the multi-minutebuild-artifactscall.Publish pnpm CLIstep.Copy Artifacts,Attest build provenance(thedist/*attestation),Generate release description,Release(softprops/action-gh-release) — these are the GitHub-Release-side ceremony. Without an explicittag_name,softprops/action-gh-release@v2.5.0defaults togithub.ref_name, which on a manual dispatch from main would create a junk release tagged literallymain.What still runs on
workflow_dispatch:actions/checkout, garnet scan,pnpm/setupPublish internal workspace packages (static token)— i.e.pn publish --filter=!pnpm --filter=!@pnpm/exe --access=public --provenanceCompilation is handled by each lib package's own
prepublishOnly: tsgo --buildhook (whichpnpm publishruns automatically), same as the existing tag-push flow.The npm registry rejects any version already on it, so re-running on an already-released tree is a no-op — that's the safety net for accidental clicks.
How to use
pacquet release: Actions → Release Pacquet → Run workflow → fill in
version(e.g.0.2.3or0.2.3-rc.1) → Run. No tag, no GitHub release.pnpm full release: still triggered by a
v*.*.*tag push. Publishes @pnpm/exe + libs + CLI, attests, copies artifacts, creates a draft GitHub release.pnpm lib-only republish: Actions → Release → Run workflow → choose
main→ Run. Publishes just the internal workspace packages from whatever versions are currently in eachpackage.json. Skips CLI, @pnpm/exe, build-artifacts, GitHub release.Test plan
version: 0.0.0-test(or similar) and inspecting the build matrix + publish-step preview before letting the OIDC step run. The semver validator should also reject obviously bad input (e.g.not-a-version).Releaseworkflow on main, confirm @pnpm/exe / pnpm CLI / GitHub-Release steps all show as skipped in the Actions UI, and only the internal-packages publish runs.v11.x.ytag push should run exactly as before — the newif:guards evaluate true on tag refs.Written by an agent (Claude Code, claude-opus-4-7).