ci: migrate npm publish to OIDC trusted publishing#983
Conversation
The npmpublish.yml workflow was authenticating via a stored NPM_TOKEN secret that recently started failing E404 on PUT — first observed after #981 merged at 6.1.1 (run 26279691349). Same E404 pattern that hit ep_hljs four days ago. Stored publish tokens have two failure modes that this PR removes entirely: 1. They expire / get rotated and silently break automated publishes. 2. They survive in compromised CI logs / forks long enough to be abused. OIDC trusted publishing exchanges a short-lived GitHub-issued id-token for a per-publish credential at the registry. No secret on our side, no expiry, and the resulting publish is attested with `--provenance` so the npm package page shows the signing GHA run. Removes: - "Set publishing config" step that consumed secrets.NPM_TOKEN - "Add package to etherpad organization" step (the access grant is idempotent and was set at initial publish; it doesn't need to run on every release and the OIDC credential isn't authorised for it) Adds: - `permissions: { contents: write, id-token: write }` on the publish job (contents:write was already implicit via GITHUB_TOKEN for the version-bump push; id-token:write is the OIDC enabler) - `registry-url` on setup-node so the auth header lands at npmjs.org - `--no-git-checks` on pnpm publish (skip the dirty-tree guard that would otherwise trip on the just-pushed version-bump commit) - `--provenance` for the signing attestation One-time setup required on https://www.npmjs.com/package/ueberdb2/access before this lands — Trusted Publishers → Add → Provider: GitHub Actions, Org: ether, Repo: ueberDB, Workflow: npmpublish.yml, Environment: blank. Documented at the top of the publish-npm job. Bumps the publish-job pnpm pin from 10 to 11 to match the test job; trusted publishing requires pnpm >= 10.4 either way. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
Review Summary by QodoMigrate npm publish to OIDC trusted publishing
WalkthroughsDescription• Replace stored NPM_TOKEN with OIDC trusted publishing • Add provenance attestation to published packages • Bump pnpm version from 10 to 11 • Remove per-publish npm access grant step Diagramflowchart LR
A["Stored NPM_TOKEN<br/>expires/rotates"] -->|Remove| B["OIDC Trusted<br/>Publishing"]
B -->|GitHub id-token| C["Short-lived<br/>credential"]
C -->|pnpm publish| D["npm registry"]
D -->|--provenance| E["Signed attestation<br/>on package page"]
File Changes1. .github/workflows/npmpublish.yml
|
Code Review by Qodo
1. OIDC active during install
|
Now that ether/ueberDB#983 unblocked the publish workflow (OIDC trusted publishing), ueberdb2 6.1.2 is live on npm and the `^6.1.0` pin in src/package.json resolves cleanly. Resolves the ERR_PNPM_OUTDATED_LOCKFILE that was blocking CI on this PR. 29 SessionStore backend tests still green against the published tarball. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: page sessionstorage cleanup to avoid OOM (#7830) SessionStore._cleanup() previously called `findKeys('sessionstorage:*', null)`, materialising every session key into a single array. On decade- old MariaDB installs with millions of sessions this OOMs the node process within ~15 minutes — see #7830. Switch to ueberdb2 6.1.0's findKeysPaged with a 500-key page size, and yield to the event loop between pages so the DB driver can release each page's buffered rows and request handlers can interleave. The break is now driven by `page.length === 0` rather than `page.length < CLEANUP_PAGE_SIZE` so a stubbed/throttled paged source still iterates the full keyspace. Adds a regression test that seeds 50 sessionstorage rows, monkey-patches `DB.findKeysPaged` to use a 4-key page, runs cleanup, and asserts every expired row is removed plus every valid row preserved across page boundaries. Closes #7830 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: address Qodo review on #7831 Four follow-ups raised by Qodo on the session cleanup paging fix: - DB.ts: fail-fast at init() if any required wrapper method (incl. findKeysPaged) is missing, so a stale ueberdb2 pin surfaces at boot rather than crashing the first cleanup run an hour later. - SessionStore: bound a single _cleanup() run to 10 minutes. Under sustained session creation the keyspace can grow faster than cleanup drains it; without a budget the next scheduled run would never fire. When the budget hits, log a warning and let the next run continue. - SessionStore: log the defensive `page[0] <= after` cursor-stall break. Previously the loop exited silently, leaving expired rows behind with no operator-visible signal of the backend regression. - Tests: the paged-cleanup regression test now removes both expiredSids AND validSids in finally, so a failed assertion doesn't leak rows. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: note paged session cleanup in CHANGELOG + settings template CHANGELOG.md picks up an entry under 3.1.0 Notable fixes describing the OOM cause, the paged iteration, the 10-minute per-run budget, the cursor-stall logging, and the fail-fast init guard. settings.json.template's sessionCleanup comment adds the page-size, budget, and pointer to #7830 so admins can reason about the new behaviour from the template alone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: regenerate lockfile against ueberdb2 6.1.2 Now that ether/ueberDB#983 unblocked the publish workflow (OIDC trusted publishing), ueberdb2 6.1.2 is live on npm and the `^6.1.0` pin in src/package.json resolves cleanly. Resolves the ERR_PNPM_OUTDATED_LOCKFILE that was blocking CI on this PR. 29 SessionStore backend tests still green against the published tarball. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Why now
The post-merge publish for #981 failed E404 in run 26279691349 — "The requested resource 'ueberdb2@6.1.1' could not be found or you do not have permission to access it" — the classic shape of a stored token that's expired or had its scope changed. `ep_hljs` hit the same pattern four days ago. Migrating off the stored token is the permanent fix; rotating the token would just defer the problem to the next rotation cycle.
This also unblocks ether/etherpad#7831, whose CI is stuck waiting for ueberdb2 6.1.1 to actually land on npm.
One-time setup required after merge
On https://www.npmjs.com/package/ueberdb2/access:
Same recipe documented at the top of the `publish-npm` job in the workflow.
Test plan
🤖 Generated with Claude Code