dotnet / project-system

The .NET Project System for Visual Studio
MIT License
967 stars 386 forks source link

Copies performed by the Build Acceleration feature should trigger the PostBuild event #9421

Closed derekpiasecki closed 6 months ago

derekpiasecki commented 6 months ago

Visual Studio Version

17.9.3

Summary

When Build Acceleration remember files to copy and does so instead of building, the PostBuild event does not run. Since PostBuild is supposed to happen after the build, and Build Acceleration is part of the build, any actions by Build Acceleration should count as "building" and therefor trigger PostBuild.

Steps to Reproduce

  1. In my particular case, I have a non-dotNet project whose output I incorporate into the output folder of the dotNet project I am building, using a project reference and <None Include="somefile.ext" CopyToOutputDirectory="PreserveNewest" />, but any similar file copy should encounter the same issue.
  2. In the dotNet project, add a PostBuild step. It doesn't matter what it does, though in our case the reason we need it to run is that it depends in part on the file that is being included, in step 1 above (example: archiving the entire output folder).
  3. With BuildAcceleration enabled, build the dotNet project. The PostBuild step runs after the build completes.
  4. If you build the dotNet project again, it does not build anything and does not run the PostBuild step (as expected).
  5. Build only the dependency so the file that the dotNet project includes has a newer timestamp (or just touch the file).
  6. With BuildAcceleration enabled, build the dotNet project. The BuildAcceleration feature recognizes the change to the included file and accelerates its copy, but the PostBuild step does not run (the PostBuild step should run).

Expected Behavior

Accelerated builds are still builds, so a PostBuild step should still run when an accelerated build completes (with no changes other than the accelerated steps, like file copies). However, this might need to be optional since some projects may have PostBuild steps that in-place modify the project's output files and thus should not be run unless the project does an actual build. Perhaps a new option such as <RunPostBuildEvent>OnBuildSuccessNotAcceleration</RunPostBuildEvent> could be used to optionally disable this behavior (or perhaps the inverse, OnBuildSuccessOrAcceleration).

Actual Behavior

When a build completes via BuildAcceleration, this does not trigger the PostBuild step.

User Impact

The main problems are that skipping the PostBuild is not the expected behavior and that it is not obvious that a problem has occurred, since the missing PostBuild step can be hard to recognize for some projects and it will only be missing for some builds (i.e. those that are accelerated). A fairly minor secondary impact is that there is no good workaround other than turning off BuildAcceleration, since manually marking files for the up-to-date check does not have the desired effect.

drewnoakes commented 6 months ago

No actual build is invoked for projects that are accelerated. If you have post-build steps that need to run on every build that a project is part of, disable build acceleration for the project.

It's not feasible for VS to invoke arbitrary build targets when acceleration occurs. Doing so requires invoking MSBuild, which is the very thing that BA tries to avoid. If you need build logic, it's better to just disable BA.

Note that in general, if your post-build steps are just copying files around, then you can model that in a way that does support BA. However, if you have post-build steps that perform packaging and such, then you'll need to ensure they run by disabling BA.