ci: switch npm publish to OIDC trusted publishing (removes NPM_TOKEN)#50
ci: switch npm publish to OIDC trusted publishing (removes NPM_TOKEN)#5027Bslash6 wants to merge 1 commit into
Conversation
Removes the long-lived NPM_TOKEN secret from the release pipeline. Every publish now authenticates via short-lived OIDC tokens minted by GitHub Actions and validated by npm against a registered trusted publisher config. Changes: - release-please.yml publish-cachekit: drop the .npmrc shim and the NODE_AUTH_TOKEN env; use npm publish (not pnpm) so we use the npm CLI's native OIDC handling - build-native.yml publish (platform + main): same — drop env tokens, use npm publish with --provenance and (for main pkg) --ignore-scripts - Both jobs upgrade npm to latest before publish; Node 22 ships npm 10.9 which predates OIDC trusted publishing (needs >= 11.5.1) id-token: write was already granted in both publish jobs; no permission delta. The provenance attestation that npm publish emits remains the SLSA L2 statement consumers already see. ONE-TIME npm side setup required before merge — see PR description.
📝 WalkthroughWalkthroughBoth CI/CD workflows transition from token-based npm/pnpm publishing to npm OIDC trusted publishing. The build-native and release-please workflows each add npm version upgrades for OIDC support, remove token environment variables, and add Changesnpm OIDC Trusted Publishing Migration
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/build-native.yml:
- Around line 173-176: Replace the unpinned npm upgrade step that uses "npm
install -g npm@latest" in the "Upgrade npm for OIDC" step with a pinned,
known-compatible version (e.g., "npm@11.5.1") to ensure deterministic builds;
update the same step in both workflows (the "Upgrade npm for OIDC" step in
build-native.yml and the corresponding step in release-please.yml) so the run
command uses the pinned package instead of `@latest`.
In @.github/workflows/release-please.yml:
- Around line 82-85: Update the GitHub Actions step named "Upgrade npm for OIDC"
to pin the npm CLI to the documented minimum version instead of using `@latest`:
change the run invocation from "npm install -g npm@latest" to "npm install -g
npm@11.5.1" (make the same change for the identical step in build-native.yml);
this ensures the OIDC publish step uses the required npm >= 11.5.1 without
introducing version drift.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 164b34c2-52c9-403b-a83b-977903ea6eed
📒 Files selected for processing (2)
.github/workflows/build-native.yml.github/workflows/release-please.yml
| # npm Trusted Publishing (OIDC) requires npm >= 11.5.1. | ||
| # Node 22 ships an older npm; upgrade in-place for the publish steps. | ||
| - name: Upgrade npm for OIDC | ||
| run: npm install -g npm@latest |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's examine the build-native.yml file to understand the full context
cat -n .github/workflows/build-native.yml | head -180 | tail -30Repository: cachekit-io/cachekit-ts
Length of output: 1346
🏁 Script executed:
# Check the Node version being used in the workflow
rg -A 5 -B 5 "node-version" .github/workflows/build-native.ymlRepository: cachekit-io/cachekit-ts
Length of output: 1226
🏁 Script executed:
# Look for release-please.yml file
find .github -name "*release*" -type fRepository: cachekit-io/cachekit-ts
Length of output: 104
🏁 Script executed:
# Now let's check release-please.yml for similar patterns
cat -n .github/workflows/release-please.yml | grep -A 5 -B 5 "npm"Repository: cachekit-io/cachekit-ts
Length of output: 1082
🏁 Script executed:
# Let's also search for any npm version specifications in the entire .github directory
rg "npm@" .github/Repository: cachekit-io/cachekit-ts
Length of output: 217
🏁 Script executed:
# Check if there are any other references to npm installation or OIDC
rg "OIDC|trusted.*publish" .github/workflows/ -iRepository: cachekit-io/cachekit-ts
Length of output: 691
🌐 Web query:
npm trusted publishing OIDC version requirement Node 22
💡 Result:
To use npm trusted publishing with OpenID Connect (OIDC), you must meet specific version requirements for both the npm CLI and Node.js. As of May 2026, official documentation requires npm CLI version 11.5.1 or later and Node.js version 22.14.0 or higher [1][2]. While some earlier versions of Node.js 22 may not include a compatible version of the npm CLI by default, you can satisfy the requirement by explicitly updating npm within your CI/CD workflow using the command npm install -g npm@latest [3][2]. If you are unable to update the npm CLI, you may encounter authentication errors, such as silent failures or 404 errors, because older versions of the npm client do not correctly handle the OIDC handshake [4]. In summary, ensure your environment uses: - npm CLI: 11.5.1 or later [1][3][2] - Node.js: 22.14.0 or later [1][2] Additionally, your CI/CD workflow must be configured with the necessary OIDC permissions (e.g., id-token: write for GitHub Actions) to generate the required tokens [1][5][6].
Citations:
- 1: https://docs.npmjs.com/trusted-publishers/
- 2: Switch to OIDC trusted publishing for npm packages WordPress/gutenberg#77227
- 3: https://www.mbgsec.com/_archive/2025-09-23-trusted-publishing-for-npm-packages-npm-docs/
- 4: https://www.linkedin.com/posts/kenrick-tandrian_npm-trusted-publishers-the-weird-404-error-activity-7415708899330142208-YBwO
- 5: https://npmdigest.com/guides/npm-trusted-publishing
- 6: https://philna.sh/blog/2026/01/28/trusted-publishing-npm/
Pin npm versions in both publish workflows instead of using @latest.
Lines 173-176 in build-native.yml and lines 82-85 in release-please.yml both upgrade npm using npm install -g npm@latest. For OIDC trusted publishing on Node 22, npm 11.5.1+ is required. Using @latest makes release workflows depend on future npm versions rather than a known-compatible baseline. Pin to a specific version (e.g., npm@11.5.1) to ensure deterministic, reproducible releases and prevent unexpected breakage from major npm updates.
♻️ Proposed changes
build-native.yml (lines 173-176):
- - name: Upgrade npm for OIDC
- run: npm install -g npm@latest
+ - name: Upgrade npm for OIDC
+ run: npm install -g npm@11.5.1release-please.yml (lines 82-85):
- - name: Upgrade npm for OIDC
- run: npm install -g npm@latest
+ - name: Upgrade npm for OIDC
+ run: npm install -g npm@11.5.1📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # npm Trusted Publishing (OIDC) requires npm >= 11.5.1. | |
| # Node 22 ships an older npm; upgrade in-place for the publish steps. | |
| - name: Upgrade npm for OIDC | |
| run: npm install -g npm@latest | |
| # npm Trusted Publishing (OIDC) requires npm >= 11.5.1. | |
| # Node 22 ships an older npm; upgrade in-place for the publish steps. | |
| - name: Upgrade npm for OIDC | |
| run: npm install -g npm@11.5.1 |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/build-native.yml around lines 173 - 176, Replace the
unpinned npm upgrade step that uses "npm install -g npm@latest" in the "Upgrade
npm for OIDC" step with a pinned, known-compatible version (e.g., "npm@11.5.1")
to ensure deterministic builds; update the same step in both workflows (the
"Upgrade npm for OIDC" step in build-native.yml and the corresponding step in
release-please.yml) so the run command uses the pinned package instead of
`@latest`.
| # npm Trusted Publishing (OIDC) requires npm >= 11.5.1. | ||
| # Node 22 ships an older npm; upgrade in-place for the publish step. | ||
| - name: Upgrade npm for OIDC | ||
| run: npm install -g npm@latest |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's examine the release-please.yml file around the mentioned lines
cat -n .github/workflows/release-please.yml | sed -n '70,95p'Repository: cachekit-io/cachekit-ts
Length of output: 828
🏁 Script executed:
# Also check if there are other workflow files with npm upgrade steps
fd '.yml$|.yaml$' .github/workflows/ --exec grep -l "npm install -g npm" {} \;Repository: cachekit-io/cachekit-ts
Length of output: 139
🏁 Script executed:
# Let's check the complete context of the release-please.yml file to understand the structure
wc -l .github/workflows/release-please.ymlRepository: cachekit-io/cachekit-ts
Length of output: 107
🏁 Script executed:
# Check build-native.yml for npm upgrade context
grep -n -B5 -A5 "npm install -g npm" .github/workflows/build-native.ymlRepository: cachekit-io/cachekit-ts
Length of output: 589
🏁 Script executed:
# Let's verify the npm version requirements by checking if there's any documentation or package metadata
# Search for any references to npm versions in the repo
rg "11\.5\.1|npm.*version|trusted.*publish" -i --type yamlRepository: cachekit-io/cachekit-ts
Length of output: 49
🏁 Script executed:
# Check what version of npm is bundled with Node 22
# First, let's see if there's any documentation in the repo about npm/node versions
fd -e md -e txt | xargs rg "npm|node" -i | head -20Repository: cachekit-io/cachekit-ts
Length of output: 597
🏁 Script executed:
# Search for any existing npm version pins in the codebase
rg "npm@[0-9]" --type yamlRepository: cachekit-io/cachekit-ts
Length of output: 49
🏁 Script executed:
# Also check package.json files for engines specifications
fd package.json -x cat -n {} | grep -i "node\|npm"Repository: cachekit-io/cachekit-ts
Length of output: 1341
🌐 Web query:
npm OIDC trusted publishing minimum version requirement
💡 Result:
To use npm trusted publishing with OpenID Connect (OIDC), you must use npm CLI version 11.5.1 or later [1][2][3]. In addition to the CLI version requirement, official documentation specifies that Node.js version 22.14.0 or higher is required [1]. Trusted publishing allows you to publish packages directly from CI/CD environments (such as GitHub Actions or GitLab CI) without the need for long-lived npm access tokens [1][4]. To implement this, you must configure the trusted publisher settings on the npmjs.com package page and ensure your CI/CD workflow has the necessary permissions (e.g., id-token: write in GitHub Actions) to generate and exchange OIDC tokens [5][1][4]. Note that a package must typically exist on the npm registry before you can configure it for trusted publishing [6][7][8].
Citations:
- 1: https://docs.npmjs.com/trusted-publishers/
- 2: https://philna.sh/blog/2026/01/28/trusted-publishing-npm/
- 3: https://github.blog/changelog/2025-07-31-npm-trusted-publishing-with-oidc-is-generally-available/
- 4: https://npmdigest.com/guides/npm-trusted-publishing
- 5: chore: Enable trusted publishing of package using OIDC auth0/express-openid-connect#803
- 6: Allow publishing initial version with OIDC npm/cli#8544
- 7: feat: adds support for oidc publish npm/cli#8336
- 8: https://medium.com/@n.saarberg/trusted-publishing-with-github-oidc-668961051bf4
Pin the npm CLI version to the documented minimum for OIDC.
Both release-please.yml (line 85) and build-native.yml (line 176) use npm@latest to upgrade npm for trusted publishing. Since OIDC publishing requires npm >= 11.5.1 (as documented in the comments), using @latest introduces unnecessary drift on a release-critical path. Pin to npm@11.5.1 in both workflows for consistency.
♻️ Proposed changes
release-please.yml:
- run: npm install -g npm@latest
+ run: npm install -g npm@11.5.1build-native.yml:
- run: npm install -g npm@latest
+ run: npm install -g npm@11.5.1📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # npm Trusted Publishing (OIDC) requires npm >= 11.5.1. | |
| # Node 22 ships an older npm; upgrade in-place for the publish step. | |
| - name: Upgrade npm for OIDC | |
| run: npm install -g npm@latest | |
| # npm Trusted Publishing (OIDC) requires npm >= 11.5.1. | |
| # Node 22 ships an older npm; upgrade in-place for the publish step. | |
| - name: Upgrade npm for OIDC | |
| run: npm install -g npm@11.5.1 |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release-please.yml around lines 82 - 85, Update the GitHub
Actions step named "Upgrade npm for OIDC" to pin the npm CLI to the documented
minimum version instead of using `@latest`: change the run invocation from "npm
install -g npm@latest" to "npm install -g npm@11.5.1" (make the same change for
the identical step in build-native.yml); this ensures the OIDC publish step uses
the required npm >= 11.5.1 without introducing version drift.
#51) ## Summary The \`build-native.yml\` publish step has been broken since the @napi-rs/cli v3 upgrade. The \`Move artifacts to platform packages\` step calls: \`\`\`yaml npx napi artifacts --artifacts-dir artifacts \`\`\` @napi-rs/cli v3 renamed that flag to \`--output-dir\` (also accepts \`-o\` / \`-d\`). The old flag name was removed entirely — passing it now produces: \`\`\` Unsupported option name ("--artifacts-dir"). \`\`\` This silently broke publication of the 5 native platform packages and the main \`@cachekit-io/cachekit-core-ts\` package. The \`cachekit-core-ts-v0.1.1\` tag (pushed 2026-04-26) attempted to publish via run \`24957357035\` and failed at this step, which is why npm still only has \`cachekit-core-ts@0.1.0\` and zero platform packages. ## Verification Ran \`napi artifacts --help\` against @napi-rs/cli@3.5.1 locally (the exact version pinned in \`packages/cachekit-core-ts/package.json\`): \`\`\` --output-dir,-o,-d #0 Path to the folder where all built .node files put, same as --output-dir of build command \`\`\` No other flag changes affect the publish step. The download target directory (\`packages/cachekit-core-ts/artifacts\`) is unchanged. ## Why this matters now This is step 1 of the bootstrap path for #50 (OIDC trusted publishing). The plan agreed with @27Bslash6: 1. **This PR** — fix napi flag so the publish step can actually run 2. After merge: cut a real 0.1.2 release (skipping the ghost 0.1.1 tag that never reached npm) 3. After that ships, configure trusted publishers for all 7 npm packages (2 main + 5 platform) 4. Merge #50 (currently draft) ## Test plan - [x] \`actionlint\` clean - [ ] CI green on this PR - [ ] After merge + first \`cachekit-core-ts-v*\` tag, verify the build-native publish job completes the artifact-move step successfully <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated build workflow configuration to align with the latest tooling version, ensuring continued compatibility with the native build process. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/cachekit-io/cachekit-ts/pull/51?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
…2 release (#52) ## Summary Two real documentation fixes that double as the trigger commit for the 0.1.2 recovery release. ### `packages/cachekit/README.md` - `Requirements: Node.js 18+` was stale. PR #47 bumped `engines.node` to `>=22.0.0` across all packages. README now matches: `Node.js 22+`. - Added a short version-history note explaining the `0.1.0 → 0.1.2` jump on npm so consumers don't think 0.1.1 is missing or yanked. ### `packages/cachekit-core-ts/README.md` (new) Every npm-published package should have a README. This one didn't. Added a minimal one covering: - What the package is and that consumers shouldn't install it directly - The 5 prebuilt platform packages and how `optionalDependencies` selects one - A summary of the public N-API surface - The same 0.1.0 → 0.1.2 version note ## Why this is the bootstrap commit for 0.1.2 The commit touches both `packages/cachekit/` and `packages/cachekit-core-ts/` paths so release-please picks both packages up for a coordinated release. The `Release-As: 0.1.2` trailer skips 0.1.1 (which exists as a git tag but never reached npm) and forces release-please to propose 0.1.2 directly. Type is `docs:` because that's what the changes honestly are — no code behavior changes. The `Release-As:` trailer is what triggers the release, not the type. ## What happens after this merges 1. release-please.yml fires on push to main 2. release-please scans commits since the last published manifest, sees the `Release-As: 0.1.2` trailer and the path touches → opens a release PR titled `chore: release main` proposing 0.1.2 for both packages 3. Merging that release PR cuts tags `cachekit-v0.1.2` and `cachekit-core-ts-v0.1.2` 4. `release-please.yml publish-cachekit` runs (auth fix from PR #45 is in place) → publishes `@cachekit-io/cachekit@0.1.2` 5. The core-ts tag triggers `build-native.yml` → publishes `@cachekit-io/cachekit-core-ts@0.1.2` + creates all 5 platform packages on npm (napi flag fix from PR #51 is in place) After step 5, all 7 packages exist on npm — at which point you can: 6. Configure trusted publishers on npmjs.com for each 7. Take PR #50 out of draft and merge it 8. Delete the `NPM_TOKEN` repo secret after the next OIDC-based release confirms the loop ## Fallback if release-please ignores `Release-As:` on a `docs:` commit If release-please's defaults don't pick up `Release-As:` from a non-releasing commit type, the fallback is to: - Bump both `package.json` files to 0.1.2 directly - Update `.release-please-manifest.json` to 0.1.2 for both packages - Manually create and push the tags I'd open that as a follow-up PR if needed — keeping the doc-fix and the release-trigger separate. ## Test plan - [x] Local validation via prek (no hooks affected by markdown-only changes) - [ ] CI green on this PR - [ ] After merge: confirm release-please opens a 0.1.2 PR within a few minutes - [ ] Merge the release PR and watch both publish workflows go green <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added comprehensive documentation for the native binding package, including installation guidance and platform support details * Updated minimum Node.js version requirement to 22+ * Clarified version and release information <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/cachekit-io/cachekit-ts/pull/52?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary Manually applies what release-please would have done if the docs-only trigger commit in #52 had been a "user-facing" type. Release-please skips `docs`/`chore`/`ci`/etc. commits even when `Release-As:` is present — `Release-As:` overrides the *version*, not the release-trigger *gate*. Rather than fake a `fix:` commit (which would have been dishonest, per the feedback on #52's earlier draft), this PR bypasses release-please entirely for the one-time recovery. Future releases use the normal release-please flow. ## What changes | File | Change | |---|---| | `.release-please-manifest.json` | Both packages bumped to `0.1.2` so release-please future runs treat 0.1.2 as the last released state | | `packages/cachekit/package.json` | `version: 0.1.1 → 0.1.2` | | `packages/cachekit-core-ts/package.json` | `version: 0.1.1 → 0.1.2` | | `packages/cachekit/CHANGELOG.md` | New `## [0.1.2]` section explaining the 0.1.1 → 0.1.2 history | | `packages/cachekit-core-ts/CHANGELOG.md` | Same | ## Manual steps after this merges 1. Tag the merge commit and push: ```bash git checkout main && git pull git tag cachekit-v0.1.2 -m "@cachekit-io/cachekit 0.1.2" git tag cachekit-core-ts-v0.1.2 -m "@cachekit-io/cachekit-core-ts 0.1.2" git push origin cachekit-v0.1.2 cachekit-core-ts-v0.1.2 ``` 2. The `cachekit-core-ts-v0.1.2` tag triggers `build-native.yml` → publishes `@cachekit-io/cachekit-core-ts@0.1.2` + creates all 5 platform packages on npm (napi flag fix from #51 is in place). 3. `workflow_dispatch release-please.yml` with `force_release: true` → publishes `@cachekit-io/cachekit@0.1.2`. The release-please job inside will skip (no user-facing commits since 0.1.1), but the `publish-cachekit` job has `force_release == 'true'` as a fire condition and will check out `github.sha` (main HEAD, now 0.1.2) and publish. 4. Verify all 7 packages exist on npm: ```bash for pkg in @cachekit-io/cachekit @cachekit-io/cachekit-core-ts \ @cachekit-io/cachekit-core-ts-linux-x64-gnu \ @cachekit-io/cachekit-core-ts-linux-arm64-gnu \ @cachekit-io/cachekit-core-ts-darwin-x64 \ @cachekit-io/cachekit-core-ts-darwin-arm64 \ @cachekit-io/cachekit-core-ts-win32-x64-msvc; do echo "$pkg: $(npm view "$pkg" version 2>&1)" done ``` 5. Configure trusted publishers on npmjs.com for each of the 7 packages. 6. Take #50 out of draft and merge it. Next release uses OIDC; no `NPM_TOKEN` needed. 7. Delete the `NPM_TOKEN` repo secret. ## Why this isn't tagged by release-please Release-please reads the manifest to know what was last released and proposes the next version from commit history. Once the manifest claims 0.1.2 is already released, release-please will look for commits *after* this PR for the next release. No release PR will be generated for 0.1.2 — that's the whole point of the manual bootstrap. ## Test plan - [x] `pnpm install` confirms lockfile already in sync (workspace deps use `workspace:*`) - [x] CI green on this PR - [ ] After merge: manually tag + push (step 1 above) - [ ] Verify `build-native.yml` run on the tag succeeds end-to-end (including the previously-broken artifact-move step) - [ ] Verify `workflow_dispatch` release-please publish-cachekit succeeds - [ ] Verify all 7 packages on npm at 0.1.2 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **Chores** * Released version 0.1.2 for cachekit and cachekit-core-ts packages. * Updated minimum Node.js requirement to version 22+. * **Documentation** * Added documentation covering platform packages and N-API surface. * Updated changelog entries with release details and version jump explanation. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/cachekit-io/cachekit-ts/pull/53?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
Two latent bugs in \`build-native.yml\`'s publish job, caught during the
local 0.1.2 bootstrap publish. Neither would have allowed a successful
release-please-driven publish even with a working \`NPM_TOKEN\` — the
publish job has never actually run end-to-end.
### Bug 1: missing \`napi version\` (platform packages stuck at
scaffolded version)
napi-rs scaffolds \`npm/<platform>/package.json\` files at the version
present when \`napi build\` first ran (here: 0.1.0). They don't update
on subsequent version bumps unless explicitly synced.
Without this step, every release would have published the platform
packages at \`0.1.0\` forever, even as the parent package bumped to
0.1.2, 0.1.3, etc. The main \`@cachekit-io/cachekit-core-ts\` package
would then fail to install because its \`optionalDependencies\` request
a matching version that wouldn't exist.
**Fix**: \`npx napi version\` between \`napi artifacts\` and the publish
loop. It reads the parent package's version and writes it into each
\`npm/<platform>/package.json\`.
### Bug 2: \`find ... npm publish {}\` interpreted as GitHub shorthand
\`npm publish npm/darwin-arm64\` is interpreted as the GitHub shorthand
\`<user>/<repo>\`, not a local directory. npm tries
\`ssh://git@github.com/npm/darwin-arm64.git\`, fails with \`Permission
denied (publickey)\` because GHA runners have no SSH key for github.com.
Visible in [run
25986564957](https://github.com/cachekit-io/cachekit-ts/actions/runs/25986564957)
which fired on the \`cachekit-core-ts-v0.1.2\` tag push.
**Fix**: prefix \`{}\` with \`./\` to force local-directory
interpretation.
## Why now
Surfaced during the local-publish bootstrap script
(\`/tmp/publish-cachekit-0.1.2.sh\`). Both bugs reproduced locally; both
fixes were validated in the script. The same fixes here mean future
CI-driven releases work as intended.
## Interaction with #50
#50 (OIDC trusted publishing, draft) also touches the publish steps in
this workflow — replacing \`NODE_AUTH_TOKEN\` with OIDC. When #50 is
ready to come out of draft, it'll rebase onto this fix and keep both
improvements.
## Test plan
- [x] \`actionlint\` clean
- [x] Both fixes validated locally during the 0.1.2 publish script run
(the napi version step bumped all 5 platform jsons to 0.1.2; the \`./\`
prefix avoided the GitHub shorthand interpretation)
- [ ] Next \`cachekit-core-ts-v*\` tag push exercises the full publish
job end-to-end (requires #50 + trusted publishers to land before
\`NPM_TOKEN\` can be retired, but this PR's fixes work with either auth
model)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Improved automated publishing workflow to sync per-platform package
versions with the main package before publishing.
* Switched to publishing platform packages via explicit local package
paths for more reliable releases.
* Adjusted preparation and publish steps and clarified flags/behavior to
reduce release inconsistencies and better document expected outcomes.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/cachekit-io/cachekit-ts/pull/55?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Summary
Removes the long-lived
NPM_TOKENsecret from the release pipeline. Every npm publish now authenticates via short-lived OIDC tokens minted by GitHub Actions and validated by npm against a registered trusted publisher config.This is the same model
cachekit-pyuses with PyPI Trusted Publishing. Closes the gap identified in the workflow comparison earlier — it was the single biggest residual supply-chain attack surface in the release flow.Trusted publishers must be configured on npmjs.com before this PR merges, or the next release will fail. The packages affected:
@cachekit-io/cachekitRelease / publish-cachekit@cachekit-io/cachekit-core-tsBuild Native / publish@cachekit-io/cachekit-core-ts-{platform}× 5Build Native / publishFor each, add a trusted publisher with:
cachekit-io/cachekit-tsrelease-please.yml(for@cachekit-io/cachekit) orbuild-native.yml(for the core-ts + platform packages)Docs: https://docs.npmjs.com/trusted-publishers
After all releases switch successfully, remove the
NPM_TOKENrepository secret — it'll be dead weight and a removable attack surface.What changed in the workflows
release-please.ymlpublish-cachekit:Configure npm authstep that wrote~/.npmrcwith the tokenNODE_AUTH_TOKEN: \${{ secrets.NPM_TOKEN }}env from the publish steppnpm publish→npm publish(npm CLI has native OIDC support; pnpm 8.x bundles older npm)npm install -g npm@latestbefore publish — Node 22 ships npm 10.9 but OIDC trusted publishing requires npm ≥ 11.5.1build-native.ymlpublish:--ignore-scriptson the main package publish (defence against malicious lifecycle scripts in the package being published)Why this matters
NPM_TOKENlets an attacker publish arbitrary versions of any package the token owner can publish — typically catastrophic for SDK consumers (cf. the npm compromise wave covered in PR chore: harden supply chain — patch transitive CVEs, enforce frozen lockfile #46).Test plan
actionlintclean (run locally via prek)release-pleasePR merge triggers a successful OIDC publish of@cachekit-io/cachekitcachekit-core-ts-v*tag triggers successful OIDC publish of@cachekit-io/cachekit-core-ts+ platform packagesNPM_TOKENfrom repo secretsOut of scope
cachekit-pyparity item — separate PR if you want to close it)pnpm publish; but a moving target — the npm-upgrade trick is more durable)Summary by CodeRabbit