Skip to content

Source bootstrap dotnet-install script from a repo-local path - #14011

Merged
JanProvaznik merged 1 commit into
dotnet:mainfrom
JanProvaznik:fix/bootstrap-local-dotnet-install-script
Jun 9, 2026
Merged

Source bootstrap dotnet-install script from a repo-local path#14011
JanProvaznik merged 1 commit into
dotnet:mainfrom
JanProvaznik:fix/bootstrap-local-dotnet-install-script

Conversation

@JanProvaznik

Copy link
Copy Markdown
Member

Fixes #13962

Context

The MSBuild bootstrap task InstallDotNetCoreTask sourced/downloaded the dotnet-install script from $(DotNetRoot). On agents where global.json matches a machine-wide SDK (e.g. the windows.vs2026.amd64 image shipping SDK 10.0.300 at C:\Program Files\dotnet), $(DotNetRoot) resolves to C:\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\ as DotNetInstallScriptRootPath instead of $(DotNetRoot). InstallDir remains 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/bootstrap and artifacts/obj/bootstrap, then ran build.cmd (full build, 0 warnings / 0 errors). Confirmed the script is now written to artifacts/obj/bootstrap/dotnet-install.ps1 and the bootstrap SDK installs to artifacts/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.

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
JanProvaznik force-pushed the fix/bootstrap-local-dotnet-install-script branch from e63f8c9 to 3d41273 Compare June 9, 2026 14:49
@JanProvaznik
JanProvaznik marked this pull request as ready for review June 9, 2026 14:50
@JanProvaznik
JanProvaznik requested a review from a team as a code owner June 9, 2026 14:50
Copilot AI review requested due to automatic review settings June 9, 2026 14:50
@JanProvaznik

Copy link
Copy Markdown
Member Author

autoreviewer ran locally with no issues

@JanProvaznik
JanProvaznik requested a review from ViktorHofer June 9, 2026 14:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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\ as DotNetInstallScriptRootPath instead of $(DotNetRoot).
  • Ensure InstallDotNetCoreTask creates the script directory before downloading the script.
  • Clarify DotNetInstallScriptRootPath documentation 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.

@JanProvaznik
JanProvaznik enabled auto-merge (squash) June 9, 2026 15:59
@JanProvaznik
JanProvaznik merged commit a91d4fa into dotnet:main Jun 9, 2026
14 checks passed
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.

Bootstrap InstallDotNetCoreTask should source dotnet-install script from a repo-local path, not $(DotNetRoot)

3 participants