Skip to content

fix(config): align scoped registry resolution between config get and publish#11494

Merged
zkochan merged 4 commits into
mainfrom
fix/11492
May 6, 2026
Merged

fix(config): align scoped registry resolution between config get and publish#11494
zkochan merged 4 commits into
mainfrom
fix/11492

Conversation

@zkochan
Copy link
Copy Markdown
Member

@zkochan zkochan commented May 6, 2026

Summary

Fixes #11492.

In pnpm v11 a scoped registry resolved to different URLs depending on which command read it:

  • pnpm config get @<scope>:registry returned the value from .npmrc
  • pnpm publish used the value from pnpm-workspace.yaml's registries block

When the two sources disagreed, pnpm publish silently targeted the URL from pnpm-workspace.yaml, even though pnpm config get reported a different (and seemingly authoritative) URL — so users could publish to the wrong registry without any indication.

This PR makes pnpm config get @<scope>:registry read from the merged Config.registries map (the same map publish and the resolvers use) before falling back to authConfig. Both commands now report and use the same URL.

Test plan

  • New config.commands test covering config get @scope:registry returning the merged value when pnpm-workspace.yaml overrides .npmrc.
  • New config.reader regression test confirming pnpm-workspace.yaml's registries overrides the same scope from .npmrc.
  • Manual verification with the bundled CLI: config get @my-org:registry now returns the same URL pnpm publish PUTs to.

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

Summary by CodeRabbit

  • Bug Fixes

    • Fixed scoped registry resolution so pnpm-workspace.yaml values correctly override .npmrc for the same scope.
  • Improvements

    • Improved pnpm config get to report registry URLs consistently with publish/resolvers and emit a warning when workspace and local registry values differ.
  • Tests

    • Added tests covering scoped registry precedence and resolved URL formatting.

