Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build scripts do not separate Restore from Build, causing confusing behavior on builds after package updates #12799

Open
1 of 2 tasks
rainersigwald opened this issue Mar 6, 2023 · 10 comments

Comments

@rainersigwald
Copy link
Member

rainersigwald commented Mar 6, 2023

  • This issue is blocking
  • This issue is causing unreasonable pain

This is the root cause of NuGet/Home#12437, which has caused @jaredpar and the Roslyn team a lot of pain recently.

The Arcade build.proj can invoke NuGet restore and build in the same build request, often when running build.ps1 -restore -build:

<MSBuild Projects="@(_ProjectToRestore)"
Properties="@(_SolutionRestoreProps)"
RemoveProperties="$(_RemoveProps);TreatWarningsAsErrors"
Targets="Restore"
SkipNonexistentTargets="true"
BuildInParallel="%(_ProjectToRestore.RestoreInParallel)"
Condition="'$(Restore)' == 'true'"/>
<!--
Build solution.
-->
<MSBuild Projects="@(ProjectToBuild)"
Properties="@(_SolutionBuildProps);__BuildPhase=SolutionBuild;_NETCORE_ENGINEERING_TELEMETRY=Build"
RemoveProperties="$(_RemoveProps)"
Targets="@(_SolutionBuildTargets)"
BuildInParallel="%(ProjectToBuild.BuildInParallel)"
Condition="'@(_SolutionBuildTargets)' != ''" />

This is not correct. Specifically, it will cause incorrect builds when

  • Projects reference NuGet packages
  • Those NuGet packages deliver build logic (.props/.targets files)
  • the references to those packages have changed since the last build (removed or version changed).

In that case, MSBuild will use stale versions of the imported build logic in the build, because they are imported in the restore operation and MSBuild tries to retain a coherent set of imports for the duration of a build.

It's not possible to do this correctly today (dotnet/msbuild#2811). However, the Arcade/restore integration can be altered to behave correctly by hooking into MSBuild's -restore behavior.

Specifically, instead of passing Restore as a property to Build.proj

/p:Restore=$restore `

the wrapper script should pass (or not pass) -restore, so MSBuild can flush caches at the appropriate point between restore and build.

For that to work, the restore logic would need to be separated from Execute into its own target, which must be named Restore. MSBuild would then call that target, flush caches, then call Execute to do the "build" portion of the build.

This is highly relevant to developer-desktop scenarios where a dev might update a package reference version, and to Roslyn's two-phase build that builds the compiler then rebuilds the repo with it. It is not an issue for from-clean builds like most CI/PR/official builds, which I think is why it has been able to linger for so long.

@missymessa
Copy link
Member

/cc @mmitche thoughts?

@mmitche
Copy link
Member

mmitche commented Mar 20, 2023

I'm all for attempting to fix this. I'm not sure whether it can fit onto dnceng's plate right now. @rainersigwald Is this something your team could fix?

@rainersigwald
Copy link
Member Author

I'm not opposed to it but we need to figure out how it'd fit in. cc @marcpopMSFT and @donJoseLuis.

@markwilkie
Copy link
Member

Thoughts on next steps here? I think the "fitting it in" is still the challenge.

@mmitche
Copy link
Member

mmitche commented Apr 11, 2023

@rainersigwald What are the risks here?

@missymessa
Copy link
Member

@rainersigwald ping :)

@rainersigwald
Copy link
Member Author

The risks are basically "continues to be a source of super subtle bugs like the one that bit Roslyn". I don't know if @donJoseLuis has team capacity to schedule this vs the other stuff we could be doing.

@missymessa
Copy link
Member

@donJoseLuis if your team has capacity to work on this, please feel free to take it, otherwise we'll close it. Thanks!

@donJoseLuis
Copy link

Time is tight, as the end of release approaches and we are shorthanded. A teammate has 4 days of availability in AUG, we'll spend it looking at this. If the fix requires more than those 4 days, we will not be able to fund it.

@missymessa
Copy link
Member

Time is tight, as the end of release approaches and we are shorthanded. A teammate has 4 days of availability in AUG, we'll spend it looking at this. If the fix requires more than those 4 days, we will not be able to fund it.

Sounds good! Thanks for checking back in :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants