* fix: setup-trusted-publishers.sh works with real npm trust CLI
Two issues found when running the script for the first time after #7490:
1. `npm trust github --file` wants ONLY the workflow filename basename
(e.g. `test-and-release.yml`), not the full
`.github/workflows/test-and-release.yml` path. npm errors out with
"GitHub Actions workflow must be just a file not a path" otherwise.
Constants updated.
2. `npm trust github` requires 2FA on accounts that have it enabled,
and there is no way to disable that requirement. Add a `--otp <code>`
pass-through flag and forward it to every call so a maintainer can
batch-process multiple packages within a single TOTP window.
Documented the limitation in the script header.
Also reword the call site so the npm command line is built without
shell-string round-tripping (passing $CMD through `$( $CMD )` was
unrelated to this bug but was bad practice).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: setup-trusted-publishers.sh recognizes 409 as already-configured
When --skip-existing is set, treat HTTP 409 Conflict from
POST /-/package/<name>/trust as 'already configured' so re-runs of
the bulk script don't fail on packages that were configured in a
previous run.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: cover setup-trusted-publishers.sh, harden against set -e, document --otp
Addresses qodo review on #7491:
- Add backend regression test that shims `npm` on PATH and asserts
`--file` is given the workflow basename (never a path), `--otp` is
forwarded to every `npm trust github` call when supplied, and the
loop survives a non-zero exit so `--skip-existing` can absorb 409
Conflict responses from the registry.
- Wrap the `npm trust github` invocation in `set +e` / `set -e`. The
`if configure_one` already shields the function from errexit in
practice, but a future refactor moving the call site out of an `if`
would silently reintroduce the bug — the explicit shim makes intent
obvious and survives such refactors.
- Document `--otp` and the 2FA / TOTP-expiry workflow in
doc/npm-trusted-publishing.md so maintainers don't follow the docs
and hit EOTP.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: migrate npm publish to OIDC trusted publishing (#7401)
Replaces NPM_TOKEN-based publishing with npm Trusted Publishing over
OIDC for both etherpad-lite core and the shared plugin publish
template. Tokens no longer expire every 90 days; each publish
authenticates via a short-lived OIDC token issued to the GitHub
Actions runner.
Changes:
- bin/plugins/lib/npmpublish.yml: the reusable workflow propagated to
every ether/ep_* plugin via the update-plugins cron. Now bumps Node
to 22, upgrades npm to >=11.5.1, declares id-token: write, drops
NODE_AUTH_TOKEN, and calls `npm publish --provenance --access public`
directly (not via pnpm/gnpm wrappers, which obscure the npm CLI
version requirement).
- bin/plugins/lib/test-and-release.yml: the parent workflow that calls
npmpublish.yml as a reusable workflow. Top-level and release-job
permissions now grant id-token: write so the OIDC token can flow
into the called workflow.
- .github/workflows/releaseEtherpad.yml: core's own publish workflow
for the ep_etherpad package. Same OIDC migration; keeps the gnpm
install + rename steps but switches the final publish to npm.
- doc/npm-trusted-publishing.md: explains how trusted publishing
works, the one-time per-package setup that has to happen on
npmjs.com, requirements (Node 22.14+, npm 11.5.1+, cloud runners),
and common errors.
The next update-plugins cron run will propagate the new template to
every plugin. Once that lands and the trusted publisher is configured
on npmjs.com per package, the NPM_TOKEN secret can be removed.
Closes#7401
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add bin/setup-trusted-publishers.sh for bulk OIDC config (#7401)
Adds a script that automates the per-package trusted-publisher setup
that previously had to be done by clicking through npmjs.com once for
each of the 80+ ep_* plugins. Uses the new `npm trust github` CLI
(npm >= 11.5.1) so the whole org can be configured in one shot:
npm login
bin/setup-trusted-publishers.sh
The script:
- Discovers every non-archived ether/ep_* repo via `gh repo list`
- Maps ep_etherpad to the etherpad-lite repo / releaseEtherpad.yml,
and every plugin to its same-named repo / test-and-release.yml
- Runs `npm trust github <pkg> --repository <org>/<repo> --file
<workflow> --yes` for each package
- Supports --dry-run, --packages <comma list>, and --skip-existing
- Verifies npm >= 11.5.1 and that the user is logged in before doing
anything destructive
Doc updated to feature the script as the recommended setup path,
with manual web-UI steps kept as a fallback.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: don't bump CI Node version to 22 for OIDC
npm 11.5.1 (the version that ships trusted publishing) actually
requires '^20.17.0 || >=22.9.0', not Node 22.14+. The npm docs
recommend Node 22 but only because that's what bundles a recent
enough npm — installing 'npm@latest' on top of Node 20.17+ works
just as well.
The repo already requires Node >= 20.0.0 in engines.node and the
setup-node@v6 'version: 20' input resolves to the latest 20.x
(currently 20.20+), which satisfies npm 11's range. Revert the CI
publish workflows from node-version: 22 back to 20 so this PR does
not raise the Node bar at all.
Doc updated to explain the actual constraint.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>