Skip to content

MSBuild .up2date files can permanently hork U2D check in VS #13478

@AArnott

Description

@AArnott

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.

IDE binlog

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:

  1. 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.
  2. 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]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions