Skip to content

Fix BuildCheck CustomCheck E2E tests (NU1605 restore downgrade)#14137

Merged
baronfel merged 7 commits into
dotnet:typed-params/corefrom
OvesN:dev/veronikao/buildcheck-customcheck-restore-fix
Jun 25, 2026
Merged

Fix BuildCheck CustomCheck E2E tests (NU1605 restore downgrade)#14137
baronfel merged 7 commits into
dotnet:typed-params/corefrom
OvesN:dev/veronikao/buildcheck-customcheck-restore-fix

Conversation

@OvesN

@OvesN OvesN commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Fixes #14163

Fixes BuildCheck tests in pipeline. Investigation flow -> found log for pipeline failure. From this log I found out that the BuildCheck CustomCheck* end-to-end tests fail at restore with NU1605 (package downgrade of Microsoft.Build.Framework), so -check never runs and the expected diagnostics are never emitted.

Root cause: Microsoft.Build had gained a ProjectReference to Microsoft.Build.Utilities, so the Microsoft.Build NuGet package declared a dependency on Microsoft.Build.Utilities.Core. During the CustomCheck test-package restore that dependency resolved to an older preview and was flagged as a downgrade-as-error.

Fix: move the public TaskItem<T> from Microsoft.Build.Utilities into Microsoft.Build.Framework so it is a single shared type usable from both the engine and Utilities. This removes the Microsoft.Build -> Microsoft.Build.Utilities.Core dependency without duplicating the type. A small internal MutableTaskItem backs the value constructor (Framework cannot reference Utilities.TaskItem); it is nullable-enabled and stores metadata in an ImmutableDictionary seeded from the shared ImmutableDictionaryExtensions.EmptyMetadata (case-insensitive comparer), matching the existing Utilities.TaskItem behavior. No product behavior change.

…-> Utilities.Core dependency

Binding ITaskItem<T>/TaskItem<T> task parameters reflected over the public
Microsoft.Build.Utilities.TaskItem<T>, which required a ProjectReference from Microsoft.Build to
Microsoft.Build.Utilities. That made the Microsoft.Build NuGet package depend on
Microsoft.Build.Utilities.Core, triggering an NU1605 package-downgrade restore failure in the
BuildCheck CustomCheck end-to-end tests.

Bind via an engine-internal ITaskItem<T> implementation (StronglyTypedTaskItem<T>) for the
interface case, and via the declared concrete type reflectively otherwise, so Microsoft.Build no
longer references Microsoft.Build.Utilities.Core.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread src/Build/BackEnd/TaskExecutionHost/StronglyTypedTaskItem.cs Outdated
Comment thread src/Build/BackEnd/TaskExecutionHost/TaskExecutionHost.cs Outdated
OvesN and others added 6 commits June 24, 2026 17:27
- Instantiate StronglyTypedTaskItem<T> directly via a switch over the closed set of supported
  value types (FileInfo/DirectoryInfo/AbsolutePath) instead of MakeGenericType/GetConstructor/Invoke.
  This keeps the constructions statically visible (better for trimming/AOT) and flows type
  information instead of using heavy reflection.
- Make StronglyTypedTaskItem.cs #nullable enable and the constructor internal (no longer located
  via reflection).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Define the closed set of ITaskItem<T>/TaskItem<T> value types once in
TaskItemTypeDetector.IsSupportedValueType. Type detection and StronglyTypedTaskItem.IsPathLikeType
now defer to it, removing the duplicated {AbsolutePath, FileInfo, DirectoryInfo} lists. The
reflection-free construction switch documents that it must mirror that predicate and guards drift
with a final throw.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…+ comments

- Reject the concrete public Microsoft.Build.Utilities.TaskItem<T> as a task INPUT parameter
  (IsValidScalarInputParameter/IsValidVectorInputParameter exclude it from the value-type branch),
  so authors get the clear UnsupportedTaskParameterTypeError diagnostic instead of an opaque cast
  failure. Input binding now routes only the interface ITaskItem<T>; the concrete type stays
  supported for OUTPUTs via name-based detection.
- Rename IsSupportedValueType -> IsSupportedPathLikeType (FileInfo/DirectoryInfo are reference
  types, not value types) and soften the "single source of truth" comments to reflect that the
  engine construction switch must be kept in sync with (not "defer to") the predicate.
- Add tests: concrete-input rejection + interface-still-valid in the verifier, and a drift guard
  asserting every supported type has a construction branch.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@OvesN OvesN marked this pull request as ready for review June 25, 2026 12:53
@baronfel baronfel merged commit 7629eac into dotnet:typed-params/core Jun 25, 2026
8 of 10 checks passed
baronfel pushed a commit that referenced this pull request Jun 25, 2026
Fixes #14163

Fixes BuildCheck tests in pipeline. Investigation flow -> found
[log](https://dev.azure.com/dnceng-public/_apis/resources/Containers/54226185/CoreOnLinux%20build%20logs?itemPath=CoreOnLinux%20build%20logs%2FMicrosoft.Build.BuildCheck.UnitTests_net10.0_x64.log)
for pipeline failure. From this log I found out that the BuildCheck
`CustomCheck*` end-to-end tests fail at restore with **NU1605** (package
downgrade of `Microsoft.Build.Framework`), so `-check` never runs and
the expected diagnostics are never emitted.

**Root cause:** `Microsoft.Build` had gained a `ProjectReference` to
`Microsoft.Build.Utilities`, so the `Microsoft.Build` NuGet package
declared a dependency on `Microsoft.Build.Utilities.Core`. During the
`CustomCheck` test-package restore that dependency resolved to an older
preview and was flagged as a downgrade-as-error.

**Fix:** move the public `TaskItem<T>` from `Microsoft.Build.Utilities`
into `Microsoft.Build.Framework` so it is a single shared type usable
from both the engine and Utilities. This removes the `Microsoft.Build`
-> `Microsoft.Build.Utilities.Core` dependency without duplicating the
type. A small internal `MutableTaskItem` backs the value constructor
(Framework cannot reference `Utilities.TaskItem`); it is
nullable-enabled and stores metadata in an `ImmutableDictionary` seeded
from the shared `ImmutableDictionaryExtensions.EmptyMetadata`
(case-insensitive comparer), matching the existing `Utilities.TaskItem`
behavior. No product behavior change.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

2 participants