Skip to content

Commit 8b43c38

Browse files
debugmcpdevcynarlabclaude
authored
docs(release): a trusted publisher is a release-day step, npm expires unvalidated configs after 48 h (#888)
Since 2026-10-02 npm expires a newly created trusted publisher 48 hours after creation unless a publish validates it; an expired entry stays listed but cannot authorize or be edited, and only a delete-and-recreate gives a fresh window. release.yml cannot validate one on its own: the CLI version comes from the tag ref and every package publishes by its package.json version, so only a real tag does. The checklist said to configure the trusted publisher right after a new package's first hand publish, and to configure publishers as a post-release follow-up. Both now say the opposite: create the configuration within 48 hours before the tag push, and after the run confirm it validated (_npmUser shows GitHub Actions (trustedPublisher)). The comment above the publish step in release.yml says the same, next to the first-publish rule it already carries. Found on @debugmcp/adapter-dart (#790): its first version was published by hand, its trusted publisher was created the same evening, and #887 tracks recreating it on release day. Claude-Session: https://claude.ai/code/session_01Mk4YHZHY5rw5cUsQG1tVxB Co-authored-by: JF <john.franklin@gmail.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
1 parent e44f1fe commit 8b43c38

2 files changed

Lines changed: 7 additions & 4 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,10 @@ jobs:
396396
# publisher only to a package that already exists (npm/cli#8544), and staged
397397
# publishing cannot create one either. A new package needs one first publish
398398
# by hand (with 2FA) or with a temporary token, then a trusted publisher,
399-
# before it joins these steps (docs/release-checklist.md).
399+
# before it joins these steps (docs/release-checklist.md). npm expires an
400+
# unvalidated trusted publisher 48 hours after creation, and only a publish
401+
# from this workflow validates it, so the configuration is a release-day
402+
# step: create it within 48 hours before the tag, not weeks ahead.
400403
#
401404
# CodeLLDB platform packages (issue #383) go first so the CLI's
402405
# optionalDependencies always resolve. They are versioned by the CodeLLDB

‎docs/release-checklist.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ Pre-release validation for mcp-debugger. Run `npm run release:dry-run` to automa
2020
### Manual
2121
- [ ] **Changelog fragments collated** — run `pnpm changelog:collate` **first**. It folds every `changelog.d/*.md` into `[Unreleased]`, creating category headings in Keep a Changelog order, and deletes the fragments. `pnpm run release:dry-run` fails if any fragment is left uncollated (#546)
2222
- [ ] **CHANGELOG reconciled against git history** — run `git log --oneline v<prev>..HEAD --no-merges` and confirm every user-visible merge appears under `[Unreleased]` (dependency bumps and pure test/CI-internal changes may be omitted deliberately), and that the section has no duplicate `### Fixed`/`### Added` headers. Since #546 the CI gate requires a fragment on every user-visible PR, so this is now a verification rather than a catch-up — but entries merged **before** #546 are not covered by the gate (#462)
23-
- [ ] **npm trusted publishing configured** — every published `@debugmcp/*` package (the 10 repo-versioned packages and the 5 `codelldb-<platform>` packages) must have a trusted publisher at npmjs.com → package Settings → Trusted Publisher (GitHub Actions; org/user: `debugmcp`, repo: `mcp-debugger`, workflow: `release.yml`, environment: blank). These packages publish token-free via OIDC; a publish without this config fails (404/permission error) — configure, then re-run via workflow_dispatch.
24-
- [ ] **First-time packages** — `release.yml` has no token path: npm attaches a trusted publisher only to a package that already exists (npm/cli#8544), and staged publishing cannot create one either. Before tagging a release that introduces a new package, publish its first version once by hand with 2FA (`npm publish --access public` from a Linux or macOS checkout, so executable bits survive), or with a short-lived granular token in a one-off workflow, then configure its trusted publisher. After that, the release publishes it like every other package.
23+
- [ ] **npm trusted publishing configured** — every published `@debugmcp/*` package (the 10 repo-versioned packages and the 5 `codelldb-<platform>` packages) must have a trusted publisher at npmjs.com → package Settings → Trusted Publisher (GitHub Actions; org/user: `debugmcp`, repo: `mcp-debugger`, workflow: `release.yml`, environment: blank). These packages publish token-free via OIDC; a publish without this config fails (404/permission error) — configure, then re-run via workflow_dispatch. **A newly created configuration expires 48 hours after creation unless a publish validates it** (npm, since 2026-10-02): it stays listed but can no longer authorize or be edited, and the only fix is to delete it and create a new one, which starts a fresh 48-hour window. Create or recreate a configuration within 48 hours **before** the tag push, never weeks ahead.
24+
- [ ] **First-time packages** — `release.yml` has no token path: npm attaches a trusted publisher only to a package that already exists (npm/cli#8544), and staged publishing cannot create one either. Before tagging a release that introduces a new package, publish its first version once by hand with 2FA (`npm publish --access public` from a Linux or macOS checkout, so executable bits survive), or with a short-lived granular token in a one-off workflow. The hand publish can happen any time; the trusted publisher cannot: because an unvalidated configuration expires after 48 hours, create it within 48 hours before the tag push, as a step of release day. Only a real tag validates it — `release.yml` takes the CLI version from the tag ref and publishes every package by its `package.json` version, so there is no one-package dispatch. After that first OIDC publish, the release publishes it like every other package.
2525
- [ ] **Docker Hub credentials** — `DOCKER_USERNAME` and `DOCKER_PASSWORD` secrets are current
2626
- [ ] **PyPI trusted publishing configured** — `debug-mcp-server-launcher` has a trusted publisher at pypi.org → project Settings → Publishing (GitHub Actions; owner: `debugmcp`, repo: `mcp-debugger`, workflow: `release.yml`, environment: blank). Publishing is token-free via OIDC with PEP 740 attestations; no `PYPI_TOKEN` secret is needed.
2727
- [ ] `release.yml` default ref updated to current tag (for workflow_dispatch reruns)
@@ -58,4 +58,4 @@ Pre-release validation for mcp-debugger. Run `npm run release:dry-run` to automa
5858
- [ ] Verify the pi package surface: on a machine with pi 0.99+ (a scratch `PI_CODING_AGENT_DIR` keeps your own config untouched), `pi install npm:@debugmcp/mcp-debugger@x.y.z`, then `pi list` shows the package, and `/mcp` in a session shows `mcp-debugger` connected with 29 tools (`mcp__mcp_debugger__*`, deferred) — registered by the package's extension (#841)
5959
- [ ] **Website content review** — audit https://debugmcp.io against what this release shipped (language matrix, tool count, feature claims, comparison table) and update `debugmcp/website`
6060
- [ ] Update `SECURITY.md` supported-versions table if a new minor line started (should have happened pre-tag)
61-
- [ ] First-publish follow-up: configure trusted publishers for any packages that just had their first release (see Manual section above)
61+
- [ ] First-publish follow-up: for any package whose trusted publisher was created for this release, confirm the configuration validated — `npm view @debugmcp/<pkg>@x.y.z _npmUser` shows `GitHub Actions (trustedPublisher)`. A hand-published first version does not validate it; if the run skipped the package, the configuration expires 48 hours after creation and must be recreated before the next tag (see Manual section above)

0 commit comments

Comments
 (0)