Skip to content

Fix ProjectImports.zip regression from shared FileUtilities statics#18

Draft
JanProvaznik wants to merge 2 commits intomainfrom
fix/project-imports-zip-regression
Draft

Fix ProjectImports.zip regression from shared FileUtilities statics#18
JanProvaznik wants to merge 2 commits intomainfrom
fix/project-imports-zip-regression

Conversation

@JanProvaznik
Copy link
Owner

Fix

Fixes the scenario test failures reported in dotnet/dotnet#5433 (codeflow for dotnet#13364).

Problem

PR dotnet#13364 moved FileUtilities from src/Shared/ (compiled into each assembly with independent statics) to src/Framework/ (single shared assembly). Before that move, ClearCacheDirectory() in XMake.cs used MSBuild.exe's own cacheDirectory static — a separate, mostly-empty directory — so the call was effectively a no-op for the real build cache. After the move, all assemblies share one cacheDirectory static, so ClearCacheDirectory() now deletes the directory that ProjectImportsCollector uses for its temporary ProjectImports.zip archive.

This causes 9 scenario test failures across all platforms:
\
Unhandled exception: Could not find a part of the path
'.../MSBuildTemp.../MSBuild-1/run-dotnet-run.ProjectImports.zip'
\\

Root Cause

Before dotnet#13364 After dotnet#13364
Each assembly compiled its own FileUtilities with independent cacheDirectory / TempFileDirectory statics All assemblies share one FileUtilities in Framework
XMake.ClearCacheDirectory() -> MSBuild.exe's cache dir (empty, no-op) XMake.ClearCacheDirectory() -> shared cache dir (contains ProjectImports.zip!)
ProjectImportsCollector -> Build.dll's cache dir (untouched by XMake cleanup) ProjectImportsCollector -> same shared cache dir (destroyed by XMake cleanup)

Fix

  • ProjectImportsCollector.cs: Store the temporary archive in TempFileDirectory (the parent) instead of GetCacheDirectory() (the child subdirectory wiped by ClearCacheDirectory()). The archive is still cleaned up by DeleteArchive() after embedding and by the ProcessExit handler.
  • ProjectImportsCollector.cs: Make DeleteArchive() resilient to IO errors (best-effort cleanup).
  • BinaryLogger_Tests.cs: Regression test that verifies the archive remains readable after ClearCacheDirectory().

Open question

Before dotnet#13364, the ClearCacheDirectory() calls in XMake.cs were no-ops for the real result cache. Now they actually delete result cache files. This is probably fine (runs after EndBuild), but is a behavioral change worth validating -- especially for the DiscardBuildResults=false case where callers may expect disk-spilled results to survive.

JanProvaznik and others added 2 commits March 13, 2026 15:37
After FileUtilities moved from Shared to Framework (dotnet#13364), all assemblies
share the same cacheDirectory static. ClearCacheDirectory() in XMake.cs now
deletes the same directory that ProjectImportsCollector uses for its temporary
archive, causing 'Could not find a part of the path' errors during binlog
finalization.

Fix: Store the temporary ProjectImports archive in TempFileDirectory (the
parent) rather than GetCacheDirectory() (the child that gets wiped). Also
make DeleteArchive resilient to the archive already being cleaned up.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The previous test simulated ProjectImportsCollector + ClearCacheDirectory
in isolation. Replace with a real build through MSBuild CLI (ExecMSBuild
with -bl:), which exercises the full XMake.Execute → EndBuild →
ClearCacheDirectory code path. Verify the binlog still contains
embedded project imports by replaying with ArchiveFileEncountered.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JanProvaznik JanProvaznik force-pushed the fix/project-imports-zip-regression branch from 4e0c79d to 1d02dca Compare March 13, 2026 15:35
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.

1 participant