diff --git a/src/Build.UnitTests/BinaryLogger_Tests.cs b/src/Build.UnitTests/BinaryLogger_Tests.cs
index 098d237bd8e..3edb919e695 100644
--- a/src/Build.UnitTests/BinaryLogger_Tests.cs
+++ b/src/Build.UnitTests/BinaryLogger_Tests.cs
@@ -542,6 +542,39 @@ public void BinaryLoggerShouldNotThrowWhenMetadataCannotBeExpanded()
ObjectModelHelpers.BuildProjectExpectSuccess(project, binaryLogger);
}
+ ///
+ /// Regression test for dotnet/dotnet#5433 — ClearCacheDirectory must not destroy the
+ /// ProjectImports archive before it is embedded in the binlog.
+ ///
+ [Fact]
+ public void BinlogEmbeddedImportsSurviveClearCacheDirectory()
+ {
+ string logFilePath = Path.Combine(_env.DefaultTestDirectory.Path, "test.binlog");
+
+ var collector = new ProjectImportsCollector(logFilePath, createFile: false, runOnBackground: false);
+ collector.AddFileFromMemory("testfile.proj", "");
+
+ // This is what XMake.cs does after EndBuild — wipes the cache directory.
+ FileUtilities.ClearCacheDirectory();
+
+ // ProcessResult must still read the archive after the cache dir is gone.
+ bool archiveRead = false;
+ collector.ProcessResult(
+ stream =>
+ {
+ stream.Length.ShouldBeGreaterThan(0);
+ archiveRead = true;
+ },
+ error => throw new InvalidOperationException(error));
+ archiveRead.ShouldBeTrue("Archive must be readable after ClearCacheDirectory");
+
+ // DeleteArchive must not throw (directory must still exist).
+ collector.DeleteArchive();
+
+ // Satisfy the fixture's expectation that _logFile exists.
+ File.WriteAllText(_logFile, string.Empty);
+ }
+
///
/// Regression test for https://github.com/dotnet/msbuild/issues/6323.
///
diff --git a/src/Build/Logging/BinaryLogger/ProjectImportsCollector.cs b/src/Build/Logging/BinaryLogger/ProjectImportsCollector.cs
index a537f8025f6..c42e54a26a8 100644
--- a/src/Build/Logging/BinaryLogger/ProjectImportsCollector.cs
+++ b/src/Build/Logging/BinaryLogger/ProjectImportsCollector.cs
@@ -63,15 +63,12 @@ public ProjectImportsCollector(
}
else
{
- string cacheDirectory = FileUtilities.GetCacheDirectory();
- if (!FileSystems.Default.DirectoryExists(cacheDirectory))
- {
- Directory.CreateDirectory(cacheDirectory);
- }
+ // Store the temporary archive in TempFileDirectory rather than GetCacheDirectory()
+ // because ClearCacheDirectory() wipes the cache dir during build shutdown.
+ string tempDirectory = FileUtilities.TempFileDirectory;
- // Archive file will be temporarily stored in MSBuild cache folder and deleted when no longer needed
_archiveFilePath = Path.Combine(
- cacheDirectory,
+ tempDirectory,
GetArchiveFilePath(
Path.GetFileName(logFilePath),
sourcesArchiveExtension));
@@ -304,7 +301,9 @@ public void Close()
public void DeleteArchive()
{
Close();
- File.Delete(_archiveFilePath);
+
+ // Best effort — the archive may already have been cleaned up.
+ FileUtilities.DeleteNoThrow(_archiveFilePath);
}
}
}