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

BuildCheck does not run on restore #10018

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open

Conversation

maridematte
Copy link
Contributor

@maridematte maridematte commented Apr 16, 2024

Fixes: #9747

Context

We currently run BuildCheck during the restore phase of the build, because of this we end up running BuildCheck twice per project. This PR disables BuildCheck during restore phase.

Changes Made

Added two check for the restore phase on the code.

The first one is on the RequestBuilder, it reads the global property IsRestore and creates a BuildCheck instance as necessary.

The second one is within the BuildCheckConnectorLogger so we do not start a new BuildCheck run because of received events. In this case I added a bool to ProjectEvaluationStartedEventArgs so we can have access to the IsRestore variable within the logger. We skip all event messages until we get a ProjectFinishedEventArgs, which signals the end of a build / the restore phase.

Tests

Added extra tests that only runs the restore target.

Reopened from #9907

Copy link
Member

@JanKrivanek JanKrivanek left a comment

Choose a reason for hiding this comment

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

There still seem to be some merge leftovers

@maridematte maridematte marked this pull request as ready for review April 23, 2024 09:40
src/Build/BackEnd/Components/Logging/ILoggingService.cs Outdated Show resolved Hide resolved

var buildCheckManager = (_componentHost.GetComponent(BuildComponentType.BuildCheckManagerProvider) as IBuildCheckManagerProvider)!.Instance;
buildCheckManager.SetDataSource(BuildCheckDataSource.BuildExecution);
var propertyEntry = _requestEntry.RequestConfiguration.GlobalProperties[MSBuildConstants.MSBuildIsRestoring];
Copy link
Member

Choose a reason for hiding this comment

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

I don't think I understand, since we have this, why we need the change to the evaluation-started event. Can you go over that again?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are two points in BuildCheck that actually run the analyzer. One of them is through the RequestBuilder which works on the worker nodes. And through the BuildCheckConnectorLogger which runs on the main node. The modification to the evaluation-started event is to get information about the restore phase to the connector logger.

{
if (isRestore)
{
isRestore = false;
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't make sense to me, won't there be a bunch of ProjectFinished events that will fire one after the other, causing the first one to unset this and the others to do check stuff?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I figured that out after I ran this for a bit. I had hoped the event was just fired once. Is there an event that is fired at the end of the restore phase that I can use to to control the flow on the connector logger?

Copy link
Member

Choose a reason for hiding this comment

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

If we are relying on the restore happen fully before the build - then the first ProjectEvaluationStartedEventArgs that is not marked with IsRestore denotes the start of the build after the restore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed the isRestore reset to happen when we receive another ProjectEvaluationStartedEventArgs event.

{
if (!isRestore)
{
_buildCheckManager.StartProjectRequest(BuildCheckDataSource.EventArgs, e.BuildEventContext!);
Copy link
Member

Choose a reason for hiding this comment

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

super-nit: Indentation

/// <summary>
/// Gets or sets is the project is currently on restore phase.
/// </summary>
public bool IsRestore { get; internal set; }
Copy link
Member

Choose a reason for hiding this comment

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

I think it's worth considering keeping the property internal for now. It's needed only internally for the infra. For a public API I wonder if exposing all global build properties wouldn't be potentially more useful. But since it's generally hard to remove or update an API once shipped, I think I would vote for not exposing anything publicly for now.

@@ -626,7 +626,7 @@ private void Evaluate()
}
}

_evaluationLoggingContext.LogProjectEvaluationStarted();
_evaluationLoggingContext.LogProjectEvaluationStarted(_data.GlobalPropertiesDictionary[MSBuildConstants.MSBuildIsRestoring] is not null); ;
Copy link
Member

Choose a reason for hiding this comment

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

We currently set the property only to true but it's not unconceivable that at some point someone would want to set it to false to mean "we're not restoring". For future proofing, would you consider parsing the value instead of just checking that the prop is defined?

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

Successfully merging this pull request may close these issues.

Analyzers prototyping - Detect and skip restore (evaluation and execution)
4 participants