-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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 reports success when an AfterTargets errors #3345
Comments
Changing 2.proj to the following makes it work. <Project DefaultTargets="Build">
<Target Name="Build" DependsOnTargets="IndirectBuild"/>
<Target Name="IndirectBuild">
<Error Text="Induce failure" />
</Target>
</Project>
|
I think the reason that this is happening is that from a certain point of view the MSBuild request is succeeding. It's legal to "partially" build another project by specifying an entry-point target, and the result of that request should be success if all of the targets that must run before that target and that target itself succeed. Consider a small project:
If you call the target In this situation,
There's no way to run Note that this has been this way since MSBuild 4.5:
|
In an internal forum, I got the question
It does not, assuming the standard pattern of targets, which is: That creates a target build order dependency that requires that When the standard |
`helix.proj` is built with the target `Test`, but does important work in `Wait`. Since that target was hooked to `Test` by an `AfterTargets`, it hit a bug in MSBuild that failed `AfterTargets` targets don't fail a build that builds the target they hook. Restructure the targets (transparently to callers) to avoid that situation and observe failures in `Wait`.
…1683) `helix.proj` is built with the target `Test`, but does important work in `Wait`. Since that target was hooked to `Test` by an `AfterTargets`, it hit a bug in MSBuild that failed `AfterTargets` targets don't fail a build that builds the target they hook. Restructure the targets (transparently to callers) to avoid that situation and observe failures in `Wait`.
Two issues: 1) Replace AfterTargets="Build" with BeforeTargets="AfterBuild" Workaround for dotnet/msbuild#3345 2) System.ValueTuple Seems like the System.ValueTuple package is missing lib/net472/_._, so lib/net47/System.ValueTuple.dll is identified as a runtime dependency although it is not.
Two issues: 1) Replace AfterTargets="Build" with BeforeTargets="AfterBuild" Workaround for dotnet/msbuild#3345 2) System.ValueTuple Seems like the System.ValueTuple package is missing lib/net472/_._, so lib/net47/System.ValueTuple.dll is identified as a runtime dependency although it is not.
We hit this (not failing, but an error occurred in AfterTargets) behavior too today. msbuild binlog analysis did not show initial error, but then if you look with $error search you can find it and it is not obvious why the build was actually not failing (ContinueOnError="false", etc was all set correctly). Glad I found this bug to explain what was happening, not sure if this sufficiently clear for everyone though. |
Is there a plan to fix this? It's let a couple bugs through our CI system recently. |
Maybe I'm misunderstanding this, but wouldn't this change the target order? In the original, you're running: Build then IndirectBuild In the fixed version, you run IndirectBuild before Build. |
@mmitche that's true, but usually not interesting; the |
`BuildResult` had code in one of its constructors specifically to handle AfterTargets failures, making sure that they are propagated to the referenced target. This didn't work in multi-proc builds for multiple reasons: 1) The process orchestrating the build may have had no visibility into targets other than those requested to be executed by the worker process. This means that the `existingResults` argument typically didn't contain results for the targets with AfterTargets specified, meaning it had no way of knowing that they had failed. 2) The process orchestrating the build may not have loaded the project file handled by the worker process. This means that the `additionalTargetsToCheck` argument could have been `null`, again making it impossible for `BuildResult` to detect the dependency. This change moves the logic of calculating target failures to the worker process, namely to `TargetBuilder`. A new flag `AfterTargetsHaveFailed` is introduced and calculated for each requested target after all targets have executed. This flag is then passed back as part of `TargetResult` and trivially used in `BuildResult`'s `OverallResult`. Note that targets with failed AfterTargets can still succeed in terms of their `ResultCode`, i.e. the failure is kept only in form of this bolt-on bit. The now unused `GetAfterTargetsForDefaultTargets` is deleted. Fixes dotnet#3345
`BuildResult` had code in one of its constructors specifically to handle AfterTargets failures, making sure that they are propagated to the referenced target. This didn't work in multi-proc builds for multiple reasons: 1) The process orchestrating the build may have had no visibility into targets other than those requested to be executed by the worker process. This means that the `existingResults` argument typically didn't contain results for the targets with AfterTargets specified, meaning it had no way of knowing that they had failed. 2) The process orchestrating the build may not have loaded the project file handled by the worker process. This means that the `additionalTargetsToCheck` argument could have been `null`, again making it impossible for `BuildResult` to detect the dependency. This change moves the logic of calculating target failures to the worker process, namely to `TargetBuilder`. A new flag `AfterTargetsHaveFailed` is introduced and calculated for each requested target after all targets have executed. This flag is then passed back as part of `TargetResult` and trivially used in `BuildResult`'s `OverallResult`. Note that targets with failed AfterTargets can still succeed in terms of their `ResultCode`, i.e. the failure is kept only in form of this bolt-on bit. The now unused `GetAfterTargetsForDefaultTargets` is deleted. Fixes #3345
Steps to reproduce
1.proj
2.proj
build with
Expected behavior
Build fails because of the
<Error>
taskActual behavior
Build succeeds:
The text was updated successfully, but these errors were encountered: