Skip to content

refactor(registry): adopt verdaccio-shaped YAML config#11970

Merged
zkochan merged 8 commits into
mainfrom
refactor/registry-verdaccio-yaml-config
May 26, 2026
Merged

refactor(registry): adopt verdaccio-shaped YAML config#11970
zkochan merged 8 commits into
mainfrom
refactor/registry-verdaccio-yaml-config

Conversation

@juanpicado

@juanpicado juanpicado commented May 26, 2026

Copy link
Copy Markdown
Member

Reshape pnpm-registry's Config to match verdaccio's config.yaml schema (storage, uplinks, packages) so the same file can drive either server. The previous Config exposed a single upstream: Option<String> resolved at startup; this replaces it with named uplinks plus per-package proxy: rules walked in declared order — same semantics as verdaccio, minus the surface pnpm-registry does not implement (auth, web, plugins, middlewares, logs routing, secret), which are accepted and ignored.

Highlights:

  • Config { listen, public_url, storage, uplinks, packages, packument_ttl } with UplinkConfig { url } and PackageAccess { access, publish, unpublish, proxy }. packages is an IndexMap walked in declared order, first-match-wins: the first pattern matching a request is the rule that applies, and if that rule has no proxy: the package is storage-only (resolution returns None instead of falling through to a later catch-all). That makes the bundled @private/* / @pnpm.e2e/needs-auth / unscoped-fixture rules behave the way the YAML says they should.
  • Config::from_yaml(path, ...) loads via serde-saphyr and resolves a relative storage: against the config file's parent. The verdaccio-only sections in the YAML are skipped silently so registry-mock's upstream config.yaml parses untouched.
  • DEFAULT_CONFIG_YAML — the bundled file mirrored from @pnpm/registry-mock — is include_str!-ed and re-exported from lib.rs so other crates (tests, benchmarks, future embedders) can use the same defaults without reading from disk. Config::from_default_yaml(base_dir, ...) parses it.
  • CLI: -c / --config <path> overrides the bundled default. --storage survives as a runtime override (handy for tests without a custom YAML); --upstream and --static are gone because the YAML now drives both. --packument-ttl-secs is optional — the loaded config's value wins when the flag is not supplied. The mock orchestrator at pacquet/tasks/registry-mock drops its --upstream flag — that command spawns the locally-built binary so it tracks this PR's source directly. The jest harness at __utils__/jest-config/with-registry/globalSetup.js keeps --upstream for now because CI installs @pnpm/pnpr from npm; the flag will be dropped in the same PR that bumps @pnpm/pnpr to a build that lacks it.
  • server.rs pre-builds one Upstream per declared uplink at router construction (keyed by name, in an IndexMap) and resolves the right client per request via Config::resolve_uplink. No per-request ThrottledClient allocations.

Existing tests are kept working by retaining the Config::proxy / Config::static_serve constructors and switching the test helper from config.upstream = ... to mutating
config.uplinks["npmjs"].url. All 107 tests in pnpm-registry pass (55 unit + 26 + 9 + 17 integration).

Ref: #11973

Summary by CodeRabbit

  • New Features

    • YAML-based registry configuration with package-level routing, multiple uplinks, auth and audit middleware
    • New --config option to load custom registry configs; optional storage override and packument TTL setting
  • Chores

    • Default registry now uses the bundled configuration (web UI disabled by default)
    • Configuration refactor to support Verdaccio-style routing patterns and per-package access/publish rules

Review Change Stack

Copilot AI review requested due to automatic review settings May 26, 2026 20:32
@juanpicado juanpicado requested a review from zkochan as a code owner May 26, 2026 20:32
@coderabbitai

coderabbitai Bot commented May 26, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Replace single-upstream registry config with a Verdaccio-shaped YAML system: bundled default YAML, IndexMap-backed uplinks, ordered per-package routing rules, pattern matching and resolve_uplink, CLI --config loading, server wiring for multiple upstreams, and updated tests/launcher to use uplink URLs.

Changes

Verdaccio-shaped YAML-driven registry configuration

Layer / File(s) Summary
Configuration data model, defaults, and bundled YAML
registry/crates/pnpm-registry/src/config.rs, registry/crates/pnpm-registry/config.yaml, registry/crates/pnpm-registry/Cargo.toml
Adds DEFAULT_CONFIG_YAML, UplinkConfig, PackageAccess, ConfigFile YAML deserialization, from_yaml/from_default_yaml, relative storage resolution, bundled config.yaml, and indexmap dependency.
Package-to-uplink routing and pattern matching
registry/crates/pnpm-registry/src/config.rs
Implements pattern_matches, resolve_relative, and Config::resolve_uplink to evaluate ordered package rules (**, @*/*, @scope/*, exact) and return the matching uplink name and config when proxy is present.
Config tests and YAML parsing coverage
registry/crates/pnpm-registry/src/config.rs tests
Expanded tests cover pattern semantics, storage resolution, YAML parsing, declared-order package evaluation, public_url defaulting/override, and error mapping for malformed/missing YAML.
CLI, launcher args, and runtime overrides
registry/crates/pnpm-registry/src/main.rs, pacquet/tasks/registry-mock/src/pnpm_registry_command.rs, __utils__/jest-config/with-registry/globalSetup.js
CLI adds --config (YAML) and makes --storage optional; main loads Config::from_yaml or from_default_yaml and applies runtime overrides (storage, packument TTL); mock launcher drops explicit --upstream and relies on bundled default YAML.
Server multi-uplink resolution and per-request selection
registry/crates/pnpm-registry/src/server.rs
AppInner holds an IndexMap of named Upstream instances built from config.uplinks; resolve_upstream selects per-package upstream via config.resolve_uplink; tarball, packument loading, and search augmentation use per-package resolution and handle missing proxy rules.
Tests updated to use uplinks
registry/crates/pnpm-registry/tests/*
Tests that previously set config.upstream now mutate config.uplinks["npmjs"].url to point at mock upstreams; assertions remain unchanged.

Sequence Diagram

sequenceDiagram
  participant Client
  participant RegistryServer
  participant npmjs as npmjsUplink
  Client->>RegistryServer: request package metadata / tarball (package name)
  RegistryServer->>RegistryServer: Config::resolve_uplink(package)
  alt proxy rule found
    RegistryServer->>npmjs: proxy request to uplink URL
    npmjs-->>RegistryServer: proxied response
    RegistryServer-->>Client: return proxied response
  else no proxy rule
    RegistryServer-->>Client: return local response / 404
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • pnpm/pnpm#11898: Earlier pnpm-registry/mock launcher work that used an explicit --upstream flag and touches the same registry config/wiring.

"A rabbit hops through YAML fields and streams,
Bundled defaults humming in registry dreams,
Uplinks named, patterns checked with care,
Per-package routing now runs everywhere,
Tests and launcher follow the newfound schemes."

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main refactoring: adopting a Verdaccio-shaped YAML configuration for the registry module.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/registry-verdaccio-yaml-config

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Review Summary by Qodo

Adopt verdaccio-shaped YAML config with named uplinks and package routing

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Reshape Config to match verdaccio's YAML schema (storage, uplinks, packages)
• Replace single upstream field with named uplinks and per-package proxy rules
• Add YAML parsing via serde-saphyr with relative path resolution
• Bundle verdaccio-shaped config.yaml and expose via DEFAULT_CONFIG_YAML
• Update CLI: add -c/--config flag, remove --upstream and --static flags
• Pre-build upstreams at router construction, resolve per-request via pattern matching
Diagram
flowchart LR
  A["Config YAML<br/>storage, uplinks, packages"] -->|parse| B["ConfigFile struct"]
  B -->|resolve paths| C["Config struct<br/>uplinks IndexMap<br/>packages IndexMap"]
  C -->|build routers| D["AppState<br/>upstreams IndexMap"]
  E["Package request"] -->|resolve_uplink| F["Pattern matching<br/>first-match wins"]
  F -->|lookup| D
  D -->|fetch| G["Upstream client"]

Loading

Grey Divider

File Changes

1. registry/crates/pnpm-registry/src/config.rs ✨ Enhancement +212/-27

Reshape Config to verdaccio schema with uplinks and packages

registry/crates/pnpm-registry/src/config.rs


2. registry/crates/pnpm-registry/src/lib.rs ✨ Enhancement +1/-1

Export new config types and bundled YAML constant

registry/crates/pnpm-registry/src/lib.rs


3. registry/crates/pnpm-registry/src/main.rs ✨ Enhancement +20/-26

Update CLI to use YAML config with new flags

registry/crates/pnpm-registry/src/main.rs


View more (6)
4. registry/crates/pnpm-registry/src/server.rs ✨ Enhancement +24/-6

Pre-build upstreams and resolve per-request via patterns

registry/crates/pnpm-registry/src/server.rs


5. registry/crates/pnpm-registry/Cargo.toml Dependencies +2/-0

Add indexmap and serde-saphyr dependencies

registry/crates/pnpm-registry/Cargo.toml


6. registry/crates/pnpm-registry/config.yaml ⚙️ Configuration changes +73/-0

Add bundled verdaccio-shaped configuration file

registry/crates/pnpm-registry/config.yaml


7. registry/crates/pnpm-registry/tests/server.rs 🧪 Tests +5/-1

Update test helper to use uplinks IndexMap

registry/crates/pnpm-registry/tests/server.rs


8. registry/crates/pnpm-registry/tests/auth_publish.rs 🧪 Tests +2/-2

Update test config mutations to use uplinks

registry/crates/pnpm-registry/tests/auth_publish.rs


9. pacquet/tasks/registry-mock/src/pnpm_registry_command.rs ✨ Enhancement +4/-2

Remove --upstream flag, rely on bundled config

pacquet/tasks/registry-mock/src/pnpm_registry_command.rs


Grey Divider

Qodo Logo

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
registry/crates/pnpm-registry/src/config.rs (1)

240-254: 💤 Low value

@*/* pattern matches malformed scoped names without a slash.

The @*/* pattern is documented as matching "all scoped packages", but the check name.starts_with('@') would also match malformed inputs like @foo (no slash). Verdaccio's actual behavior requires the full @scope/name structure.

♻️ Proposed fix to tighten the match
     if pattern == "@*/*" {
-        return name.starts_with('@');
+        return name.starts_with('@') && name.contains('/');
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@registry/crates/pnpm-registry/src/config.rs` around lines 240 - 254, The
pattern_matches function's handling of the "@*/*" pattern is too permissive
because it returns true for any name starting with '@' (e.g., "`@foo`"); update
pattern_matches so the "@*/*" branch checks that name has a proper scoped form
(starts with '@' and contains a '/' with non-empty scope and package segments)
before returning true; modify the "@*/*" check in pattern_matches to validate
the presence of a slash and that both scope and package portions are non-empty
(use existing name parsing helpers or explicit checks) so only well-formed
"`@scope/name`" strings match.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@registry/crates/pnpm-registry/src/config.rs`:
- Around line 240-254: The pattern_matches function's handling of the "@*/*"
pattern is too permissive because it returns true for any name starting with '@'
(e.g., "`@foo`"); update pattern_matches so the "@*/*" branch checks that name has
a proper scoped form (starts with '@' and contains a '/' with non-empty scope
and package segments) before returning true; modify the "@*/*" check in
pattern_matches to validate the presence of a slash and that both scope and
package portions are non-empty (use existing name parsing helpers or explicit
checks) so only well-formed "`@scope/name`" strings match.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fe3cb2d4-8557-4de7-a483-67a9336e49ae

