[Investigation] CI infrastructure failures — npm public-registry slowdown - #19928
[Investigation] CI infrastructure failures — npm public-registry slowdown#19928Mitch Denny (mitchdenny) wants to merge 2 commits into
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 19928Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 19928" |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
This diagnostic-only PR is explicitly marked as not for merge.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Balanced
Findings: None
What changed in this PR
Diagnostic-only PR adding whitespace to trigger CI; it is explicitly not intended for merge.
Changes:
- Adds a blank line to
README.md.
| File | Description |
|---|---|
README.md |
Adds trailing whitespace to trigger CI. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
…ot CI Targets job:polyglot so the PR exercises the TypeScript SDK Validation job that is currently failing, for infrastructure diagnosis. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Investigation findingsTL;DR — this is an npm problem, not a NuGet problem. Regression window
Evidence 1 — the hang is exactly at
|
| Invocation | Registry | Duration |
|---|---|---|
Docker global install (explicit --registry) |
pkgs.dev.azure.com/dnceng/.../dotnet-public-npm |
8s ✅ |
| Guest AppHost project install (default registry) | registry.npmjs.org |
2m21s |
| Next guest install (default registry) | registry.npmjs.org |
killed at 120s, exit 143 ❌ |
#8 8.045 added 8 packages, and changed 1 package in 8s <-- dnceng mirror
[00:33:30] Executing: /usr/local/bin/npm install
[00:35:51] typescript/nodejs guest process 491 exited with code 0 <-- 2m21s, default registry
[00:35:53] Executing: /usr/local/bin/npm install
[00:37:51] Cancellation requested while waiting for ... process 572
[00:37:51] typescript/nodejs guest process 572 exited with code 143
❌ Failed to install TypeScript (Node.js) dependencies.
❌ Timed out waiting 120s for AppHost to start.
The dnceng npm mirror is fast; the public registry is not. That is the whole bug.
Why only generated/TypeScript apps are affected
The repo pins the internal mirror at the root:
./.npmrc registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/
./extension/.npmrc (same)
But the templates ship no .npmrc, and generated apps are created outside the repo (/tmp/Aspire.Deployment.EndToEnd.Tests/Workspace/...), so they never inherit that config and fall back to registry.npmjs.org. That is precisely why in-repo npm work (extension build, markdownlint) is unaffected while every generated TypeScript AppHost stalls.
Hypotheses checked and ruled out
- NuGet network-isolation lockdown — no evidence. All sources in
NuGet.configare dnceng (pkgs.dev.azure.com/dnceng.pkgs.visualstudio.com); there is no publicapi.nuget.orgfeed. Restores succeed, and observedNotFoundresponses are just normal package-source-mapping fallthrough before a successful install fromdotnet-eng. Deployment-test NuGet restore completed in 1.1s. - npm.js outage — not per the status page.
status.npmjs.orgreports All Systems Operational, no active incidents. The only recent incident (Intermittent Failures Impacting npm Publish, Sep 3 21:42→23:21Z) was publish-only and resolved ~4h before run33832301417. So this is degradation/throttling not reflected on the status page, or egress filtering on the runners. docs/ci/copilot-agent-firewall.md(commit9395ca9e63, Sep 3 19:20) — red herring. It documents a probe for the Copilot coding-agent shell, not GitHub Actions runners, and is docs-only.- A repo regression — unlikely. No commit in the regression window touches the guest/TypeScript
npm installpath. AzureSandboxesfailure — separate issue. It fails atWaitUntil("success prompt [5 OK] $")after 7m17s, unrelated to npm.
Registry reachability from a non-CI network is healthy for both (registry.npmjs.org ~0.08–2.9s, dnceng mirror ~1.9s), reinforcing that the slowness is specific to the CI egress path.
Suggested mitigation
Point generated AppHosts at the internal mirror instead of the public registry, e.g. ship an .npmrc with the TypeScript templates or set npm_config_registry in the environment the CLI passes to the guest runtime (GuestAppHostProject.InstallDependenciesAsync). That both fixes CI and removes a hard runtime dependency on npmjs.org — the same isolation posture already applied to NuGet. Raising the 120s timeout would only mask it.
Verification in flight
- Full deployment E2E run on
main:33834532243 - This PR touches a TypeScript polyglot fixture so
job:polyglotruns the failing TypeScript SDK Validation job directly.
Correction / refinement on the suggested mitigationMy earlier suggestion — "point generated AppHosts at the internal dnceng mirror" — was too glib. There is a deliberate design decision that says the opposite, and it should not be reversed casually.
/// The canonical public npm registry URL. Commands that resolve, pack, or install
/// packages pass this explicitly via <c>--registry</c> so resolution and install use
/// the public feed and cannot inherit a project-level <c>.npmrc</c> that redirects to a
/// private feed (for example an Azure DevOps Artifacts feed). Such a private feed would
/// otherwise return 401 for packages (including transitive dependencies) it has not
/// mirrored, breaking <c>aspire agent init</c>.
/// See https://github.com/microsoft/aspire/issues/19370.
private const string PublicRegistry = "https://registry.npmjs.org/";So the CLI intentionally forces Worth noting the two npm paths are distinct:
Both therefore land on the public registry. The dependency is by design, not by accident. Revised options
I'd suggest (1) + (2): confirm with GitHub whether runner egress to I have not made any product change in this PR — it remains whitespace-only for diagnosis. |
Tests selector0 / 99 PR test projects · 1 PR job · 0 advisory-only targets, from 1 changed file. Selected PR test projects (0 / 99)none — no PR-gated .NET test projects run for this change. Selected PR jobs (1)
Advisory workflow impact (0)none How these were chosen — grouped by what changedJob reasons
Selection computed for commit |
Full deployment run — reproduced, plus an important refinementFull deployment E2E run on 31 of 46 deploy jobs passed, 7 failed, 8 still running at time of writing. The failure set is stable and reproducible across three independent runs. Refinement: the stall is intermittent, not a uniform slowdownI need to correct an implication in my first comment. It is not the case that npm is uniformly slow — the same
The heavy install (112 packages, real network work) finished in 4s. The following install stalled indefinitely with zero npm output. And it is not positional either — in So: any given What this meansThis is consistent with intermittent network stalls to The core conclusions from my first comment stand:
Still opennpm emits no output at all when it stalls, so I can't yet say which request hangs (tarball fetch, metadata, or the audit endpoint). Confirming that needs Recommendation is unchanged from my previous comment: raise the runner-egress question with GitHub, and independently make the guest dependency install retry with a configurable timeout so a stalled connection degrades gracefully instead of failing the run outright. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
Reproduced on this PR — decisive evidenceThe The log captures three
Same command, same machine, same registry, same minutes: 3m53s / 33s / >120s. For reference, on the last green run the equivalent sequence was 4s / 709ms / 468ms. That is the whole story. Summary of the investigationConfirmed
Refuted
Unrelated
Suggested next steps
This PR is diagnostic only — no product code changed. Happy to open a separate PR for the retry/timeout hardening in (2) if that's wanted. |
Final tally — full deployment run
|
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
Purpose
Whitespace-only commit to trigger CI so we can observe and diagnose current infrastructure failures.
Not for merge. Diagnostic vehicle only — no product code is changed.
Conclusion
This is an npm problem, not a NuGet problem.
npm installagainst the public registry (registry.npmjs.org) has become drastically slow from CI runners — ~2m21s vs the normal ~4s — so every Aspire path that shells out tonpm installblows its 120s timeout. NuGet restore is healthy (1.1s in the same failing job) and there is no evidence of a NuGet network-isolation lockdown.The decisive evidence is two
npm installcalls minutes apart inside the same CI container:--registry)dotnet-public-npmmirrorregistry.npmjs.orgregistry.npmjs.orgGenerated apps are created outside the repo (
/tmp/...), so they never inherit the repo's dnceng.npmrcand fall back to the public registry — which is why in-repo npm work (extension build, markdownlint) is unaffected while every generated TypeScript AppHost stalls.Ruled out: NuGet isolation lockdown, an npm.js status-page incident (the only recent one was publish-only and resolved ~4h earlier), the Copilot agent firewall doc, and any repo regression in the window.
AzureSandboxesis a separate, unrelated failure.Full detail, log excerpts and the regression window are in the comments below, along with a correction on mitigation: the CLI deliberately pins the public registry (
NpmRunner.cs, see #19370) because the private mirror 401s on unmirrored transitive dependencies — so redirecting to the mirror is not a safe fix.Verification
main:33834532243job:polyglotexercises the failing TypeScript SDK Validation job directly.