Skip to content

Fix build race condition in VS templates#6413

Open
lauren-ciha wants to merge 26 commits intomainfrom
user/laurenciha/disable-template-build-button-during-package-install
Open

Fix build race condition in VS templates#6413
lauren-ciha wants to merge 26 commits intomainfrom
user/laurenciha/disable-template-build-button-during-package-install

Conversation

@lauren-ciha
Copy link
Copy Markdown
Member

Before

If a user attempts to build the C# templates before the NuGet wizard installs package dependencies, the build would fail with Xaml compile errors

With this PR

  • If a user attempts to build the C# templates before the NuGet wizard installs:
    • The build is blocked until the packages are installed
    • An InfoBar appears notifying users that the build will continue once NuGet dependencies have installed
  • If automatic package download is disabled, an InfoBar appears alerting users that they will need to install packages before building the template

Validation

Manual Validation

Language Packaged Unit Test App Wapproj Class Library (C#) / Runtime Component (C++)
Criteria (Package auto-download enabled) Build blocks with InfoBar message until download succeeds, then builds successfully (C#), builds as expected (C++) Build blocks with InfoBar message until download succeeds, then builds successfully (C#), builds as expected (C++) Build blocks with InfoBar message until download succeeds, then builds successfully (C#), builds as expected (C++) Build blocks with InfoBar message until download succeeds, then builds successfully (C#), builds as expected (C++)
C# Pass Pass Pass Pass
C++ Pass Pass Pass Pass
Criteria (Package auto-download disabled) Warning InfoBar appears with instructions for downloading packages Warning InfoBar appears with instructions for downloading packages Warning InfoBar appears with instructions for downloading packages Warning InfoBar appears with instructions for downloading packages
C# Pass Pass Pass Pass
C++ Pass Pass Pass Pass

A microsoft employee must use /azp run to validate using the pipelines below.

WARNING:
Comments made by azure-pipelines bot maybe inaccurate.
Please see pipeline link to verify that the build is being ran.

For status checks on the main branch, please use TransportPackage-Foundation-PR
(https://microsoft.visualstudio.com/ProjectReunion/_build?definitionId=81063&_a=summary)
and run the build against your PR branch with the default parameters.

…r a number of manual tests, works with single-project C# and C#/C++ wapproj (not C# unit test)
@lauren-ciha lauren-ciha marked this pull request as ready for review April 17, 2026 22:41
Comment thread dev/VSIX/Shared/BuildGuard.cs
Copy link
Copy Markdown
Contributor

@guimafelipe guimafelipe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, it was a bit harder to track what the build guard is doing. There were a group of booleans that were always changed and used to check what to do. I would advise to change the design a bit to be a proper state machine, with clear transitions between the state instead of tracking those 6 boolean values. What do you think?

Comment on lines +36 to +49
public void SetReleaseCondition(Func<bool> condition)
{
_shouldRelease = condition;
}

public void SetInfoBarMessage(string message)
{
ThreadHelper.ThrowIfNotOnUIThread();
_infoBarMessage = message;
if (_isBlocking)
{
ShowInfoBarWhenShellReady();
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use the C# setter/getter here for clarity?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it's theoretically possible, I'm not sure it makes sense for SetInfoBarMessage because it calls a UI change ShowInfoBarWhenShellIsReady() as well as assigning the _message value.

Comment thread dev/VSIX/Shared/BuildGuard.cs Outdated
return;
}

_solutionBuildManager5 = ServiceProvider.GlobalProvider.GetService(typeof(SVsSolutionBuildManager)) as IVsSolutionBuildManager5;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to get it every time? Can we just set this up in the constructor once?

Comment thread dev/VSIX/Shared/BuildGuard.cs
Comment thread dev/VSIX/Shared/BuildGuard.cs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants