-
Notifications
You must be signed in to change notification settings - Fork 1.4k
MSBuild .up2date files can permanently hork U2D check in VS #13478
Description
Issue Description
MSBuild creates and updates *.Up2Date files via its Microsoft.Common.CurrentVersion.targets file as a means to assist Visual Studio in its IDE-level up-to-date checks. But these files are not always updated after a successful project build, leading to the projects never being seen as up-to-date when their timestamps don't happen to line up perfectly.
Steps to Reproduce
In the VS repo:
git checkout 44a2568eb96d05d46391c76e7148364d1c4c4f27
git clean -fdx :/
.\retail.ps1
bm src\Copilot\dirs.proj
src\Copilot\Copilot.slnx
Build the solution in VS (repeatedly). You might also need to unload the "*NpmRestore" projects since they are (at present) permanently seen as out-of-date for other reasons that I'm also pursuing.
Expected Behavior
After two solution builds, all projects are seen as up-to-date.
That's the goal, anyway. As I said the NpmRestore projects have other issues. And so do the UIInternal and Microsoft.VisualStudio.Shell.Connected projects. So you can ignore those.
Actual Behavior
The Copilot.Service.Vsix and Copilot.UI.TestContracts projects are seen as out-dated due to their .up2date files.
Analysis
Here is Copilot's (excellent) analysis of the problem:
Root cause: the .Up2Date file is not updated on every successful build. In MSBuild it is only touched by Microsoft.Common.CurrentVersion.targets target _CopyFilesMarkedCopyLocal, and only when
this condition is true:
<Touch Files="@(CopyUpToDateMarker)"
AlwaysCreate="true"
Condition="'@(ReferencesCopiedInThisBuild)' != '' and '$(WroteAtLeastOneFile)' == 'true'" />So the marker advances only when the project copies at least one changed copy-local reference. If a project rebuilds but doesn’t copy any changed refs into its own output, the marker stays old
and FastUpToDate treats the project as stale on the next build.
For the projects in your log:
- Copilot.Service.Vsix
Its meaningful inputs are mostly non-copy-local/project-layout inputs. The project reference to Copilot.Service.csproj has ReferenceOutputAssembly=false, and the binlog shows no effective
_CopyFilesMarkedCopyLocal work for this project. Result: the build succeeds, but Copilot..DC15E88A.Up2Date is never touched. - Copilot.UI.TestContracts
It references Copilot.Vsix.csproj with Private=False. The binlog shows _CopyFilesMarkedCopyLocal ran, but every candidate copy was skipped as unchanged, so WroteAtLeastOneFile stayed false and
Copilot..BBA9B640.Up2Date was not touched. That’s why a newer Copilot.Vsix.dll still beats the old marker on the next build.
But the build never writes those files into the consuming projects’ output folders, so those projects are permanently not up-to-date.
So the answer is: the stale .Up2Date timestamps are not a VS bug in timestamp propagation; they’re a consequence of how MSBuild defines the marker. It only tracks changed copy-local reference
copies, not “project built successfully.”
Versions & Configurations
18.6.0 Insiders [11627.215.main]