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
8 changes: 7 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Required for provenance statement
id-token: write # Required for npm trusted publishing (OIDC) and provenance
strategy:
matrix:
node-version: [24]
Expand All @@ -25,6 +25,9 @@ jobs:
version: 11.9.0
run_install: false

# `registry-url` is deliberately not set: it makes setup-node write a
# `_authToken=${NODE_AUTH_TOKEN}` line into .npmrc, which we have no token for.
# The default registry (registry.npmjs.org) is what trusted publishing targets anyway.
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
Expand All @@ -42,6 +45,9 @@ jobs:
CI: 1

- run: node scripts/prepublish.mjs

# No token is configured anywhere: pnpm exchanges the GitHub OIDC id token for a
# short-lived registry token, per package, via npm trusted publishing.
- run: pnpm publish --provenance --no-git-checks --filter '!monorepo'
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Expand Down
42 changes: 42 additions & 0 deletions docs/how_to_release.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,45 @@ pnpm prettier -w .
### Make PR with the changes

Like in other clients, new version is published by adding new tag.

## Publishing to npm (trusted publishing)

The `Release` workflow (`.github/workflows/release.yaml`) authenticates to npm with
[trusted publishing](https://docs.npmjs.com/trusted-publishers/): GitHub Actions mints a
short-lived OIDC token for the run, so there is no `NPM_TOKEN` secret involved. The
provenance attestation is still requested explicitly through `--provenance`.

Each package is configured separately on npmjs.com. For `@qdrant/js-client-rest`,
`@qdrant/js-client-grpc` and `@qdrant/qdrant-js`, under
_Settings → Trusted publishing → GitHub Actions_:

| Field | Value |
| -------------------- | -------------- |
| Organization or user | `qdrant` |
| Repository | `qdrant-js` |
| Workflow filename | `release.yaml` |
| Environment name | _(empty)_ |
| Allowed actions | `npm publish` |

The values are case-sensitive, and the workflow filename is just the filename — not the
path under `.github/workflows/`. Renaming or moving the release workflow means updating
this configuration for all three packages, otherwise publishing fails with a `404`.

Once trusted publishing works, publishing access for each package can be locked down under
_Settings → Publishing access → Require two-factor authentication and disallow tokens_.

### Requirements the workflow has to keep satisfying

- `permissions: id-token: write` on the release job — without it there is no OIDC token.
- pnpm >= 11.1.x. pnpm implements the OIDC exchange itself (it does not delegate to the
npm CLI), so the npm version on the runner is irrelevant. Earlier pnpm 11 releases had
a bug that broke the exchange; `pnpm/action-setup` must also be >= v6.0.6.
- No `_authToken` in `.npmrc`, and `registry-url` left unset on `actions/setup-node`
(it would write a token placeholder). If the OIDC exchange fails, pnpm only logs
`Skipped OIDC: ...` and falls back to whatever token it finds — with no token
configured the publish fails loudly instead of silently bypassing trusted publishing.
- The `repository.url` in each `package.json` must match this repository.

Note that the token exchange is per package name, so a brand-new package cannot be
published this way: its first version has to be published manually, after which trusted
publishing can be configured for it.