Source bootstrap dotnet-install script from a repo-local path - #14011
Merged
JanProvaznik merged 1 commit intoJun 9, 2026
Merged
Conversation
The bootstrap AcquireSdk target passed $(DotNetRoot) as the
DotNetInstallScriptRootPath, so InstallDotNetCoreTask downloaded
dotnet-install.{ps1,sh} into wherever the SDK happens to live. On agents
where global.json matches a machine-wide SDK, $(DotNetRoot) resolves to
"C:\Program Files\dotnet\", which is non-writable and contains a space.
The dotnet-install script is just a build tool; its location should not be
tied to the SDK install root. Point DotNetInstallScriptRootPath at the
repo-local $(ArtifactsObjDir)bootstrap\ instead, and have the task create
that directory before downloading. InstallDir stays repo-local and separate.
Fixes dotnet#13962
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
JanProvaznik
force-pushed
the
fix/bootstrap-local-dotnet-install-script
branch
from
June 9, 2026 14:49
e63f8c9 to
3d41273
Compare
JanProvaznik
marked this pull request as ready for review
June 9, 2026 14:50
Member
Author
|
autoreviewer ran locally with no issues |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adjusts MSBuild’s bootstrap SDK acquisition so the dotnet-install script is always downloaded and executed from a repo-local artifacts directory rather than from $(DotNetRoot), avoiding writes to machine-global/non-writable locations (and paths with spaces) when the machine-wide SDK is reused.
Changes:
- Update bootstrap targets to pass
$(ArtifactsObjDir)bootstrap\asDotNetInstallScriptRootPathinstead of$(DotNetRoot). - Ensure
InstallDotNetCoreTaskcreates the script directory before downloading the script. - Clarify
DotNetInstallScriptRootPathdocumentation to reflect repo-local intent and rationale.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/MSBuild.Bootstrap.Utils/Tasks/InstallDotNetCoreTask.cs | Creates the script root directory before downloading; updates property documentation to clarify repo-local semantics. |
| eng/BootStrapMsBuild.targets | Switches DotNetInstallScriptRootPath to $(ArtifactsObjDir)bootstrap\ and documents why it must be repo-local. |
ViktorHofer
approved these changes
Jun 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #13962
Context
The MSBuild bootstrap task
InstallDotNetCoreTasksourced/downloaded thedotnet-installscript from$(DotNetRoot). On agents whereglobal.jsonmatches a machine-wide SDK (e.g. thewindows.vs2026.amd64image shipping SDK 10.0.300 atC:\Program Files\dotnet),$(DotNetRoot)resolves toC:\Program Files\dotnet\— a machine-global, non-writable path that also contains a space. Writing the script there needs elevation and pollutes a global directory, and the embedded space is the class of failure patched in the VMR (dotnet/dotnet#7061, #7075, #7076, #7080).Per @rainersigwald's follow-up request, the script — which is just a build tool — should always be repo-local and decoupled from wherever the SDK happens to live. This builds on top of the already-backflowed quoting fixes in
SetupScriptsExecutionSettings.Change
eng/BootStrapMsBuild.targets: pass the repo-local$(ArtifactsObjDir)bootstrap\asDotNetInstallScriptRootPathinstead of$(DotNetRoot).InstallDirremains repo-local and intentionally separate.src/MSBuild.Bootstrap.Utils/Tasks/InstallDotNetCoreTask.cs: create the (now repo-local) script directory before downloading, since it may not pre-exist; clarify the property doc.Validation
Removed
artifacts/bin/bootstrapandartifacts/obj/bootstrap, then ranbuild.cmd(full build, 0 warnings / 0 errors). Confirmed the script is now written toartifacts/obj/bootstrap/dotnet-install.ps1and the bootstrap SDK installs toartifacts/bin/bootstrap/core/sdk/. The bootstrap task no longer writes into$(DotNetRoot).No user-facing behavior change — this only affects MSBuild's own bootstrap acquisition, so no ChangeWave is needed.