Files
pnpm/.github/workflows/release.yml
Zoltan Kochan dd79bdc08e ci: require release workflow to run on tags (#12613)
The Release workflow allowed workflow_dispatch from branch refs but only built `@pnpm/exe` artifacts on tag refs. A branch dispatch on main after the 11.9.0 release bump selected the platform artifact packages in the internal publish step, then failed in their prepublishOnly binary verification because the binaries had not been built.

Add a preflight job that accepts only refs/tags/v*.*.*. The real release job depends on that preflight, so non-tag dispatches fail before entering the protected release environment or configuring npm auth.

With non-tag refs rejected up front, the release job can run the full tag release path without per-step tag guards.
2026-06-23 23:20:03 +02:00

99 lines
4.7 KiB
YAML

name: Release
on:
push:
tags:
- "v*.*.*"
# Manual trigger for rerunning a tag release. Dispatching this workflow from a
# branch fails before publishing because release artifacts are only built on
# version tags.
workflow_dispatch:
jobs:
validate-release-ref:
runs-on: ubuntu-latest
permissions: {}
steps:
- name: Validate release ref
run: |
case "${GITHUB_REF}" in
refs/tags/v*.*.*) ;;
*)
echo "::error::The release workflow must run from a version tag like v11.9.0. Current ref: ${GITHUB_REF}"
exit 1
;;
esac
release:
needs: validate-release-ref
permissions:
id-token: write # Required for OIDC
contents: write # for softprops/action-gh-release to create GitHub release
attestations: write # for actions/attest-build-provenance
# Runs on macOS so the darwin artifacts can be ad-hoc signed with native
# `codesign` (no need to build/install `ldid` on the runner) and so
# `verify-binary.mjs` can smoke-test the darwin-arm64 SEA in place — a
# macos-latest runner is Apple Silicon and can execute the arm64 binary.
# Note: this does NOT fix the darwin-x64 crash (nodejs/node#62893) — that's
# an upstream Node.js SEA bug independent of signing; see pack-app docs.
runs-on: macos-latest
environment: release
steps:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- uses: garnet-org/action@2b7fc9d79b54f551b43358c27424a36064b3e078 # v2
with:
api_token: ${{ secrets.GARNET_API_TOKEN }}
- name: Install pnpm and Node
uses: pnpm/setup@b1cac37306e39c21283b9dd6cb0ac288fb35ba6b
with:
runtime: node@26.3.1
# The publish phase is split into three sequential steps to control which packages
# use trusted publishing (OIDC) vs. a static token. `pnpm publish` currently bails
# out of OIDC as soon as a static `_authToken` is configured, so the only way to
# force trusted publishing for a given package today is to run its publish in a
# step that doesn't have NPM_TOKEN set. See https://github.com/pnpm/pnpm/pull/11495
# for the longer-term fix that lets OIDC override a configured token.
- name: Publish @pnpm/exe (trusted publishing)
# No NPM_TOKEN: pnpm has no static token to short-circuit on, so it will perform
# the OIDC token exchange against npm's trusted-publishing config for `@pnpm/exe`.
# The exe artifacts must be built before the publish, so they're built here too.
run: |
pn --filter=@pnpm/exe run build-artifacts
pn --filter=@pnpm/exe publish --tag=next-11 --access=public --provenance
- name: Publish internal workspace packages (static token)
# The other workspace packages don't have trusted publishing configured on npm,
# so we still need a static token here. The token is removed from pnpm's config
# at the end of the step so it can't leak into the trusted-publishing step that
# follows (where its presence would silently downgrade `pnpm` to token publishing).
env:
# Setting the "npm_config_//registry.npmjs.org/:_authToken" env variable directly
# doesn't work — pnpm doesn't appear to pass auth tokens to child processes.
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
trap 'pn config delete "//registry.npmjs.org/:_authToken" || true' EXIT
pn config set "//registry.npmjs.org/:_authToken" "${NPM_TOKEN}"
pn publish --filter=!pnpm --filter=!@pnpm/exe --access=public --provenance
- name: Publish pnpm CLI (trusted publishing)
# No NPM_TOKEN — same rationale as the @pnpm/exe step above. This must come after
# the previous step has cleared its NPM_TOKEN from pnpm's config.
run: pn publish --filter=pnpm --tag=next-11 --access=public --provenance
- name: Copy Artifacts
run: pn copy-artifacts
- name: Attest build provenance
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
with:
subject-path: 'dist/*'
- name: Generate release description
run: pn make-release-description
- name: Release
# `gh release create` could replace this, but the release pipeline is
# sensitive and softprops/action-gh-release is widely battle-tested.
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0 # zizmor: ignore[superfluous-actions]
with:
draft: true
files: dist/*
body_path: RELEASE.md