📥 Commits

Reviewing files that changed from the base of the PR and between 89c2b52 and 413789a.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • pacquet/tasks/registry-mock/src/pnpm_registry_command.rs
  • registry/crates/pnpm-registry/Cargo.toml
  • registry/crates/pnpm-registry/config.yaml
  • registry/crates/pnpm-registry/src/config.rs
  • registry/crates/pnpm-registry/src/lib.rs
  • registry/crates/pnpm-registry/src/main.rs
  • registry/crates/pnpm-registry/src/server.rs
  • registry/crates/pnpm-registry/tests/auth_publish.rs
  • registry/crates/pnpm-registry/tests/server.rs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Agent
  • GitHub Check: Code Coverage
  • GitHub Check: Lint and Test (windows-latest)
  • GitHub Check: Lint and Test (ubuntu-latest)
  • GitHub Check: Lint and Test (macos-latest)
  • GitHub Check: Run benchmark on ubuntu-latest
  • GitHub Check: Run benchmark on ubuntu-latest
🧰 Additional context used
📓 Path-based instructions (4)
registry/crates/**/Cargo.toml

📄 CodeRabbit inference engine (registry/AGENTS.md)

registry/crates/**/Cargo.toml: When using existing pacquet-* crates, declare them in the root [workspace.dependencies] and use { workspace = true } in the crate's Cargo.toml
New registry-only crates must be placed under registry/crates// and named pnpm-registry- in Cargo.toml, with the package name using the pnpm-registry- prefix exclusively
Do not reach for the pacquet- prefix to name new registry-side crates; use pnpm-registry- prefix exclusively for registry-only crates

Files:

  • registry/crates/pnpm-registry/Cargo.toml
registry/**/Cargo.toml

📄 CodeRabbit inference engine (registry/AGENTS.md)

Add new registry-only crates to [workspace.dependencies] at the root with the pnpm-registry- prefix so other crates can use { workspace = true }

Files:

  • registry/crates/pnpm-registry/Cargo.toml
registry/crates/**/*.rs

📄 CodeRabbit inference engine (registry/AGENTS.md)

Follow the pacquet code-style guide (../pacquet/CODE_STYLE_GUIDE.md) for Rust-level conventions including imports, naming, ownership, error handling, and test layout

Files:

  • registry/crates/pnpm-registry/src/lib.rs
  • registry/crates/pnpm-registry/tests/auth_publish.rs
  • registry/crates/pnpm-registry/src/main.rs
  • registry/crates/pnpm-registry/tests/server.rs
  • registry/crates/pnpm-registry/src/server.rs
  • registry/crates/pnpm-registry/src/config.rs
pacquet/**/*.rs

📄 CodeRabbit inference engine (pacquet/AGENTS.md)

pacquet/**/*.rs: When porting a function that fires pnpm:<channel> events through globalLogger, logger.debug(), or streamParser.write(), mirror the call site, payload, and ordering so the reporter parses pacquet's NDJSON the same way it parses pnpm's.
Declare a newtype wrapper for branded string types. Do not collapse the brand into a plain String or &str.
If upstream always validates before construction, validate in pacquet's wrapper too. The wrapper must construct only via TryFrom<String> and/or FromStr. Do not provide an infallible public constructor.
If upstream never validates, just brand for type-safety. Expose an infallible From<String> (and From<&str> when convenient).
If upstream occasionally constructs without validation, expose from_str_unchecked as an escape hatch alongside the validating constructor.
Match upstream serde behavior for branded types that cross JSON, YAML, or INI boundaries. Use #[serde(try_from = "String")] for deserialization and #[serde(into = "String")] for serialization.
Use #[derive(derive_more::From)] and #[derive(derive_more::Into)] for mechanical conversion impls. Fall back to manual impl only when conversion needs custom logic.
String-literal unions should become enums, not newtype wrappers. Model closed sets of valid string values as enums.
Template literal types should be treated as branded strings with validation discipline from rules 2-5.
Choose owned vs. borrowed parameters to minimize copies. Widen to the most encompassing type (&Path over &PathBuf, &str over &String) when it doesn't force extra copies.
Prefer Arc::clone(&x) / Rc::clone(&x) over x.clone() for reference-counted types, so the cost is visible at the call site.
Follow Rust API Guidelines for naming conventions.
Do not use star imports inside module bodies. Write use super::{Foo, bar} instead of use super::*;. Two forms stay allowed: external-crate preludes like use rayon::prelude::*; and root-of-module re-...

Files:

  • pacquet/tasks/registry-mock/src/pnpm_registry_command.rs
🧠 Learnings (1)
📚 Learning: 2026-05-20T23:07:58.444Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11784
File: pacquet/crates/resolving-deps-resolver/src/hoist_peers.rs:120-133
Timestamp: 2026-05-20T23:07:58.444Z
Learning: When reviewing code in this pacquet Rust port, follow the upstream pnpm compatibility rule: only match pnpm’s behavior exactly. Do not propose review changes that intentionally deviate from pnpm’s documented/observed behavior, even if pnpm appears buggy. If you identify a real bug in pnpm behavior, the review should prioritize fixing it upstream in pnpm first, and avoid implementing a pnpm-behavior workaround here unless the same fix has already landed upstream.

Applied to files:

  • pacquet/tasks/registry-mock/src/pnpm_registry_command.rs
🔇 Additional comments (17)
registry/crates/pnpm-registry/src/config.rs (8)

1-9: LGTM!


10-16: LGTM!


18-58: LGTM!


60-77: LGTM!


79-93: LGTM!


95-137: LGTM!


138-218: LGTM!


220-232: LGTM!

registry/crates/pnpm-registry/config.yaml (1)

1-73: LGTM!

registry/crates/pnpm-registry/Cargo.toml (1)

28-32: LGTM!

registry/crates/pnpm-registry/src/lib.rs (1)

22-22: LGTM!

registry/crates/pnpm-registry/src/main.rs (2)

1-8: LGTM!

Also applies to: 10-38


40-60: LGTM!

registry/crates/pnpm-registry/src/server.rs (1)

9-10: LGTM!

Also applies to: 47-50, 66-70, 74-74, 450-452, 718-720, 1066-1074, 1088-1094

registry/crates/pnpm-registry/tests/server.rs (1)

17-21: LGTM!

registry/crates/pnpm-registry/tests/auth_publish.rs (1)

678-678: LGTM!

Also applies to: 722-722

pacquet/tasks/registry-mock/src/pnpm_registry_command.rs (1)

86-89: LGTM!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors pnpm-registry to load Verdaccio-shaped YAML configuration for storage, uplinks, and package proxy routing, replacing the previous single-upstream CLI-driven configuration.

Changes:

  • Adds YAML-backed Config parsing with ordered uplinks and packages.
  • Updates server routing to prebuild and resolve named upstreams per request.
  • Adjusts CLI/tests/mock launcher wiring for the new config model.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
registry/crates/pnpm-registry/src/config.rs Adds Verdaccio-shaped config structs, YAML loading, default config inclusion, and package uplink resolution.
registry/crates/pnpm-registry/src/server.rs Replaces single upstream with named prebuilt upstreams resolved from package rules.
registry/crates/pnpm-registry/src/main.rs Adds --config, changes storage override handling, and removes old upstream/static CLI flags.
registry/crates/pnpm-registry/src/lib.rs Re-exports new config types and bundled YAML constant.
registry/crates/pnpm-registry/config.yaml Adds bundled default Verdaccio-shaped registry configuration.
registry/crates/pnpm-registry/Cargo.toml Adds indexmap and serde-saphyr dependencies.
registry/crates/pnpm-registry/tests/server.rs Updates test helper to mutate the default npmjs uplink URL.
registry/crates/pnpm-registry/tests/auth_publish.rs Updates upstream-based search tests for the new uplink config shape.
pacquet/tasks/registry-mock/src/pnpm_registry_command.rs Stops passing --upstream and relies on bundled config defaults.
Cargo.lock Records new pnpm-registry dependencies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread registry/crates/pnpm-registry/src/config.rs Outdated
Comment on lines +13 to +16
/// Path to a verdaccio-shaped YAML config (storage, uplinks,
/// packages). When omitted, the bundled default config is used.
#[arg(short = 'c', long)]
config: Option<PathBuf>,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 59f4b41: dropped the --upstream arg from __utils__/jest-config/with-registry/globalSetup.js. The bundled config already declares the npmjs uplink at https://registry.npmjs.org/, which is what that line was supplying. The PNPM_REGISTRY_MOCK_UPLINK env hatch had no other call sites in the repo, so dropping it is safe — callers needing a non-npmjs uplink can use -c <yaml>.


Written by an agent (Claude Code, claude-opus-4-7).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted in 722b17f after a closer look. CI installs @pnpm/pnpr from npm — the pinned 0.0.0-26052601 build still accepts --upstream (with a default of https://registry.npmjs.org), so passing the flag from globalSetup.js against that binary works fine; clap does not reject it. The Rust source change in this PR doesn't affect the binary CI actually runs.

Dropping --upstream from globalSetup.js now would be cosmetic until a new @pnpm/pnpr is published from this PR's source. Keeping it avoids a flag-rejection break the moment that release ships, so the cleanup will land in the same PR that bumps @pnpm/pnpr. pacquet/tasks/registry-mock still drops its --upstream — that command spawns target/release/pnpm-registry, which is this PR's source, so the drop there is required and stays.


Written by an agent (Claude Code, claude-opus-4-7).

@github-actions

github-actions Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Micro-Benchmark Results

Linux

group                          main                                   pr
-----                          ----                                   --
tarball/download_dependency    1.02      8.0±0.37ms   545.5 KB/sec    1.00      7.8±0.48ms   557.1 KB/sec

@codecov-commenter

codecov-commenter commented May 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.42379% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.04%. Comparing base (e55f4b5) to head (722b17f).

Files with missing lines Patch % Lines
registry/crates/pnpm-registry/src/main.rs 0.00% 12 Missing ⚠️
registry/crates/pnpm-registry/src/config.rs 98.77% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #11970      +/-   ##
==========================================
+ Coverage   87.95%   88.04%   +0.08%     
==========================================
  Files         228      228              
  Lines       27819    28068     +249     
==========================================
+ Hits        24469    24713     +244     
- Misses       3350     3355       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Integrated-Benchmark Report (Linux)

Scenario: Isolated linker: fresh restore, cold cache + cold store

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 2.046 ± 0.132 1.894 2.276 1.03 ± 0.07
pacquet@main 1.990 ± 0.060 1.898 2.109 1.00
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 2.04641976048,
      "stddev": 0.13230352685673397,
      "median": 2.00886275598,
      "user": 2.7690584599999997,
      "system": 3.27427718,
      "min": 1.8941216784800001,
      "max": 2.27560470648,
      "times": [
        2.19494284948,
        2.18929069148,
        1.8941216784800001,
        1.96304181848,
        2.06060241848,
        1.9739672594800002,
        1.9039771224800002,
        2.27560470648,
        2.04375825248,
        1.96489080748
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 1.99042432908,
      "stddev": 0.05964330241993459,
      "median": 1.99351534698,
      "user": 2.7995307599999997,
      "system": 3.2682464800000006,
      "min": 1.8982688334800002,
      "max": 2.10873127248,
      "times": [
        2.01026400148,
        1.9055676824800003,
        2.01742422248,
        1.9734471874800001,
        1.8982688334800002,
        1.98843499248,
        1.98461148548,
        2.10873127248,
        1.99859570148,
        2.01889791148
      ]
    }
  ]
}

Scenario: Isolated linker: fresh restore, hot cache + hot store

Command Mean [ms] Min [ms] Max [ms] Relative
pacquet@HEAD 671.9 ± 19.5 642.5 704.4 1.00
pacquet@main 717.9 ± 52.2 684.0 858.9 1.07 ± 0.08
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 0.6718605823400001,
      "stddev": 0.01947773224080718,
      "median": 0.6706701212400001,
      "user": 0.3693597599999999,
      "system": 1.38071646,
      "min": 0.6425196082400001,
      "max": 0.70438528824,
      "times": [
        0.70438528824,
        0.6736634852400001,
        0.6569794402400001,
        0.70269734924,
        0.6425196082400001,
        0.6730745382400001,
        0.6594730522400001,
        0.67693390224,
        0.6682657042400001,
        0.66061345524
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 0.71791405304,
      "stddev": 0.052152984641406254,
      "median": 0.69670688924,
      "user": 0.37974206,
      "system": 1.34897496,
      "min": 0.6840368262400001,
      "max": 0.8589381462400001,
      "times": [
        0.8589381462400001,
        0.7290523492400001,
        0.68799670824,
        0.69588894924,
        0.7312810402400001,
        0.6903772732400001,
        0.69562080624,
        0.69752482924,
        0.6840368262400001,
        0.70842360224
      ]
    }
  ]
}

Scenario: Isolated linker: fresh install, cold cache + cold store

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 2.356 ± 0.058 2.228 2.433 1.02 ± 0.03
pacquet@main 2.308 ± 0.044 2.243 2.387 1.00
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 2.3563851950199997,
      "stddev": 0.05771201846787757,
      "median": 2.35209543212,
      "user": 3.86961964,
      "system": 3.05091266,
      "min": 2.22775194762,
      "max": 2.43262212162,
      "times": [
        2.39409691662,
        2.31733042862,
        2.40372963562,
        2.35630224962,
        2.43262212162,
        2.40037268862,
        2.34133511662,
        2.34788861462,
        2.34242223062,
        2.22775194762
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 2.3077030498199997,
      "stddev": 0.04384544801158406,
      "median": 2.29604525612,
      "user": 3.94387774,
      "system": 3.0461457599999995,
      "min": 2.24287622062,
      "max": 2.38671265262,
      "times": [
        2.30148601362,
        2.2871954686200002,
        2.27231628662,
        2.33800197262,
        2.24287622062,
        2.32836505662,
        2.27344993062,
        2.38671265262,
        2.35602239762,
        2.29060449862
      ]
    }
  ]
}

Scenario: Isolated linker: fresh install, hot cache + hot store

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 1.505 ± 0.023 1.474 1.533 1.01 ± 0.03
pacquet@main 1.490 ± 0.032 1.428 1.540 1.00
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 1.5054859187400003,
      "stddev": 0.02272088716276475,
      "median": 1.50473686694,
      "user": 1.7590028,
      "system": 1.91499362,
      "min": 1.47403630794,
      "max": 1.53311207094,
      "times": [
        1.51870721594,
        1.52026369394,
        1.5320247199400001,
        1.53311207094,
        1.48544724294,
        1.49076651794,
        1.5271587929400001,
        1.47403630794,
        1.48618591394,
        1.4871567109400001
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 1.49002647074,
      "stddev": 0.03169171534239999,
      "median": 1.48729215994,
      "user": 1.7866272000000003,
      "system": 1.8384866199999998,
      "min": 1.42799833694,
      "max": 1.54036523994,
      "times": [
        1.42799833694,
        1.4902426879400001,
        1.54036523994,
        1.5025294949399999,
        1.4838913229400001,
        1.48131369094,
        1.52123421294,
        1.5097976179400001,
        1.48434163194,
        1.45855047094
      ]
    }
  ]
}

@github-actions

github-actions Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

🐰 Bencher Report

Branchpr/11970
Testbedpacquet
Click to view all benchmark results
BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
isolated-linker.fresh-install.cold-cache.cold-store📈 view plot
🚷 view threshold
2,356.39 ms
(-12.08%)Baseline: 2,680.22 ms
3,216.27 ms
(73.26%)
isolated-linker.fresh-install.hot-cache.hot-store📈 view plot
🚷 view threshold
1,505.49 ms
(-16.93%)Baseline: 1,812.37 ms
2,174.84 ms
(69.22%)
isolated-linker.fresh-restore.cold-cache.cold-store📈 view plot
🚷 view threshold
2,046.42 ms
(-0.29%)Baseline: 2,052.38 ms
2,462.85 ms
(83.09%)
isolated-linker.fresh-restore.hot-cache.hot-store📈 view plot
🚷 view threshold
671.86 ms
(+2.32%)Baseline: 656.60 ms
787.92 ms
(85.27%)
🐰 View full continuous benchmarking report in Bencher

Copilot AI review requested due to automatic review settings May 26, 2026 21:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.

Comment thread registry/crates/pnpm-registry/src/config.rs Outdated
juanpicado and others added 3 commits May 26, 2026 23:20
Reshape pnpm-registry's Config to match verdaccio's `config.yaml`
schema (storage, uplinks, packages) so the same file can drive
either server. The previous Config exposed a single
`upstream: Option<String>` resolved at startup; this replaces it
with named uplinks plus per-package `proxy:` rules walked in
declared order — same semantics as verdaccio, minus the surface
pnpm-registry does not implement (auth, web, plugins,
middlewares, logs routing, secret), which are accepted and
ignored.

Highlights:

  * `Config { listen, public_url, storage, uplinks, packages,
    packument_ttl }` with `UplinkConfig { url }` and
    `PackageAccess { access, publish, unpublish, proxy }`.
    `packages` is an `IndexMap` so first-match wins in declared
    order — `**` cannot accidentally shadow `@*/*`.
  * `Config::from_yaml(path, ...)` loads via `serde-saphyr` and
    resolves a relative `storage:` against the config file's
    parent. The verdaccio-only sections in the YAML are skipped
    silently so `registry-mock`'s upstream `config.yaml` parses
    untouched.
  * `DEFAULT_CONFIG_YAML` — the bundled file mirrored from
    `@pnpm/registry-mock` — is `include_str!`-ed and re-exported
    from `lib.rs` so other crates (tests, benchmarks, future
    embedders) can use the same defaults without reading from
    disk. `Config::from_default_yaml(base_dir, ...)` parses it.
  * CLI: `-c` / `--config <path>` overrides the bundled default.
    `--storage` survives as a runtime override (handy for tests
    without a custom YAML); `--upstream` and `--static` are gone
    because the YAML now drives both. The mock orchestrator at
    `pacquet/tasks/registry-mock` drops its `--upstream` flag —
    the bundled config already declares the `npmjs` uplink.
  * `server.rs` pre-builds one `Upstream` per declared uplink at
    router construction (keyed by name, in an `IndexMap`) and
    resolves the right client per request via
    `Config::resolve_uplink`. No per-request `ThrottledClient`
    allocations.

