Skip to content

Bootstrap pnpm via a registry-honoring fallback when corepack can't reach its metadata endpoint - #1374

Merged
Cedric Vidal (cedricvidal) merged 2 commits into
microsoft:mainfrom
cedricvidal:fix/corepack-npm-registry
Jul 31, 2026
Merged

Cedric Vidal (cedricvidal) merged 2 commits into
microsoft:mainfrom
cedricvidal:fix/corepack-npm-registry

Conversation

@cedricvidal

Copy link
Copy Markdown
Collaborator

Problem

Follow-up to #1373. That PR forwards the host npm registry into the image builds via NPM_CONFIG_REGISTRY, but the pnpm bootstrap still fails on networks that have no route to the public npm registry, for two reasons:

  1. corepack ignores npm_config_registry. It resolves the package manager from its own per-version metadata endpoint, ${registry}/pnpm/<version>. Some private registry proxies serve the full packument (${registry}/pnpm → 200) but return 404 for that per-version document, so corepack prepare errors out (request to …/pnpm/10.29.1 … 404).
  2. Ordering. Forward the host npm registry into docker image builds #1373 placed the NPM_CONFIG_REGISTRY ARG/ENV after the corepack prepare line, so npm_config_registry wasn't even in effect during bootstrap.

Fix

Applied uniformly to all 12 Node Dockerfiles (20 build stages):

ARG NPM_CONFIG_REGISTRY=https://registry.npmjs.org/
ENV npm_config_registry=${NPM_CONFIG_REGISTRY} \
    COREPACK_NPM_REGISTRY=${NPM_CONFIG_REGISTRY}
# corepack bootstraps pnpm from the registry's per-version metadata endpoint,
# which some private registry proxies don't serve; fall back to a pinned global
# install (honors npm_config_registry) so restricted networks can still build.
RUN corepack enable && (corepack prepare [email protected] --activate || npm install -g [email protected] --force)
  • Move the ARG/ENV before the corepack step.
  • Also export COREPACK_NPM_REGISTRY (the variable corepack honors) so it succeeds on proxies that do serve per-version metadata, and fails fast otherwise.
  • Fall back to a pinned npm install -g [email protected] --force when corepack can't reach its endpoint. Plain npm uses the full packument, which proxies do serve. --force is required because corepack enable has already planted a pnpm shim at /usr/local/bin/pnpm (otherwise npm fails with EEXIST).

Impact

The default stays the public registry, so external contributors and CI are unaffected — corepack succeeds and the fallback never runs. The fallback only fires on restricted networks and installs the same pinned pnpm version.

Validation

  • Reproduced the corepack 404 and confirmed the fallback in throwaway node:22.22.0-slim containers against a private proxy.
  • Built the api image standalone (corepack 404 → npm install -g … --force → pnpm install pulled all deps via the proxy → build succeeded).
  • Full docker compose … up --build -d of the dev stack behind the proxy: all services built and came up healthy.

Follow-up to #1373. That change forwards the host npm registry into the
image builds, but the pnpm bootstrap still fails on networks with no
route to the public registry, because:

  * corepack resolves the package manager from its own per-version
    metadata endpoint (`${registry}/pnpm/<version>`). Some private
    registry proxies serve the full packument (`${registry}/pnpm`) but
    return 404 for the per-version document, so corepack errors out.
  * the `NPM_CONFIG_REGISTRY` ARG/ENV were placed *after* the corepack
    step, so `npm_config_registry` was not yet in effect during bootstrap.

Move the ARG/ENV ahead of the corepack step, also export
`COREPACK_NPM_REGISTRY` (the variable corepack honors), and fall back to a
pinned `npm install -g [email protected] --force` when corepack cannot reach
its metadata endpoint. `--force` is required because `corepack enable`
has already planted a pnpm shim at that path.

The default remains the public registry, so external contributors and CI
are unaffected: corepack succeeds and the fallback never runs. The
fallback installs the same pinned pnpm version via the standard packument
endpoint, which proxies do serve.

Co-authored-by: Copilot App <[email protected]>
Co-authored-by: Copilot App <[email protected]>

Copilot-Session: 7f3fabf3-4153-4af7-8b1f-daf6b83f93ca
@github-actions

Copy link
Copy Markdown

Test Results (Node.js 22)

test: Run #30

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Pending ⏳ Other ❓ Flaky 🍂 Duration ⏱️
2602 2602 0 0 0 0 0 2m26s

🎉 All tests passed!

Github Test Reporter

@cedricvidal
Cedric Vidal (cedricvidal) merged commit 129cb92 into microsoft:main Jul 31, 2026
16 checks passed
Cedric Vidal (cedricvidal) added a commit that referenced this pull request Oct 8, 2026
Resolve conflicts with main (#1379, #1373/#1374, #1381, #1385):
- Port main's ACP worker logic into the reusable worker.ts; keep index.ts thin
- Use main's agent-registry admission; keep host checks for resume/bulk-resume
- Pin SCOPE_AGENT_VERSION for host and Docker workers to the registered version
- CLI api-client: main's auth + environment-aware client; SSE sends auth
- Drop Foundry proxy (superseded by #1379) and .scope Dockerfile rewrite
- Regenerate pnpm-lock.yaml and OpenAPI snapshot

Co-authored-by: Copilot App <[email protected]>
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