Skip to content

fix(ui-scripts): route publish-private to the private registry even when ~/.npmrc has an @instructure scope mapping#2560

Draft
balzss wants to merge 1 commit into
masterfrom
fix-publish-private-scoped-registry
Draft

fix(ui-scripts): route publish-private to the private registry even when ~/.npmrc has an @instructure scope mapping#2560
balzss wants to merge 1 commit into
masterfrom
fix-publish-private-scoped-registry

Conversation

@balzss
Copy link
Copy Markdown
Contributor

@balzss balzss commented May 15, 2026

Summary

ui-scripts publish-private was routing publishes to npmjs when the operator's ~/.npmrc had an @instructure:registry=https://registry.npmjs.org/ mapping (common after any prior npm login against npmjs).

The temp .npmrc that publish-private writes only set the default registry (registry=...). It did not set the scoped mapping (@instructure:registry=...). pnpm's scoped-package resolution checks the scope-specific mapping first, found the operator's npmjs one (inherited from the operator's ~/.npmrc), and silently retargeted the publish to npmjs — where auth then failed with ENEEDAUTH.

Fix

Two defenses in packages/ui-scripts/lib/commands/publish-private.js:

  1. Add @instructure:registry=<INSTUI_PRIVATE_REGISTRY> to the temp .npmrc so pnpm's scoped lookup also points at the private registry. This is the correct fix — it matches the resolution path pnpm actually uses for scoped packages.
  2. Pass --registry=<INSTUI_PRIVATE_REGISTRY> explicitly to pnpm publish and pnpm info. CLI flags override every config source, so the publish lands at the right host even if some other config layer behaves unexpectedly. Belt-and-suspenders.

Auth still flows through the temp .npmrc via NPM_CONFIG_USERCONFIG, matched by host in the //host/:_authToken= line — unchanged.

Test Plan

  • Reproduced the bug locally by writing @instructure:registry=https://registry.npmjs.org/ into a .npmrc and pointing NPM_CONFIG_GLOBALCONFIG at it. Unpatched publish-private routed the publish to npmjs (matching the original failure).
  • Patched publish-private under the same simulated config routed to the configured INSTUI_PRIVATE_REGISTRY instead.
  • One-package smoke test against a real private registry from a machine that has @instructure:registry=https://registry.npmjs.org/ in its ~/.npmrc — confirm the publish lands at the private registry, not npmjs.

🤖 Generated with Claude Code

…hen ~/.npmrc has an @instructure scope mapping

The publish was leaking to npmjs when the operator's ~/.npmrc had a
prior @instructure:registry=https://registry.npmjs.org/ scope mapping
(common after a previous `npm login`). The temp .npmrc only set the
default `registry=` line, so pnpm's scoped-package resolution found
the operator's npmjs mapping first, silently retargeted the publish
to npmjs, and the upload failed with ENEEDAUTH against npmjs while
the configured private registry never saw the request.

Two defenses:
  - Write `@instructure:registry=<INSTUI_PRIVATE_REGISTRY>` into the
    temp .npmrc, so pnpm's scoped lookup also points at the private
    registry
  - Pass `--registry=<INSTUI_PRIVATE_REGISTRY>` explicitly to both
    `pnpm publish` and the `pnpm info` already-published check. CLI
    flags beat every config source, so the publish lands at the right
    host even if any other config layer behaves unexpectedly

Auth still resolves from the temp .npmrc (matched by host in the
`//host/:_authToken=` line).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@balzss balzss force-pushed the fix-publish-private-scoped-registry branch from 920ff40 to 46872f4 Compare May 15, 2026 17:13
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 15, 2026

PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://instructure.design/pr-preview/pr-2560/

Built to branch gh-pages at 2026-05-15 17:19 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 15, 2026

Visual regression report

No changes.

Status Count
Unchanged 32
Changed 0
New 0
Removed 0

📊 View full report

Baselines come from the visual-baselines branch. They refresh on every merge to master.

github-actions Bot pushed a commit that referenced this pull request May 15, 2026
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.

1 participant