Skip to content
Merged
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,33 @@ jobs:
echo "wanted=${expected} actual=${actual}"
case "${actual}" in "v${expected}"*) ;; *) echo "::error::node mismatch"; exit 1 ;; esac

# `registry-url` is what kept every release workflow off this action: measured 2026-09-05,
# seven of the nine `release.yml` in this ecosystem pass it, and the action did not accept
# it — so adopting the shared setup meant losing npm authentication. It is a passthrough to
# `actions/setup-node`, and a passthrough nobody exercises is a passthrough that can be
# silently dropped in a refactor.
- name: Run the action again, asking for a registry
uses: ./actions/setup
with:
node-version: ${{ matrix.node }}
working-directory: fixtures/pnpm-repo
# No install: the toolchain and the .npmrc are the whole subject here.
install: 'false'
registry-url: 'https://registry.npmjs.org'
- name: setup-node wrote an npmrc binding the token
shell: bash
# Asserting the FILE rather than `npm config get registry`, because the latter reads the
# effective config and would go green on a registry that came from somewhere else — the
# claim under test is that this action caused it.
run: |
set -euo pipefail
: "${NPM_CONFIG_USERCONFIG:?setup-node did not point NPM_CONFIG_USERCONFIG anywhere}"
echo "userconfig: ${NPM_CONFIG_USERCONFIG}"
test -f "${NPM_CONFIG_USERCONFIG}"
grep -q 'registry.npmjs.org' "${NPM_CONFIG_USERCONFIG}"
grep -q '_authToken' "${NPM_CONFIG_USERCONFIG}"
echo "npmrc names the registry and binds _authToken"

npm-oidc-action:
name: npm-oidc action
runs-on: ubuntu-latest
Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- **`actions/setup` accepts `registry-url`, which is what kept every release workflow off it
(#54).** Measured 2026-09-05 across the ten consumers: **22 workflows set up Node and pnpm by
hand, and exactly one file used this action.** The largest group of duplicates is the nine
`release.yml`, and **seven of them pass `registry-url`** — so adopting the shared setup meant
losing npm authentication. One missing passthrough was holding the whole adoption.

Everything else was already equivalent, including the part most likely to be lost in a rewrite:
the action's `cache-dependency-path` already lists `package.json` beside `pnpm-lock.yaml`, which
is the fix for a pnpm major bump restoring a store the new pnpm reads as inconsistent
(`ERR_PNPM_MISSING_PACKAGE_INDEX_FILE`).

Exercised rather than asserted: the action's own CI job now runs it with a registry and checks
that `setup-node` wrote an `.npmrc` naming the registry and binding `_authToken`. The assertion
reads the FILE rather than `npm config get registry`, because the latter would go green on a
registry that came from somewhere else.

- **`promotion-gate.yml` is now a reusable workflow, so the gate that protects `develop` has one
home instead of ten (#51).** Measured 2026-09-05 across the ten consumers of this repository:
nine held **byte-identical** copies of a 74-line gate (identical after stripping comments and
Expand Down
15 changes: 15 additions & 0 deletions actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,19 @@ inputs:
has to say so here — otherwise the install runs against nothing and reports success.
required: false
default: '.'
registry-url:
description: >-
Passed straight to `actions/setup-node`, which writes an `.npmrc` binding
`_authToken` to `NODE_AUTH_TOKEN`. A publishing job needs it; nothing else does, so it is
empty by default and `setup-node` then writes no `.npmrc` at all.

This input exists because its absence was what kept every release workflow off this action.
Measured 2026-09-05 across the ten consumers: 22 workflows set up Node and pnpm by hand and
exactly one file used this action. Of the nine `release.yml`, SEVEN pass `registry-url` —
so for the largest group of duplicates, adopting the shared setup meant losing npm
authentication. One missing passthrough was holding the whole adoption.
required: false
default: ''

outputs:
package-manager-version:
Expand Down Expand Up @@ -62,6 +75,8 @@ runs:
with:
node-version: ${{ inputs.node-version }}
node-version-file: ${{ inputs.node-version == '' && format('{0}/.nvmrc', inputs.working-directory) || '' }}
# Empty writes no `.npmrc`, which is what every non-publishing job wants.
registry-url: ${{ inputs.registry-url }}
cache: pnpm
# The cache key must change when the package manager does. setup-node keys the pnpm store on
# the lockfile alone, so a pnpm 9 -> 10 bump leaves the key identical and the job restores a
Expand Down