chore: version packages (#583) #440
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| concurrency: ${{ github.workflow }}-${{ github.ref }} | |
| permissions: | |
| contents: read | |
| jobs: | |
| release: | |
| name: Release — version PR or publish | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| permissions: | |
| contents: read | |
| id-token: write | |
| env: | |
| NPM_CONFIG_PROVENANCE: true | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| fetch-depth: 0 | |
| - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 | |
| # Node 24 bundles npm 11.13+, above the 11.5.1 floor where npm implements | |
| # the OIDC trusted-publishing exchange. Node 22 ships npm 10.9, which has | |
| # no OIDC support at all — the previous workaround installed npm 11.14.1 | |
| # into RUNNER_TEMP and prepended it to PATH, but changesets/action spawns | |
| # the publish in a subprocess that could still resolve the bundled npm 10. | |
| # With no OIDC, npm falls back to the .npmrc token and the publish PUT | |
| # returns a bare 404. Matching dawn and angular-agent-framework, which | |
| # both publish with provenance on this setup. | |
| # | |
| # `registry-url` is deliberate and matches those repos: it writes the | |
| # publish .npmrc. It is safe precisely because NODE_AUTH_TOKEN is never | |
| # set — see the guard below. | |
| - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 | |
| with: | |
| node-version: 24.19.0 | |
| cache: pnpm | |
| registry-url: https://registry.npmjs.org | |
| - run: pnpm install --frozen-lockfile --ignore-scripts --ignore-pnpmfile | |
| - run: pnpm security:audit | |
| - run: pnpm typecheck | |
| - run: pnpm lint | |
| - run: pnpm test | |
| - run: pnpm build | |
| - run: pnpm consumer:check | |
| - run: pnpm react:compat | |
| - run: pnpm lint:packaging | |
| - run: pnpm publish:preflight | |
| - name: Assert OIDC-only publishing | |
| run: | | |
| # Two invariants, both of which have silently broken a release: | |
| # 1. No npm token in the environment. Any token makes npm use token | |
| # auth and skip the trusted-publishing exchange, which also means | |
| # no provenance attestation — a silent downgrade, not a failure. | |
| # 2. npm >= 11.5.1, the floor where the OIDC exchange exists. Below | |
| # it npm cannot do trusted publishing at all and falls back to | |
| # the .npmrc token, producing a bare `E404 Not Found - PUT`. | |
| fail=0 | |
| if [ -n "${NODE_AUTH_TOKEN:-}" ]; then | |
| echo "::error::NODE_AUTH_TOKEN is set. Publishing is OIDC-only; a token disables the OIDC exchange and drops provenance." | |
| fail=1 | |
| fi | |
| if [ -n "${NPM_TOKEN:-}" ]; then | |
| echo "::error::NPM_TOKEN is set in the environment. Publishing is OIDC-only." | |
| fail=1 | |
| fi | |
| npm_version=$(npm --version) | |
| echo "npm $npm_version (node $(node --version))" | |
| if [ "$(printf '%s\n11.5.1\n' "$npm_version" | sort -V | head -1)" != "11.5.1" ]; then | |
| echo "::error::npm $npm_version is below the 11.5.1 OIDC trusted-publishing floor." | |
| fail=1 | |
| fi | |
| if [ "$fail" -ne 0 ]; then exit 1; fi | |
| echo "OIDC-only preconditions hold." | |
| - name: Version PR or publish | |
| id: changesets | |
| uses: changesets/action@8488615a623b1b9c987934bb89eae8af6a946ac1 # v2 | |
| with: | |
| version-script: pnpm exec changeset version | |
| publish-script: node ./scripts/publish-configured-packages.mjs | |
| pr-title: "chore: version packages" | |
| commit-message: "chore: version packages" | |
| # This secret must contain a fine-grained PAT, repository-scoped to | |
| # pretable, with only Contents and Pull requests write access. GitHub | |
| # does not expose a secret's underlying grants through the repository | |
| # secret API, so rotation must verify them in the token's settings. | |
| github-token: ${{ secrets.RELEASE_GITHUB_TOKEN }} | |
| # No NODE_AUTH_TOKEN. Publishing is OIDC-only: any token in the | |
| # environment makes npm use token auth and skip the trusted-publishing | |
| # exchange, which also means no provenance attestation. A package | |
| # without a trusted publisher must fail loudly here rather than fall | |
| # back to a token — see the preflight guard above. | |
| - name: Enable auto-merge on Version PR | |
| if: steps.changesets.outputs.pr-number != '' | |
| env: | |
| GH_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }} | |
| run: | | |
| gh pr merge \ | |
| --auto \ | |
| --squash \ | |
| --repo ${{ github.repository }} \ | |
| ${{ steps.changesets.outputs.pr-number }} |