diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7cd1cf4..9ac3f36 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -42,8 +42,43 @@ jobs: registry-url: https://registry.npmjs.org/ cache: npm + # OIDC trusted publishing needs npm >= 11.5.1; Node 22 LTS bundles + # npm 10.x, so upgrade globally before `npm ci` so all later npm + # invocations (including publish) use the new version. + - name: Upgrade npm for OIDC trusted publishing + run: npm install -g npm@^11.5.1 + - run: npm ci + # Preflight for OIDC trusted publishing. There is no long-lived + # NPM_TOKEN anymore — each run mints a short-lived OIDC token from + # GitHub, which npm exchanges with the registry. The two things that + # can break: + # 1. The workflow lost `permissions: id-token: write` (no OIDC + # endpoint exposed -> ACTIONS_ID_TOKEN_REQUEST_URL is unset). + # 2. npm CLI is too old to know how to do the exchange. + # Both surface here, instead of as an opaque registry rejection + # halfway through a publish. + # + # To (re)configure the npm side: npmjs.com -> each package + # (@openhop/server, @openhop/web, openhop) -> Settings -> Trusted + # Publisher -> GitHub Actions, with repo `naorsabag/openhop` and + # workflow `publish.yml`. + - name: Verify OIDC trusted publishing is wired up + run: | + if [ -z "${ACTIONS_ID_TOKEN_REQUEST_URL:-}" ]; then + echo "::error::OIDC unavailable — workflow is missing 'permissions: id-token: write'." + exit 1 + fi + npm_version=$(npm --version) + # `sort -V -C` returns success iff the input is already version-sorted, + # so feeding "11.5.1\n$npm_version" succeeds iff $npm_version >= 11.5.1. + if ! printf '%s\n' "11.5.1" "$npm_version" | sort -V -C; then + echo "::error::npm $npm_version is too old for OIDC trusted publishing — need >=11.5.1." + exit 1 + fi + echo "::notice::OIDC ready, npm $npm_version" + - name: Resolve target versions id: versions run: | @@ -89,25 +124,28 @@ jobs: id: publish_server if: steps.server_status.outputs.publish == 'true' working-directory: packages/server + # No env: OIDC handles auth via id-token. npm >=11.5.1 also + # auto-attaches a signed provenance attestation on trusted-publishing + # runs — no --provenance flag needed. run: npm publish --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Publish @openhop/web id: publish_web if: steps.web_status.outputs.publish == 'true' working-directory: packages/web + # No env: OIDC handles auth via id-token. npm >=11.5.1 also + # auto-attaches a signed provenance attestation on trusted-publishing + # runs — no --provenance flag needed. run: npm publish --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Publish openhop CLI id: publish_cli if: steps.cli_status.outputs.publish == 'true' working-directory: packages/cli + # No env: OIDC handles auth via id-token. npm >=11.5.1 also + # auto-attaches a signed provenance attestation on trusted-publishing + # runs — no --provenance flag needed. run: npm publish --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # Tag + GitHub Release whenever ANY publish happened. Tag scheme # branches on what actually shipped so a one-package bump can't