Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
contents: write # creating git tags and GitHub releases
issues: write # semantic-release opens issues on failure
pull-requests: write
id-token: write # npm provenance
id-token: write # OIDC — npm trusted publishing + provenance
steps:
- uses: actions/checkout@v6
with:
Expand All @@ -31,6 +31,18 @@ jobs:
node-version: 22
cache: pnpm
registry-url: 'https://registry.npmjs.org'

# Trusted publishing (OIDC) needs npm CLI >= 11.5.1. Node 22 bundles npm
# 10.9.x, which cannot perform the exchange. This matters because
# @semantic-release/npm treats a successful exchange as proof that auth is
# handled and returns *without* writing any token into .npmrc — so it then
# runs `npm publish` with no credentials, and an npm that can't do OIDC
# fails there. Installs use pnpm; publishing still goes through npm.
- name: Ensure npm supports trusted publishing
run: |
npm install -g npm@^11.5.1
npm --version

- run: pnpm install --frozen-lockfile

# Re-run the gate before publishing so a red build never reaches npm,
Expand Down
11 changes: 10 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,16 @@ If a squash is unavoidable, rename the squash commit message to `feat: …` or `

**`@semantic-release/git` and `@semantic-release/changelog` are intentionally not used, and are no longer installed.** Both would try to push a `chore(release):` commit back to the release branch, which branch protection rejects. Don't re-add them to `devDependencies` — they sat there unused (and generating dependabot majors) until they were removed. `package.json` and `CHANGELOG.md` in the repo are not auto-maintained — the authoritative record is the [GitHub Releases page](https://github.com/guzzlerio/deride/releases).

**Secrets required by the release workflow:** `NPM_TOKEN` (automation token with publish + provenance rights). `GITHUB_TOKEN` is provided automatically.
**npm authentication uses trusted publishing (OIDC) — not a long-lived token.** The publisher is configured registry-side at npmjs.com → deride → Settings → Trusted Publisher, pinned to this repo and `release.yml`. The workflow grants `id-token: write`, and `@semantic-release/npm` exchanges the GitHub OIDC token for a short-lived registry credential.

Two consequences worth knowing before editing `release.yml`:

- **Renaming the workflow file breaks publishing.** The trusted publisher config pins the filename. Rename it and the OIDC exchange returns 404 and the release fails.
- **npm CLI must be >= 11.5.1.** Node 22 bundles npm 10.9.x, so the workflow upgrades npm explicitly. On a successful exchange the plugin writes *no* token to `.npmrc`, so `npm publish` has to authenticate via OIDC itself — an older npm reaches that point with no credentials. Don't remove that step.

Provenance is generated automatically under trusted publishing. It was never actually enabled before (nothing passed `--provenance`, and `deride@2.2.0` has no attestations) despite the workflow comment claiming otherwise.

**Secrets:** `GITHUB_TOKEN` is provided automatically. `NPM_TOKEN` is retained only as a fallback — `@semantic-release/npm` uses it when the OIDC exchange fails. It is not the primary path.

## Conventional Commits — enforced on every PR

Expand Down