From dd78feb38fc8e2fdef61aeeeecbd3f6b5a9cf1b2 Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Wed, 16 Sep 2026 17:33:23 -0700 Subject: [PATCH 1/3] Add ContinueOnError support for DispatchToInnerBuilds target --- .../CrossTargetingTsrgets_Tests.cs | 79 +++++++++++++++++++ .../Microsoft.Common.CrossTargeting.targets | 9 ++- 2 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 src/Build.UnitTests/CrossTargetingTsrgets_Tests.cs diff --git a/src/Build.UnitTests/CrossTargetingTsrgets_Tests.cs b/src/Build.UnitTests/CrossTargetingTsrgets_Tests.cs new file mode 100644 index 00000000000..1ce644f36d9 --- /dev/null +++ b/src/Build.UnitTests/CrossTargetingTsrgets_Tests.cs @@ -0,0 +1,79 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using Microsoft.Build.UnitTests; +using Xunit; + +namespace Microsoft.Build.UnitTests +{ + public class CrossTargetingTargetsTests + { + private readonly ITestOutputHelper _output; + + public CrossTargetingTargetsTests(ITestOutputHelper output) + { + _output = output; + } + + [Theory] + [InlineData("WarnAndContinue", true, true)] + [InlineData("true", true, true)] + [InlineData("ErrorAndContinue", false, true)] + [InlineData("ErrorAndStop ", false, false)] + [InlineData("false", false, false)] + [InlineData(null, false, false)] + public void DispatchToInnerBuildsCanContinueOnError(string? continueOnError, bool expectSuccess, bool expectAfterDispatch) + { + using TestEnvironment env = TestEnvironment.Create(_output); + TransientTestFile nugetTargets = env.CreateFile("NuGet.targets", ""); + + TransientTestProjectWithFiles project = env.CreateTestProjectWithFiles(""" + + + failing;successful + InnerBuild + false + + + + + + + + + + + + + """); + + var globalProperties = new Dictionary + { + ["NuGetRestoreTargets"] = nugetTargets.Path, + }; + + if (continueOnError is not null) + { + globalProperties["DispatchToInnerBuildsContinueOnError"] = continueOnError; + } + + MockLogger logger = expectSuccess + ? project.BuildProjectExpectSuccess(globalProperties) + : project.BuildProjectExpectFailure(globalProperties); + + logger.AssertLogContains("INNER_FAILURE"); + + if (expectAfterDispatch) + { + logger.AssertLogContains("AFTER_DISPATCH"); + } + else + { + logger.AssertLogDoesntContain("AFTER_DISPATCH"); + } + } + } +} \ No newline at end of file diff --git a/src/Tasks/Microsoft.Common.CrossTargeting.targets b/src/Tasks/Microsoft.Common.CrossTargeting.targets index 1c9d0c555b1..7018a9fee38 100644 --- a/src/Tasks/Microsoft.Common.CrossTargeting.targets +++ b/src/Tasks/Microsoft.Common.CrossTargeting.targets @@ -121,7 +121,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. @(InnerOutput) - The combined output items of the inner targets across all target frameworks.. ============================================================ - --> + --> @@ -129,11 +129,16 @@ Copyright (C) Microsoft Corporation. All rights reserved. + BuildInParallel="$(BuildInParallel)" + ContinueOnError="$(DispatchToInnerBuildsContinueOnError)"> + + false + + + -->