Existing tests are kept working by retaining the `Config::proxy`
/ `Config::static_serve` constructors and switching the test
helper from `config.upstream = ...` to mutating
`config.uplinks["npmjs"].url`. All 38 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zkochan zkochan force-pushed the refactor/registry-verdaccio-yaml-config branch from f04f62e to 548869f Compare May 26, 2026 21:20

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@registry/crates/pnpm-registry/src/main.rs`:
- Around line 36-37: The CLI arg packument_ttl_secs is defined with a default
and thus always overwrites the YAML packument_ttl; change the CLI arg
declaration (packument_ttl_secs) to be an Option<u64> (no default) and update
the code that applies config so you only set the runtime packument_ttl when
packument_ttl_secs.is_some(), leaving the YAML packument_ttl intact when the CLI
flag is not provided; refer to the packument_ttl_secs argument and the place
where packument_ttl from the YAML config is assigned/overwritten in main.rs to
implement this conditional assignment.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d5e5264f-e753-4a9f-bb29-a0e522ce3a21

📥 Commits

Reviewing files that changed from the base of the PR and between f04f62e and 548869f.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • pacquet/tasks/registry-mock/src/pnpm_registry_command.rs
  • registry/crates/pnpm-registry/Cargo.toml
  • registry/crates/pnpm-registry/config.yaml
  • registry/crates/pnpm-registry/src/config.rs
  • registry/crates/pnpm-registry/src/lib.rs
  • registry/crates/pnpm-registry/src/main.rs
  • registry/crates/pnpm-registry/src/server.rs
  • registry/crates/pnpm-registry/tests/auth_publish.rs
  • registry/crates/pnpm-registry/tests/server.rs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Run benchmark on ubuntu-latest
  • GitHub Check: Code Coverage
  • GitHub Check: Run benchmark on ubuntu-latest
  • GitHub Check: Lint and Test (ubuntu-latest)
  • GitHub Check: Lint and Test (windows-latest)
  • GitHub Check: Lint and Test (macos-latest)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Compile & Lint
🧰 Additional context used
📓 Path-based instructions (4)
registry/crates/**/*.rs

📄 CodeRabbit inference engine (registry/AGENTS.md)

Follow the pacquet code-style guide (../pacquet/CODE_STYLE_GUIDE.md) for Rust-level conventions including imports, naming, ownership, error handling, and test layout

Files:

  • registry/crates/pnpm-registry/src/lib.rs
  • registry/crates/pnpm-registry/tests/server.rs
  • registry/crates/pnpm-registry/src/server.rs
  • registry/crates/pnpm-registry/src/main.rs
  • registry/crates/pnpm-registry/tests/auth_publish.rs
  • registry/crates/pnpm-registry/src/config.rs
registry/crates/**/Cargo.toml

📄 CodeRabbit inference engine (registry/AGENTS.md)

registry/crates/**/Cargo.toml: When using existing pacquet-* crates, declare them in the root [workspace.dependencies] and use { workspace = true } in the crate's Cargo.toml
New registry-only crates must be placed under registry/crates// and named pnpm-registry- in Cargo.toml, with the package name using the pnpm-registry- prefix exclusively
Do not reach for the pacquet- prefix to name new registry-side crates; use pnpm-registry- prefix exclusively for registry-only crates

Files:

  • registry/crates/pnpm-registry/Cargo.toml
registry/**/Cargo.toml

📄 CodeRabbit inference engine (registry/AGENTS.md)

Add new registry-only crates to [workspace.dependencies] at the root with the pnpm-registry- prefix so other crates can use { workspace = true }

Files:

  • registry/crates/pnpm-registry/Cargo.toml
pacquet/**/*.rs

📄 CodeRabbit inference engine (pacquet/AGENTS.md)

pacquet/**/*.rs: When porting a function that fires pnpm:<channel> events through globalLogger, logger.debug(), or streamParser.write(), mirror the call site, payload, and ordering so the reporter parses pacquet's NDJSON the same way it parses pnpm's.
Declare a newtype wrapper for branded string types. Do not collapse the brand into a plain String or &str.
If upstream always validates before construction, validate in pacquet's wrapper too. The wrapper must construct only via TryFrom<String> and/or FromStr. Do not provide an infallible public constructor.
If upstream never validates, just brand for type-safety. Expose an infallible From<String> (and From<&str> when convenient).
If upstream occasionally constructs without validation, expose from_str_unchecked as an escape hatch alongside the validating constructor.
Match upstream serde behavior for branded types that cross JSON, YAML, or INI boundaries. Use #[serde(try_from = "String")] for deserialization and #[serde(into = "String")] for serialization.
Use #[derive(derive_more::From)] and #[derive(derive_more::Into)] for mechanical conversion impls. Fall back to manual impl only when conversion needs custom logic.
String-literal unions should become enums, not newtype wrappers. Model closed sets of valid string values as enums.
Template literal types should be treated as branded strings with validation discipline from rules 2-5.
Choose owned vs. borrowed parameters to minimize copies. Widen to the most encompassing type (&Path over &PathBuf, &str over &String) when it doesn't force extra copies.
Prefer Arc::clone(&x) / Rc::clone(&x) over x.clone() for reference-counted types, so the cost is visible at the call site.
Follow Rust API Guidelines for naming conventions.
Do not use star imports inside module bodies. Write use super::{Foo, bar} instead of use super::*;. Two forms stay allowed: external-crate preludes like use rayon::prelude::*; and root-of-module re-...

Files:

  • pacquet/tasks/registry-mock/src/pnpm_registry_command.rs
🧠 Learnings (1)
📚 Learning: 2026-05-20T23:07:58.444Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11784
File: pacquet/crates/resolving-deps-resolver/src/hoist_peers.rs:120-133
Timestamp: 2026-05-20T23:07:58.444Z
Learning: When reviewing code in this pacquet Rust port, follow the upstream pnpm compatibility rule: only match pnpm’s behavior exactly. Do not propose review changes that intentionally deviate from pnpm’s documented/observed behavior, even if pnpm appears buggy. If you identify a real bug in pnpm behavior, the review should prioritize fixing it upstream in pnpm first, and avoid implementing a pnpm-behavior workaround here unless the same fix has already landed upstream.

Applied to files:

  • pacquet/tasks/registry-mock/src/pnpm_registry_command.rs
🔇 Additional comments (15)
registry/crates/pnpm-registry/src/lib.rs (1)

22-22: LGTM!

registry/crates/pnpm-registry/src/server.rs (1)

9-9: LGTM!

Also applies to: 47-50, 66-70, 74-74, 450-452, 718-719, 1066-1074, 1088-1094

pacquet/tasks/registry-mock/src/pnpm_registry_command.rs (1)

86-89: LGTM!

registry/crates/pnpm-registry/Cargo.toml (1)

28-28: LGTM!

Also applies to: 32-32

registry/crates/pnpm-registry/config.yaml (1)

1-73: LGTM!

registry/crates/pnpm-registry/src/config.rs (8)

1-16: LGTM!


18-58: LGTM!


60-77: LGTM!


79-93: LGTM!


95-139: LGTM!


141-220: LGTM!


222-256: LGTM!


258-472: LGTM!

registry/crates/pnpm-registry/tests/auth_publish.rs (1)

678-678: LGTM!

Also applies to: 722-722

registry/crates/pnpm-registry/tests/server.rs (1)

17-17: LGTM!

Comment thread registry/crates/pnpm-registry/src/main.rs Outdated
Match verdaccio's first-match-wins semantics: when a `packages` pattern
matches but has no `proxy:`, the package is storage-only — resolution
stops there and returns `None` instead of falling through to a later
catch-all. Without this, storage-only rules in the bundled config
(`@private/*`, `plugin-example`, the unscoped fixtures, etc.) were
silently being proxied to npm via the `**` rule. Also drop the
`--upstream` flag from the jest globalSetup; the bundled config already
declares the `npmjs` uplink with the same URL.

---
Written by an agent (Claude Code, claude-opus-4-7).
Copilot AI review requested due to automatic review settings May 26, 2026 21:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

zkochan added 2 commits May 26, 2026 23:29
`perfectionist::macro-argument-binding` rejects impure expressions
passed directly into a macro because macros may evaluate their args
more than once. Bind `path.display()` to a local first so the format
call sees a single, already-evaluated value.

---
Written by an agent (Claude Code, claude-opus-4-7).
---
Written by an agent (Claude Code, claude-opus-4-7).
Copilot AI review requested due to automatic review settings May 26, 2026 21:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
registry/crates/pnpm-registry/src/config.rs (1)

220-220: ⚡ Quick win

Consider validating proxy name references.

If a package rule specifies a proxy name that doesn't exist in uplinks, this returns None silently. While this might be intentional for graceful degradation, a misconfigured proxy name (e.g., typo) could be difficult to debug since packages would silently fall back to storage-only mode.

Consider adding a validation pass or debug logging to warn when a referenced proxy name is not found in the uplinks map.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@registry/crates/pnpm-registry/src/config.rs` at line 220, The lookup
self.uplinks.get_key_value(proxy_name).map(|(k, v)| (k.as_str(), v)) can
silently return None for a misspelled or missing proxy; add validation and a
debug/warn when a package rule references a proxy name not present in
self.uplinks. Modify the code path in config.rs (the uplinks lookup) to check
for existence (e.g., match or if let) and emit a process-level warning or a
logger call identifying the missing proxy_name and the affected package/rule
context, or return a Result/Err so callers (where package rules are processed)
can surface an error; ensure the message includes the proxy_name and the rule
identifier for easier debugging.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@registry/crates/pnpm-registry/src/config.rs`:
- Line 220: The lookup self.uplinks.get_key_value(proxy_name).map(|(k, v)|
(k.as_str(), v)) can silently return None for a misspelled or missing proxy; add
validation and a debug/warn when a package rule references a proxy name not
present in self.uplinks. Modify the code path in config.rs (the uplinks lookup)
to check for existence (e.g., match or if let) and emit a process-level warning
or a logger call identifying the missing proxy_name and the affected
package/rule context, or return a Result/Err so callers (where package rules are
processed) can surface an error; ensure the message includes the proxy_name and
the rule identifier for easier debugging.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cf959742-09fe-4722-b760-fbf137bb25e7

📥 Commits

Reviewing files that changed from the base of the PR and between 548869f and 59f4b41.

📒 Files selected for processing (2)
  • __utils__/jest-config/with-registry/globalSetup.js
  • registry/crates/pnpm-registry/src/config.rs
💤 Files with no reviewable changes (1)
  • utils/jest-config/with-registry/globalSetup.js
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Run benchmark on ubuntu-latest
  • GitHub Check: Lint and Test (windows-latest)
  • GitHub Check: Lint and Test (ubuntu-latest)
  • GitHub Check: Lint and Test (macos-latest)
  • GitHub Check: Code Coverage
  • GitHub Check: Run benchmark on ubuntu-latest
  • GitHub Check: Compile & Lint
🧰 Additional context used
📓 Path-based instructions (1)
registry/crates/**/*.rs

