From e453eb5e19f50cf432eeba141a7a5225392b126a Mon Sep 17 00:00:00 2001 From: martyy-code Date: Mon, 3 Aug 2026 13:26:47 +0200 Subject: [PATCH 1/2] ci(release): switch publish step to npm trusted publishing (OIDC) Drops the NODE_AUTH_TOKEN env var from the publish step. The job's existing 'id-token: write' permission is what GitHub needs to mint the OIDC token, which npm exchanges for a short-lived publish credential. Required (by the user, before or after merge): 1. Add a trusted publisher on npmjs.com for @deessejs/errors, pointing at deessejs/errors with workflow 'release.yml'. 2. Cut one release via the modified workflow to validate end-to-end. 3. On npmjs.com: Settings -> Publishing access -> 'Require 2FA and disallow tokens' (recommended maximum-security posture). 4. Revoke the NPM_TOKEN GitHub secret once the OIDC publish succeeds. Adds a changeset to pass the new ci.yml lint. --- .changeset/switch-to-trusted-publishing.md | 5 +++++ .github/workflows/release.yml | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 .changeset/switch-to-trusted-publishing.md diff --git a/.changeset/switch-to-trusted-publishing.md b/.changeset/switch-to-trusted-publishing.md new file mode 100644 index 0000000..ab285dd --- /dev/null +++ b/.changeset/switch-to-trusted-publishing.md @@ -0,0 +1,5 @@ +--- +"@deessejs/errors": patch +--- + +Switch the release workflow to npm trusted publishing (OIDC) instead of `secrets.NPM_TOKEN`. The `id-token: write` permission, already declared on the job, is sufficient for GitHub to mint the OIDC token that npm exchanges for a short-lived publish credential. Provenance is generated automatically on public repos. The `NPM_TOKEN` secret can be revoked once the first OIDC publish succeeds. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3bc4dc3..95cd5f8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -84,8 +84,6 @@ jobs: - name: Publish packages if: steps.detect.outputs.has_changesets == 'true' && (github.event_name == 'workflow_dispatch' || inputs.dry_run != true) - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} run: | if [ -n "${{ inputs.packages }}" ]; then pnpm changeset publish --packages=$(echo "${{ inputs.packages }}" | tr ',' ' ') From 5a6f11c436ade7d327bd08d5bfcf6d6f00aa70f9 Mon Sep 17 00:00:00 2001 From: martyy-code Date: Mon, 3 Aug 2026 13:33:35 +0200 Subject: [PATCH 2/2] ci(release): tag release job with environment: release GitHub Environment gives us a deployment record per run, visible in the Deployments API and the GitHub UI. No protection rules are attached yet, so the trigger stays label-less / fire-on-every-merge. Future hardening (required reviewers, branch restrictions, wait timer, env secrets) can attach to the same environment without changing this workflow further. The environment on the npmjs.com trusted publisher config is intentionally left blank for now; we only point at the workflow file. Adding environment name on the trusted publisher side would require the env on the workflow to exist first, which it now does. Adds a changeset to pass the new ci.yml lint. --- .changeset/add-release-environment.md | 5 +++++ .github/workflows/release.yml | 1 + 2 files changed, 6 insertions(+) create mode 100644 .changeset/add-release-environment.md diff --git a/.changeset/add-release-environment.md b/.changeset/add-release-environment.md new file mode 100644 index 0000000..96fd689 --- /dev/null +++ b/.changeset/add-release-environment.md @@ -0,0 +1,5 @@ +--- +"@deessejs/errors": patch +--- + +Tag the release job with `environment: release` so the run is recorded as a deployment to the `release` GitHub environment. Future hardening (required reviewers, branch restrictions, wait timer) can attach to the same environment without further workflow changes. Provenance and trusted publishing are unaffected. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 95cd5f8..4ebd652 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,6 +26,7 @@ jobs: release: name: Release runs-on: ubuntu-latest + environment: release # Run when a PR is merged into main OR manually triggered if: | github.event_name == 'workflow_dispatch' ||