Skip to content

ci: install .NET and NuGet packages on a faster drive on Windows - #5782

Draft
ric-oliv wants to merge 3 commits into
mainfrom
ci/windows-dotnet-on-workspace-drive
Draft

ric-oliv wants to merge 3 commits into
mainfrom
ci/windows-dotnet-on-workspace-drive

Conversation

@ric-oliv

@ric-oliv ric-oliv commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

The two Windows .NET legs are tied with macOS as the slowest jobs in the build workflow, and about 12 minutes of each goes to Setup Environment and Restore. Linux does the same work in about 4.5.

From the logs of run 39858273561:

  • setup-dotnet takes 97 to 108 seconds on Windows, against 24 to 31 on macOS and Linux.
  • The workload step takes 331 to 338 seconds, against 110 to 122. It installs the workloads as MSI packages, because the images keep .NET under C:\Program Files\dotnet. About 2 of those minutes restore the Android test app, which the Windows solution filters exclude.
  • Restore takes 4.8 to 5.3 minutes, against about 1. NuGet extracts the packages into the user profile on C:.

This PR is an experiment to find out which of those matters:

  • The Windows legs install .NET and keep the NuGet cache next to the workspace, where workloads install as plain files. On win-x64 that also moves them to D:, where the workspace already is. win-arm64 has no D:, so there they stay on C:.
  • If the workload step gets faster on both legs, the MSI install mode was the cost. If Restore only gets faster on win-x64, the drive matters too.
  • Setup Environment skips the Android test app on Windows. That also applies to verify-api and the MSBuild job, which build the same Windows solution filter.

Measured on two runs of this PR, against the median of 7 main runs from October 22 and 23:

main Run 1 Run 2
win-x64 Setup Environment 5.4 min 3.5 3.8
win-x64 Restore 5.4 1.0 1.0
win-x64 job 42.6 34.0 35.5
win-arm64 Setup Environment 8.7 6.9 6.0
win-arm64 Restore 4.9 5.0 3.8
win-arm64 job 43.8 40.5 38.4

Run 1's logs, against run 39858273561, answer the question:

  • Neither leg installs an MSI package anymore. The workload step went from 338 to 100 seconds on win-x64 and from 331 to 194 on win-arm64, so the MSI install mode was a cost on both legs.
  • setup-dotnet went from 97 to 53 seconds and Restore from about 5 minutes to 1 only on win-x64, where the files moved to D:. So the drive is what made those two slow.
  • With a fresh .NET folder, the step no longer updates the image's preinstalled maui-windows and wasm-tools workloads, and the build still passes without them.

win-arm64 stayed the slower Windows leg, because its runner has no D:.

A Dev Drive on win-arm64

A probe, #5798, ran the win-arm64 leg's steps four ways, twice each. These are whole-job minutes, with the unit tests in the foreground:

Run 1 Run 2 Restore Build Integration test
As on main 40.0 44.3 5.5, 4.4 8.9, 11.2 13.8, 15.4
Defender real-time scanning off 35.7 38.5 4.2, 5.2 7.1, 8.6 13.2, 13.7
.NET, NuGet and TEMP on a Dev Drive 33.0 33.0 1.9, 2.1 7.0, 7.1 11.4, 11.2
Also the workspace on the Dev Drive 36.7 45.6 2.6, 4.8 7.7, 9.3 12.4, 13.2
  • The image already excludes C:\ and D:\ from Defender, which is why turning off real-time scanning saved little.
  • The Dev Drive reports no file system filters attached, and creating it takes about 10 seconds.
  • With the workspace on it too, Setup Environment took 7.9 and 12 minutes, so the workspace stays on C:.

So when the workspace is on C:, which today is only win-arm64, the step now creates a Dev Drive and puts the NuGet packages and TEMP on it. .NET goes next to the workspace on every Windows runner, as before.

The step moved into a windows-dotnet-drive composite action, because the MSBuild job uses it too. That job's workspace is on D:, but its restore ran in the user profile on C: and took 8.8 minutes in #5796.

Measured on this run, against the 5 runs of the other CI PRs from the same evening, which don't have this change. For the MSBuild job that's 4 runs, leaving out #5796, which adds -m.

Without this PR This PR
MSBuild job 29.6 to 30.4 min 20.0
Its Run MSBuild step 23.1 to 24.0 14.7
win-x64 job 28.8 to 38.6 23.2
win-x64 Restore 3.7 to 7.6 1.0
win-arm64 job 36.1 to 43.0 38.5
win-arm64 Restore 3.8 to 4.6 3.2
  • msbuild.exe resolved the .NET SDK from D:\a\sentry-dotnet\.dotnet and nothing from C:\Program Files, so Visual Studio's MSBuild works with .NET next to the workspace.
  • win-arm64 drew a slow host this time. Steps the drive doesn't touch were slower too, with setup-android at 66 seconds against 58 in the probe. Across all of that day's win-arm64 runs, the medians without and with the Dev Drive were Setup 5.7 and 6.5 minutes, Restore 3.9 and 2.1, Build 8.7 and 7.1, and the integration tests 13.4 and 11.4. That's about 4.5 minutes faster in those four steps.
  • Setup got about a minute slower with .NET on the Dev Drive, because setup-dotnet installed every SDK there. So a second probe, ci: probe where .NET should live on the win-arm64 runner (do not merge) #5801, compared three layouts in the same run:
win-arm64 Run 1 Run 2 Setup Restore Build Integration test
Everything next to the workspace on C: 37.2 35.8 6.6, 6.0 4.2, 3.8 8.0, 7.7 12.9, 12.4
.NET, NuGet and TEMP on the Dev Drive 36.9 failed 7.6 2.4 7.8 12.5
Only NuGet and TEMP on the Dev Drive 33.8 32.4 6.1, 5.7 2.2, 2.0 7.7, 7.0 11.9, 11.7

The last layout is the fastest, so .NET stays next to the workspace now.

  • The failed run hit a race. Right after the drive mounted, fsutil devdrv trust failed with "Access is denied" because the volume was still in use, and that failed the job. The step now retries trust, and if it still fails it only warns, because the Dev Drive is a speedup. The antivirus setting now comes before the drive exists, since it only applies to volumes mounted after it.

The first run's iOS Device Tests failure was the known flaky integration retry, and its rerun passed.

#skip-changelog

@codecov

codecov Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.11%. Comparing base (ff0355e) to head (0a4f927).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5782      +/-   ##
==========================================
- Coverage   76.13%   76.11%   -0.02%     
==========================================
  Files         528      528              
  Lines       19579    19579              
  Branches     3829     3829              
==========================================
- Hits        14906    14903       -3     
- Misses       3791     3793       +2     
- Partials      882      883       +1     

☔ View full report in Codecov by Harness.
📢 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.

The Windows .NET legs spend about 12 minutes in Setup Environment and
Restore, against about 4.5 on Linux. On the Windows images, setup-dotnet
installs into C:\Program Files\dotnet, where the SDK installs workloads as
MSI packages, and NuGet extracts packages into the user profile on C:. The
workload step takes 5.6 minutes there, against about 2 on macOS and Linux,
which install more workloads.

This installs .NET and the NuGet cache next to the workspace, where
workloads install as plain files. On the x64 runners that also moves them to
D:, and on the arm64 runners they stay on C:, so the two legs separate the
install mode from the drive. Windows also stops restoring the Android test
app, which its solution filters exclude.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The arm64 Windows runners have no D: drive, so .NET and the NuGet
packages stayed on C:, and the win-arm64 leg kept a 4 to 5 minute
restore. A probe ran the leg's steps with them and TEMP on a Dev Drive,
and the job took 33.0 minutes twice, against 40.0 and 44.3 without it.
Restore, build and the integration tests each got 2 to 4 minutes
faster. Turning off Defender's real-time scanning saved less, because
the image already excludes C:\ from it.

The step moves into a composite action, because the MSBuild job uses
it too. That job's workspace is on D:, but its restore ran in the user
profile on C: and took 8.8 minutes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ric-oliv ric-oliv changed the title ci: install .NET and NuGet packages next to the workspace on Windows ci: install .NET and NuGet packages on a faster drive on Windows Oct 24, 2026
A second probe ran the win-arm64 leg's steps three ways in one run.
With only the NuGet packages and TEMP on the Dev Drive, the job took
33.8 and 32.4 minutes. With .NET there too, it took 36.9, and with
nothing there 37.2 and 35.8. Installing every SDK onto the new drive
made Setup Environment slower than it saved.

In one of those jobs, `fsutil devdrv trust` failed with "Access is
denied" because the new volume was still in use, and that failed the
job. Trust is now retried, and if it still fails the step only warns,
because the Dev Drive is a speedup. The antivirus setting now comes
before the drive exists, since it only applies to volumes mounted
after it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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