dotnet / msbuild

The Microsoft Build Engine (MSBuild) is the build platform for .NET and Visual Studio.
https://docs.microsoft.com/visualstudio/msbuild/msbuild
MIT License
5.17k stars 1.34k forks source link

[Bug]: Breaking change in serialized BuildResult can lead to errors in result caching with older data #10208

Closed dfederm closed 1 day ago

dfederm commented 3 weeks ago

Issue Description

I am seeing the following errors when using the result caching feature:

MSB4256: Reading input result cache files from path "<stuff>\Foo.MSBuildResultsCache" encountered an error: Unable to read beyond the end of the stream.
MSBUILD : error : MSB4258: Writing output result cache file in path "<stuff>\Bar.MSBuildResultsCache" encountered an error: Object reference not set to an instance of an object.

Specifically the result cache file was produced by MSBuild 17.10, but I'm currently using MSBuild 17.11.

It appears that a field was added to the BuildResult in #9987 which is likely causing this issue.

Steps to Reproduce

See detail above

Expected Behavior

See detail above

Actual Behavior

See detail above

Analysis

No response

Versions & Configurations

No response

AR-May commented 2 weeks ago

Discussed the issue internally.

Problem: The build results cache was not initially intended to be used cross MSBuild versions (i.e. to be produced by one version and used by another). When a functionality to use the build caches created outside the local build was added, we became unable to modify BuildResult class (including adding fields) because it deserializes the build results from the cache file with a fixed structure. BuildResult and ResultsCache also has no notion of a version, thus flexible deserialization from the cache based on the version is not possible.

Resolution: We are going to introduce in a non-breaking way the notion of a cache/result version. The caches will not be forwards compatible (produced by newer version and used by older) but backwards compatible with the previous two released versions (produced by older version and used by newer one). We also will add an escape hatch which will allow to produce old-style result caches even on a newer version to make the transition to versioned caches smoother.