📄 CodeRabbit inference engine (registry/AGENTS.md)

Follow the pacquet code-style guide (../pacquet/CODE_STYLE_GUIDE.md) for Rust-level conventions including imports, naming, ownership, error handling, and test layout

Files:

  • registry/crates/pnpm-registry/src/config.rs
🔇 Additional comments (7)
registry/crates/pnpm-registry/src/config.rs (7)

1-16: LGTM!


18-93: LGTM!


95-139: LGTM!


141-205: LGTM!


207-222: LGTM!


224-258: LGTM!


260-475: LGTM!

The clap default was unconditionally clobbering config.packument_ttl on
every run, defeating any value the loaded config supplies. Make the
flag `Option<u64>` and only override when the caller passed one.

---
Written by an agent (Claude Code, claude-opus-4-7).
…w binary

CI installs @pnpm/pnpr from npm; the pinned 0.0.0-26052601 build still
accepts --upstream (with a default), so dropping the flag here is
premature. Defer the change to the same PR that bumps @pnpm/pnpr to a
version built from this PR's source. pacquet/tasks/registry-mock keeps
its drop because that command spawns the locally-built binary.

---
Written by an agent (Claude Code, claude-opus-4-7).
Copilot AI review requested due to automatic review settings May 26, 2026 21:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@zkochan zkochan merged commit f03dc2d into main May 26, 2026
28 checks passed
@zkochan zkochan deleted the refactor/registry-verdaccio-yaml-config branch May 26, 2026 21:52
@zkochan zkochan mentioned this pull request May 27, 2026
zkochan added a commit to marvinhagemeister/pnpm that referenced this pull request May 29, 2026
…rop --upstream

Two fixes for the pnpm CLI test harness:

- @pnpm/testing.registry-mock imported @pnpm/network.fetch and
  @pnpm/registry-access.client at module top, which transitively load
  @pnpm/core-loggers/@pnpm/logger. Helpers like @pnpm/testing.command-defaults
  import this module's constants and are pulled in statically by tests before
  they call jest.unstable_mockModule('@pnpm/logger') — so the logger was loaded
  before the mock, breaking it (e.g. exec.logs' recursive-prefix test saw 0
  lifecycleLogger.debug calls). Import those deps lazily inside addDistTag/addUser.

- globalSetup no longer passes --upstream: the pnpm-registry binary dropped that
  flag in pnpm#11970 (uplink is configured via the bundled verdaccio-shaped config,
  which already proxies npmjs).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants