[build] Share provisioned .NET SDK across worktrees - #12490
[build] Share provisioned .NET SDK across worktrees#12490simonrozsival wants to merge 2 commits into
Conversation
Allow local builds to opt into a versioned, configuration-specific shared SDK root through DOTNET_INSTALL_DIR while keeping CI on worktree-local installations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: cbf40b05-e7fb-454f-a214-feb9a301ae95
|
Local validation completed:
|
Use one versioned shared SDK root for both Debug and Release while retaining configuration-specific checkout output and location marker files. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: cbf40b05-e7fb-454f-a214-feb9a301ae95
|
Updated the shared layout to use one SDK installation for both configurations: Debug and Release retain separate checkout-local outputs and separate location marker files, but both markers point to the same SDK root. Shell, PowerShell, MSBuild property evaluation, and |
There was a problem hiding this comment.
Pull request overview
This PR updates the local build bootstrapping flow to optionally share the pinned .NET SDK installation across multiple git worktrees (and across Debug/Release), while keeping workload packs and build outputs checkout-local. It does this by introducing a persisted “resolved dotnet root” file per configuration and teaching the build entry points (Make/MSBuild/dotnet-local) to honor it.
Changes:
- Add an opt-in shared SDK installation mode via
DOTNET_INSTALL_DIR, installing the pinned SDK under<base>/<sdk-version>/(disabled in CI environments). - Persist the resolved SDK location to
bin/<Configuration>/dotnet-install-location.txtand teachdotnet-local(bash/cmd) and Make’s MSBuild wrapper to use it. - Document the shared SDK setup steps for both Unix and Windows build instructions.
Show a summary per file
| File | Description |
|---|---|
| eng/install-dotnet.sh | Adds shared-install behavior for the pinned SDK and writes dotnet-install-location.txt. |
| eng/install-dotnet.ps1 | PowerShell equivalent of shared-install behavior and persisted location file. |
| dotnet-local.sh | Resolves dotnet root from dotnet-install-location.txt when present. |
| dotnet-local.cmd | Resolves dotnet root from dotnet-install-location.txt when present and factors probing into a helper label. |
| Documentation/building/windows/instructions.md | Documents DOTNET_INSTALL_DIR workflow for Windows and clarifies dotnet-local behavior. |
| Documentation/building/unix/instructions.md | Documents DOTNET_INSTALL_DIR workflow for Unix and clarifies dotnet-local behavior. |
| Directory.Build.props | Adds MSBuild-time resolution of DotNetPreviewPath based on DOTNET_INSTALL_DIR and/or the persisted location file. |
| build-tools/scripts/msbuild.mk | Updates Make/MSBuild invocation to use the persisted dotnet root file and quotes the dotnet tool path. |
Review details
- Files reviewed: 8/8 changed files
- Comments generated: 2
- Review effort level: Lite
| <_DotNetInstallBase Condition=" '$(DOTNET_INSTALL_DIR)' != '' and '$(TF_BUILD)' == '' and '$(GITHUB_ACTIONS)' == '' and '$(CI)' == '' ">$([System.IO.Path]::Combine('$(MSBuildThisFileDirectory)', '$(DOTNET_INSTALL_DIR)'))</_DotNetInstallBase> | ||
| <DotNetPreviewPath Condition=" '$(DotNetPreviewPath)' == '' and '$(_DotNetInstallBase)' != '' ">$([MSBuild]::EnsureTrailingSlash('$(_DotNetInstallBase)\$(MicrosoftNETSdkPackageVersion)'))</DotNetPreviewPath> | ||
| <DotNetPreviewPath Condition=" '$(DotNetPreviewPath)' == '' and Exists('$(BuildOutputDirectory)dotnet-install-location.txt') ">$([System.IO.File]::ReadAllText('$(BuildOutputDirectory)dotnet-install-location.txt').Trim())</DotNetPreviewPath> | ||
| <DotNetPreviewPath Condition=" '$(DotNetPreviewPath)' == '' ">$(BuildOutputDirectory)dotnet\</DotNetPreviewPath> |
| if [[ -n "${DOTNET_INSTALL_DIR:-}" && -z "${TF_BUILD:-}" && -z "${GITHUB_ACTIONS:-}" && -z "${CI:-}" ]]; then | ||
| if [[ "$DOTNET_INSTALL_DIR" = /* ]]; then | ||
| install_base="$DOTNET_INSTALL_DIR" | ||
| else | ||
| install_base="$repo_root/$DOTNET_INSTALL_DIR" | ||
| fi | ||
| mkdir -p "$install_base" | ||
| install_base="$(cd -P "$install_base" && pwd)" | ||
| install_dir="$install_base/$sdk_version" |
|
|
||
| MSBUILD = msbuild | ||
| DOTNET_ROOT = $(topdir)/bin/$(CONFIGURATION)/dotnet/ | ||
| DOTNET_INSTALL_LOCATION = $(topdir)/bin/$(CONFIGURATION)/dotnet-install-location.txt |
There was a problem hiding this comment.
should this location have $(CONFIGURATION) in the path?
Context
Each git worktree currently provisions the same pinned .NET SDK into its own
bin/<configuration>/dotnetdirectory. Developers using several worktreestherefore download and store duplicate SDK installations.
Changes
Treat
DOTNET_INSTALL_DIRas an opt-in shared SDK base for local builds.Install each pinned SDK once under:
Share that versioned SDK between worktrees and between Debug and Release
builds.
Persist the resolved SDK path in each checkout under
bin/<configuration>/dotnet-install-location.txt, allowing later Make,MSBuild, and
dotnet-localinvocations to find it without requiring theenvironment variable to remain set.
Keep configuration-specific workload packs and build outputs under each
checkout's existing
bin/Debugorbin/Releasedirectories.Ignore
DOTNET_INSTALL_DIRwhenTF_BUILD,GITHUB_ACTIONS, orCIis set.CI therefore retains the existing worktree-local
bin/<configuration>/dotnetbehavior.Document the opt-in setup for Unix and Windows.
Example:
Validation
make prepareandmake all: 0 warnings, 0 errors.make preparefrom a second worktree using the same base. The installerreported the SDK was already installed and emitted zero download attempts.
dotnet-localpath handling.