…publish (#11492)

`pnpm config get @<scope>:registry` now reports the same URL that
`pnpm publish` and the resolvers actually use. Previously `config get`
only read `.npmrc`, while `publish`/install used the merged
`Config.registries` map (where pnpm-workspace.yaml's `registries`
overrides `.npmrc`), so the two could diverge silently and a publish
would go to the wrong registry.

Also warn at config load when the same scope (or the default registry)
is defined in both `.npmrc` and `pnpm-workspace.yaml` with different
values.
Copilot AI review requested due to automatic review settings May 6, 2026 12:55
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7f44511a-a7c9-4bee-bc38-dca5a697e368

📥 Commits

Reviewing files that changed from the base of the PR and between 3234c10 and 3331d69.

📒 Files selected for processing (1)
  • pnpm/test/config/get.ts

📝 Walkthrough

Walkthrough

Aligns pnpm config get with pnpm publish by resolving scoped registry keys from the merged registries map (e.g., pnpm-workspace.yaml), and emits a warning when the same scope has different registry values between .npmrc and pnpm-workspace.yaml.

Changes

Scoped Registry Config Resolution Alignment

Layer / File(s) Summary
Config Reading / Tests
config/reader/test/index.ts
Adds test asserting pnpm-workspace.yaml registries override the same scope in .npmrc.
Core Command Logic
config/commands/src/configGet.ts
lookupConfig now checks opts._config.registries for keys that start with @ and end with :registry, returning the merged workspace registry when present.
Command Tests
config/commands/test/configGet.test.ts, pnpm/test/config/get.ts
Adds/updates tests to expect the workspace-defined scoped registry (including trailing-slash normalization) when config get is called for scoped registries.
Release Notes / Changeset
.changeset/scoped-registry-config-get-publish.md
Adds a changeset marking two packages as patches and documents that pnpm config get @<scope>:registry now reports the same registry URL used by publish/resolvers and that a warning is emitted for conflicting values.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

"I sniffed the configs in the burrow deep,
Workspace wins where scopes would stray;
No more surprises in the publish sweep,
I hop, I cheer, the registries play. 🥕"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: aligning scoped registry resolution between config get and publish commands to prevent divergent behavior.
Linked Issues check ✅ Passed The PR implements all required objectives from issue #11492: it makes config get read from merged registries map [11492], adds tests for workspace.yaml override behavior [11492], and ensures both commands use the same registry source [11492].
Out of Scope Changes check ✅ Passed All changes are directly related to resolving the scoped registry divergence: code to support scoped registry lookups, test coverage for the override behavior, and expected value updates in existing tests.

✏️ 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 fix/11492

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Microsoft Presidio Analyzer (2.2.362)
pnpm/test/config/get.ts

Microsoft Presidio Analyzer failed to scan this file


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

Comment thread config/reader/test/index.ts Fixed
Comment thread config/reader/test/index.ts Fixed
Comment thread config/reader/test/index.ts Fixed
Comment thread config/reader/test/index.ts Fixed
Avoid the CodeQL warning about unescaped `.` in
`from-npmrc.example.com` regex literals — the assertions only need a
substring check, so use `.toContain()` directly.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 addresses a pnpm v11 inconsistency where pnpm config get @<scope>:registry could report a different registry URL than the one actually used by pnpm publish/resolvers (workspace registries override vs .npmrc). It aligns config get behavior with the merged Config.registries map and adds a user-facing warning when conflicting registry definitions are detected.

Changes:

  • Update pnpm config get @<scope>:registry to prefer the merged Config.registries value (workspace registries + .npmrc) over the raw .npmrc (authConfig) value.
  • Add config-load warnings when the same scope/default registry is defined in both .npmrc and pnpm-workspace.yaml with different URLs.
  • Add tests covering the aligned config get behavior and the new conflict-warning behavior, plus a changeset entry.

Reviewed changes

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

Show a summary per file
File Description
config/reader/src/index.ts Adds conflict-detection warning when workspace registries disagree with .npmrc registries before merging/normalizing.
config/reader/test/index.ts Adds tests for scoped/default registry conflict warnings and “no warning” cases.
config/commands/src/configGet.ts Makes scoped :registry lookups prefer the merged opts._config.registries map.
config/commands/test/configGet.test.ts Adds regression test ensuring config get @scope:registry returns the merged registry value.
.changeset/scoped-registry-config-get-publish.md Documents the behavior change and warning addition as patch releases.

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

Comment thread config/reader/src/index.ts Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
config/reader/test/index.ts (1)

582-586: ⚡ Quick win

Assert that the warning explicitly states which source wins.

These checks confirm both URLs are present, but they don’t lock in the “winner” wording/source. A warning could regress to ambiguous text and still pass.

Suggested test hardening
     const scopeWarning = warnings.find((w) => w.includes('@my-org'))
     expect(scopeWarning).toBeDefined()
     expect(scopeWarning).toContain('https://from-npmrc.example.com/')
     expect(scopeWarning).toContain('https://from-workspace-yaml.example.com/')
+    expect(scopeWarning).toContain('.npmrc')
+    expect(scopeWarning).toContain('pnpm-workspace.yaml')
+    expect(scopeWarning).toContain('takes precedence')

@@
     const defaultWarning = warnings.find((w) => w.includes('default registry'))
     expect(defaultWarning).toBeDefined()
     expect(defaultWarning).toContain('https://from-npmrc.example.com/')
     expect(defaultWarning).toContain('https://from-workspace-yaml.example.com/')
+    expect(defaultWarning).toContain('.npmrc')
+    expect(defaultWarning).toContain('pnpm-workspace.yaml')
+    expect(defaultWarning).toContain('takes precedence')

Also applies to: 605-608

🤖 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 `@config/reader/test/index.ts` around lines 582 - 586, The test currently only
checks that both URLs appear in the scopeWarning (found via warnings.find) which
allows ambiguous wording to slip through; update the assertions to assert the
warning explicitly states which source wins (e.g., contains a clear phrase like
"from-npmrc.example.com wins" or "workspace YAML wins" alongside the winning
URL) so the message is unambiguous, and apply the same stronger assertion
pattern to the analogous assertions around lines 605-608; target the
scopeWarning variable returned by warnings.find and assert the exact winner
wording rather than just presence of both URLs.
🤖 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 `@config/reader/test/index.ts`:
- Around line 582-586: The test currently only checks that both URLs appear in
the scopeWarning (found via warnings.find) which allows ambiguous wording to
slip through; update the assertions to assert the warning explicitly states
which source wins (e.g., contains a clear phrase like "from-npmrc.example.com
wins" or "workspace YAML wins" alongside the winning URL) so the message is
unambiguous, and apply the same stronger assertion pattern to the analogous
assertions around lines 605-608; target the scopeWarning variable returned by
warnings.find and assert the exact winner wording rather than just presence of
both URLs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 189f96ad-76e9-471a-b68b-eb3043dac4eb

📥 Commits

Reviewing files that changed from the base of the PR and between 9372b1d and 9ba5159.

📒 Files selected for processing (1)
  • config/reader/test/index.ts

zkochan added 2 commits May 6, 2026 15:19
A pnpm-workspace.yaml `registries` entry overriding a value from
~/.npmrc is the normal local-over-global precedence, not a footgun
worth surfacing. Now that `pnpm config get @<scope>:registry` reports
the same URL `pnpm publish` uses, the divergence the user noticed in
\#11492 is gone, and an extra warning would just be noise on the
common case.

The regression test that covers `pnpm-workspace.yaml` overriding the
.npmrc value for the same scope stays.
After #11494, `pnpm config get @<scope>:registry` returns the value
from the merged `Config.registries` map — the same URL the resolvers
and `publish` use — which is normalized with a trailing slash. Update
the e2e expectation to match.
Copilot AI review requested due to automatic review settings May 6, 2026 14:29
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 5 out of 5 changed files in this pull request and generated no new comments.

@zkochan zkochan merged commit 7bcfd97 into main May 6, 2026
17 checks passed
@zkochan zkochan deleted the fix/11492 branch May 6, 2026 15:06
zkochan added a commit that referenced this pull request May 6, 2026
…publish (#11494)

Fixes [#11492](#11492).

In pnpm v11 a scoped registry resolved to different URLs depending on which command read it:

- `pnpm config get @<scope>:registry` returned the value from `.npmrc`
- `pnpm publish` used the value from `pnpm-workspace.yaml`'s `registries` block

When the two sources disagreed, `pnpm publish` silently targeted the URL from `pnpm-workspace.yaml`, even though `pnpm config get` reported a different (and seemingly authoritative) URL — so users could publish to the wrong registry without any indication.

This PR makes `pnpm config get @<scope>:registry` read from the merged `Config.registries` map (the same map `publish` and the resolvers use) before falling back to `authConfig`. Both commands now report and use the same URL.
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.

pnpm publish and pnpm config get resolve scoped registries from different sources, causing silent publishes to the wrong registry

3 participants