Skip to content

[ci] Isolate Unix .NET CLI first-run state - #13397

Merged
simonrozsival merged 1 commit into
mainfrom
simonrozsival-ci-dotnet-permissions
Nov 4, 2026
Merged

simonrozsival merged 1 commit into
mainfrom
simonrozsival-ci-dotnet-permissions

Conversation

@simonrozsival

Copy link
Copy Markdown
Member

Context: #13376
Context: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1663841

The macOS MSBuild test job fails in dotnet build-server shutdown, before tests run:

System.UnauthorizedAccessException: Access to the path '/Users/cloudtest/.dotnet/11.0.100-rc.3.26522.148.toolpath.sentinel' is denied.
 ---> System.IO.IOException: Permission denied

The bootstrap SDK update in #13376 moves DOTNET_ROOT out of the potentially non-writable ~/.dotnet, but first-run initialization still writes its version-specific sentinels there. Installing a new SDK can therefore expose the existing agent-home permissions problem. The subsequent dotnet --info check does not exercise this initialization: it succeeds even when shutdown cannot create its sentinel. This is not specific to .NET 11; the same failure reproduces with .NET 10.

Give the shared Unix setup a fresh DOTNET_CLI_HOME under Agent.TempDirectory and propagate it to subsequent job steps. NuGet also honors DOTNET_CLI_HOME, so link the existing .nuget and .local directories into the temporary home to preserve configuration, credential-provider discovery, and caches. Keep both original and job-local global tools discoverable through PATH. Leave HOME, Windows setup, and shared-home permissions unchanged, without suppressing failures.

Validation:

  • python3 /Users/simon/.copilot/session-state/0b56633e-c42d-4d10-84b4-09137b9f923d/files/validate-cli-home.py --sdk-version 11.0.100-rc.2.26504.105 — passed.
  • python3 /Users/simon/.copilot/session-state/0b56633e-c42d-4d10-84b4-09137b9f923d/files/validate-cli-home.py --sdk-version 10.0.402 — passed.
  • bash -n on both rendered installer variants — passed through the harness.
  • git diff --check — passed.

The local harness, retained as a session artifact rather than checked in, reproduces the original permission failure with real CLI commands and a synthetic read-only .dotnet. It then executes the template's actual Bash body and confirms shutdown succeeds, sentinels stay isolated, and tool discovery, user NuGet configuration/plugins, caches, and explicit cache overrides remain intact. Both installer cleanup settings, repeated setup, and paths containing spaces pass. Only download/installation is stubbed to reuse installed SDKs; shared-home permissions remain unchanged.

All 48 Azure pipeline YAML files also parsed successfully:

python3 - <<'PY'
from pathlib import Path
import yaml
files = list(Path('build-tools/automation').rglob('*.yaml'))
for path in files:
    yaml.safe_load(path.read_text())
print(f'Parsed {len(files)} Azure pipeline YAML files successfully')
PY

Live Azure execution/template expansion, authenticated NuGet feeds, Linux/Windows execution, and the exact RC3 SDK were not exercised. No product SDK build or device tests were run for this pipeline-only change.

Moving DOTNET_ROOT does not move first-run sentinels, so a hosted agent with a non-writable ~/.dotnet still fails before build-server shutdown can run. Set a fresh DOTNET_CLI_HOME under Agent.TempDirectory for subsequent job steps.

Preserve NuGet configuration, credential providers, and caches through links to the existing home, and keep both existing and job-local global tools discoverable without changing HOME or shared-directory permissions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings November 4, 2026 16:10

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.

🟢 Approval recommended

No active review issues are recorded for the Unix CI change isolating .NET CLI first-run state.

No open issues 🎉

What changed in this PR

This PR isolates .NET CLI first-run state in the shared Unix CI setup, addressing macOS permission failures that moving DOTNET_ROOT alone does not resolve.

Changes:

  • Creates a fresh DOTNET_CLI_HOME under Agent.TempDirectory and propagates it to subsequent steps.
  • Links existing NuGet and local-data directories to preserve configuration, credential discovery, and caches.
  • Adds original and job-local global-tool directories to PATH, without changing HOME or Windows setup.
File Description
build-tools/​automation/​yaml-templates/​use-dot-net.yaml Isolates Unix CLI state while preserving access to existing NuGet data and global tools.

Review effort: Balanced

@simonrozsival simonrozsival added the flaky-ci Intermittent CI failures and work to improve CI reliability label Nov 4, 2026
@simonrozsival

Copy link
Copy Markdown
Member Author

@dalexsoto review

@simonrozsival
simonrozsival enabled auto-merge (squash) November 4, 2026 16:41

@dalexsoto dalexsoto left a comment

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.

Static review found no blocking issues in this revision. The Unix CLI-home isolation preserves existing NuGet state and both global-tool locations across the setup/build/test consumers, while leaving HOME and Windows setup unchanged.

@simonrozsival
simonrozsival merged commit 91376ae into main Nov 4, 2026
42 checks passed
@simonrozsival
simonrozsival deleted the simonrozsival-ci-dotnet-permissions branch November 4, 2026 20:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

flaky-ci Intermittent CI failures and work to improve CI reliability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants