Skip to content

[build] Share provisioned .NET SDK across worktrees - #12490

Open
simonrozsival wants to merge 2 commits into
mainfrom
dev/simonrozsival/shared-dotnet-sdk-cache
Open

[build] Share provisioned .NET SDK across worktrees#12490
simonrozsival wants to merge 2 commits into
mainfrom
dev/simonrozsival/shared-dotnet-sdk-cache

Conversation

@simonrozsival

@simonrozsival simonrozsival commented Aug 24, 2026

Copy link
Copy Markdown
Member

Context

Each git worktree currently provisions the same pinned .NET SDK into its own
bin/<configuration>/dotnet directory. Developers using several worktrees
therefore download and store duplicate SDK installations.

Changes

  • Treat DOTNET_INSTALL_DIR as an opt-in shared SDK base for local builds.

  • Install each pinned SDK once under:

    $DOTNET_INSTALL_DIR/<sdk-version>/
    
  • 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-local invocations to find it without requiring the
    environment variable to remain set.

  • Keep configuration-specific workload packs and build outputs under each
    checkout's existing bin/Debug or bin/Release directories.

  • Ignore DOTNET_INSTALL_DIR when TF_BUILD, GITHUB_ACTIONS, or CI is set.
    CI therefore retains the existing worktree-local
    bin/<configuration>/dotnet behavior.

  • Document the opt-in setup for Unix and Windows.

Example:

export DOTNET_INSTALL_DIR="$HOME/android-dotnet-sdk"
make prepare

Validation

  • Completed make prepare and make all: 0 warnings, 0 errors.
  • Ran make prepare from a second worktree using the same base. The installer
    reported the SDK was already installed and emitted zero download attempts.
  • Verified Debug and Release resolve the same versioned SDK root.
  • Verified shell, PowerShell, Make, MSBuild, and dotnet-local path handling.
  • Verified absolute paths, relative paths, and paths containing spaces.
  • Verified CI markers force the existing checkout-local SDK path.

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
@simonrozsival

Copy link
Copy Markdown
Member Author

Local validation completed:

  • First worktree: DOTNET_INSTALL_DIR="$HOME/android-dotnet-sdk" make prepare succeeded and installed SDK 11.0.100-rc.1.26411.119.
  • First worktree: make all then succeeded with DOTNET_INSTALL_DIR unset, proving the persisted install location is used. Final result: 0 warnings, 0 errors.
  • Created a second worktree on dev/simonrozsival/shared-dotnet-sdk-cache-verification.
  • Second worktree: the same make prepare succeeded and reported .NET Core SDK with version '11.0.100-rc.1.26411.119' is already installed.\n- The second preparation had 0 Attempting to download messages.\n- Both worktrees persisted the same SDK root: ~/android-dotnet-sdk/11.0.100-rc.1.26411.119/Debug/.

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
@simonrozsival

Copy link
Copy Markdown
Member Author

Updated the shared layout to use one SDK installation for both configurations:

$DOTNET_INSTALL_DIR/<sdk-version>/

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 dotnet-local were validated against the unified path.

@simonrozsival
simonrozsival marked this pull request as ready for review August 24, 2026 12:35
Copilot AI lite review requested due to automatic review settings August 24, 2026 12:35

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 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.txt and teach dotnet-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

Comment thread Directory.Build.props
Comment on lines +19 to 22
<_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>
Comment thread eng/install-dotnet.sh
Comment on lines +29 to +37
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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

should this location have $(CONFIGURATION) in the path?

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.

3 participants