* refactor(pnpr): rename pnpm-registry to pnpr
Rename the registry server across the board to match the npm wrapper
package name, which was already `@pnpm/pnpr`.
- crate `pnpm-registry` -> `pnpr`, `pnpm-registry-fixtures` -> `pnpr-fixtures`
- binaries `pnpm-registry` -> `pnpr`, `pnpm-registry-prepare` -> `pnpr-prepare`
- module paths and log targets `pnpm_registry::*` -> `pnpr::*`
- binary-locating env vars `PNPM_REGISTRY_BIN` -> `PNPR_BIN`,
`PNPM_REGISTRY_PREPARE_BIN` -> `PNPR_PREPARE_BIN`
- top-level directory `registry/` -> `pnpr/` (crates, npm wrapper, fixtures)
The registry-mock storage concept is intentionally left as-is:
`PNPM_REGISTRY_MOCK_PORT`/`PNPM_REGISTRY_MOCK_STORAGE`/`PNPM_REGISTRY_STORAGE`,
the `~/.cache/pnpm-registry/storage` path + benchmark cache keys, and the
external `pnpm-registry-mock` npm package referenced in test fixtures.
* style(pnpr): rustfmt import grouping after rename
* ci(pnpr): point typos at pnpr instead of removed registry dir
* chore(pnpr): update pre-push path filter from registry to pnpr
Replace the external `@pnpm/registry-mock` (Verdaccio) test dependency with an in-repo, in-process registry that serves package fixtures to **both** the pacquet Rust tests and the pnpm CLI (Jest) tests. No separately managed registry process is needed.
### How it works
- **Fixtures** live at `registry/.fixtures/packages/<name>/<version>/…`, moved verbatim from [`pnpm/registry-mock`](https://github.com/pnpm/registry-mock) (keyed by each `package.json`'s `name`+`version`).
- **`pnpm-registry-fixtures`** builds verdaccio-shaped storage from those fixtures; the in-tree **`pnpm-registry`** crate serves it.
- Files whose names differ only by case (`@pnpm.e2e/with-same-file-in-different-cases`) and `bundleDependencies` trees are composed **in memory** by the builder, since neither can be committed to the working tree.
- **pacquet**: `pacquet-testing-utils`' `TestRegistry` starts the server lazily (once per process) in proxy mode, serving `@pnpm.e2e` fixtures locally and falling through to the npm uplink for real packages (`is-positive`, `is-negative`, …) — matching how registry-mock behaved.
- **pnpm CLI**: the `with-registry` Jest `globalSetup` builds storage from the fixtures via the new `pnpm-registry-prepare` binary (built from source in the Test CI job) and serves it with `pnpm-registry`. `REGISTRY_MOCK_PORT` / `REGISTRY_MOCK_CREDENTIALS` / `getIntegrity` now come from `@pnpm/testing.registry-mock`.
### Result
`@pnpm/registry-mock` is removed from every manifest, the catalog, and `packageExtensions`; `cargo test` / `cargo nextest run` / `just test` and the pnpm CLI Jest suites all run registry-backed tests without launching Verdaccio.
The e2e/integration test harness spawns `pnpm-registry` as a faster
verdaccio replacement. CI used to install Rust and build the crate
from source on every test job — adding several minutes per platform.
`@pnpm/pnpr` now publishes the prebuilt binary to npm, and `pnpm install`
already pulls in the matching `@pnpm/pnpr.<platform>-<arch>` package
via optionalDependencies. The Jest globalSetup resolves that binary
through `@pnpm/pnpr/bin/pnpr`'s own module path (the wrapper carries
the platform packages as siblings in its `node_modules`, not on the
parent chain of this file).
- Add `@pnpm/pnpr` to `pnpm-workspace.yaml` catalog and depend on it
from `@pnpm/jest-config`.
- Replace `resolvePnpmRegistryBin`'s `$CARGO_TARGET_DIR` lookup with
`require.resolve` through the npm-installed wrapper. The
`PNPM_REGISTRY_BIN` env var is still honored as an escape hatch for
contributors who want to point at a locally-built Rust binary.
- Remove the "Install Rust toolchain" + "Build pnpm-registry" steps
from `.github/workflows/test.yml`.
---
Written by an agent (Claude Code, claude-opus-4-7).
Lands the pieces of the npm registry protocol that pnpm-registry was missing, and switches the TypeScript test harness off verdaccio onto pnpm-registry. `@pnpm/registry-mock` (the npm package) is untouched.
### Server-side additions (`registry/crates/pnpm-registry`)
- `PUT /-/user/org.couchdb.user:<name>` — adduser / login, returns a Bearer token. In-memory user + token stores.
- `PUT /:pkg` — publish (scoped + unscoped). Base64-decodes `_attachments`, merges into the existing packument, writes manifest + tarball atomically. 100 MiB body limit.
- `GET /-/package/:pkg/dist-tags` + `PUT/DELETE /-/package/:pkg/dist-tags/:tag` — rewrites the on-disk packument so tag changes survive a restart.
- `Authorization: Bearer` and `Authorization: Basic` both identify the caller.
- Per-package access policy (wax glob patterns). Defaults mirror `@pnpm/registry-mock`'s `config.yaml`: `@private/*` and `@pnpm.e2e/needs-auth` require auth; everything else is anonymous read, authenticated write. Enforced on every packument / version-manifest / tarball GET and every write endpoint.
### TypeScript-test migration
- `__utils__/jest-config/with-registry/globalSetup.js` keeps `prepare()` from `@pnpm/registry-mock` (still needed for the tempy storage path written into the runtime-config yaml — `getIntegrity` reads it from there) but spawns `pnpm-registry` instead of verdaccio. `addUser`, `addDistTag`, `getIntegrity`, `REGISTRY_MOCK_*` from registry-mock work as-is — they're plain npm-wire-protocol HTTP calls.
- Binary lookup follows pacquet's pattern: `PNPM_REGISTRY_BIN` env override, then `target/release/pnpm-registry`, then `target/debug/pnpm-registry`.
- CI test job (`.github/workflows/test.yml`) installs the Rust toolchain via the existing `./.github/actions/rustup` composite action and builds `pnpm-registry --release` before tests run. Per-platform — Linux and Windows in the matrix each build their own.
Without an explicit shell, the step ran under PowerShell on
windows-latest, where `$TEST_SCRIPT` is not a variable (PowerShell
exposes env vars as `$env:TEST_SCRIPT`). `pn run ""` then exited 0
and just listed available scripts — the Windows test legs have been
silently no-op'ing since the env-var move in #11608.
The sibling `Verify Node version` and `Determine test scope` steps
already pin `shell: bash`; this brings `Run tests` in line.
---
Written by an agent (Claude Code, claude-opus-4-7).
Adds the Garnet network-monitoring action to the smoke test job, the
release workflow, and the npm tag workflow. The full CI test matrix is
left untouched to keep per-job overhead off the broad cross-platform
runs; the smoke test still exercises a representative install/test flow.
Resolves all 30 zizmor alerts reported on main after #11607:
- template-injection (19): move `${{ ... }}` interpolations in `run:` blocks
to `env:` so untrusted-ish values (workflow_dispatch inputs, github.ref_name,
github.actor) can't break out of shell quoting.
- artipacked (8): add `persist-credentials: false` to `actions/checkout` in
audit, benchmark, ci, codeql-analysis, docker, release, test workflows.
`update-lockfile.yml` keeps the persisted token (later step pushes to a
branch) with a `zizmor: ignore[artipacked]` comment and justification.
- dependabot-cooldown (1): add a 7-day cooldown so brand-new (potentially
malicious) Actions releases don't get auto-PR'd day-of-release.
- ref-version-mismatch (1): `bluwy/release-for-reddit-action` SHA pointed at
the `v2` tag, not a non-existent `v2.0.0`. Fix the comment.
- superfluous-actions (1): mark `softprops/action-gh-release` with a
`zizmor: ignore` and justification — the release pipeline is sensitive and
the action is battle-tested; we're not swapping it for `gh release` here.
Verified locally with `zizmor --persona regular .github` (online audits on):
No findings to report. Good job! (2 ignored, 32 suppressed)
---
Written by an agent (Claude Code, claude-opus-4-7).
## Summary
Migrates CI workflows from `pnpm/action-setup` + manual `pn runtime set node …` + `pn install` to the new combined `pnpm/setup` action (see https://github.com/pnpm/setup/pull/1).
`pnpm/setup` installs pnpm and the JS runtime in one step. It also runs `pnpm install` automatically when a `package.json` is present, so per-workflow install steps are dropped. When the `runtime` input is set, the action passes `--no-runtime` to `pnpm install` so the matrix-selected Node version isn't shadowed by a different `devEngines.runtime` pin.
## What changed
| Workflow | Migration |
|---|---|
| `test.yml` | `pnpm/setup` with `runtime: node@${{ inputs.node }}`. Verify-Node step asserts the matrix version stayed active. Verify-npm step retained as canary (npm comes from the runner image, not the pnpm-installed runtime). |
| `ci.yml` | `pnpm/setup` (no `runtime` input — `devEngines.runtime` in package.json handles the Node pin). |
| `release.yml` | `pnpm/setup` with `runtime: node@26.0.0`. |
| `benchmark.yml` | `pnpm/setup` with `runtime: node@26.0.0`. |
| `audit.yml` | `pnpm/setup` with `install: false` — audit only needs pnpm itself, not `node_modules`. |
| `update-lockfile.yml` | `pnpm/setup` with `install: false` — the job deletes `pnpm-lock.yaml` and regenerates it via `--lockfile-only`, so the action's auto-install would be wasted. |
| `update-latest.yml` | Untouched — it only uses npm, no pnpm setup needed. |
## Caveats / things to watch
- **npm availability.** `pnpm runtime set node` does not extract npm. The runner image's pre-installed Node toolchain provides `npm` on PATH; if a future runner image change removes that, dlx-style git-hosted dependency tests in `test.yml` will fail. The `Verify npm` step in `test.yml` is the canary.
## Related upstream change
- [pnpm/setup#3](https://github.com/pnpm/setup/pull/3) — added the `install` input so callers like `audit.yml` and `update-lockfile.yml` can opt out of the action's auto-install.
Adds `devEngines.runtime` to pin the Node.js version (24.6.0, `onFail: download`) the project uses for development, so contributors don't have to manage Node versions manually.
CI changes that come with it:
- Bumps pnpm to **11.1.1** and `pnpm/action-setup` to a bootstrap that ships `@zkochan/cmd-shim` 9.0.3. The cmd-shim update is required because the previous shim's `exec cmd /C` got mangled by Git Bash's MSYS path conversion (`/C` → Windows path), which broke any `pn …` invocation from `shell: bash` on Windows.
- Switches the install step to `pn install --no-runtime` so the per-test-matrix Node version chosen by `pn runtime -g set node …` isn't overridden by the project-pinned 24.6.0.
- Adds a `Verify Node version` step that asserts `pn node -v` matches the matrix's Node.
* fix: ensure PNPM_HOME/bin is in PATH during pnpm setup
When upgrading from old pnpm (global bin = PNPM_HOME) to new pnpm
(global bin = PNPM_HOME/bin), `pnpm setup` would fail because the
spawned `pnpm add -g` checks that the global bin dir is in PATH.
Prepend PNPM_HOME/bin to PATH in the spawned process env so the
check passes during the transition.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: update pnpm to v11 beta 2
* chore: update pnpm to v11 beta 2
* chore: update pnpm to v11 beta 2
* chore: update pnpm to v11 beta 2
* fix: lint
* refactor: rename _-prefixed scripts to .-prefixed scripts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: update root package.json to use .test instead of _test
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ci: update action-setup
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ci: run Linux/Node 24 tests first, then the rest of the matrix
Run tests on ubuntu-latest / Node.js 24 as a smoke test first.
The remaining 5 matrix combinations only start if it passes,
saving CI resources on failing PRs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(ci): extract test steps into reusable workflow
Reduces duplication by moving all test steps into test.yml as a
reusable workflow. ci.yml now calls it twice: once for the smoke
test (Linux/Node 24) and once for the remaining matrix.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(ci): remove redundant if conditions from dependent jobs
The if condition only needs to be on compile-and-lint. Downstream
jobs are automatically skipped when their needs are skipped.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(ci): clean up check names for reusable workflow
Drop redundant "Test" prefix from caller job names since the
reusable workflow job key "test" is automatically appended by
GitHub, e.g. "CI / ubuntu-latest / Node.js 24 / test".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style(ci): capitalize Test in reusable workflow job name
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>