Skip to content

Migrate existing tasks to typed task parameters - #6

Draft
OvesN wants to merge 1 commit into
dev/veronikao/typed-parameter-infrastructure-fixesfrom
dev/veronikao/typed-task-parameter-examples
Draft

Migrate existing tasks to typed task parameters#6
OvesN wants to merge 1 commit into
dev/veronikao/typed-parameter-infrastructure-fixesfrom
dev/veronikao/typed-task-parameter-examples

Conversation

@OvesN

@OvesN OvesN commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Summary

Migrates three existing in-box tasks to analyzer-recommended typed parameters:

  • VerifyFileHash.FileAbsolutePath
  • ZipDirectory paths → ITaskItem<FileInfo> / ITaskItem<DirectoryInfo>
  • GetFileHash.FilesITaskItem<AbsolutePath>[]

Removes IMultiThreadableTask and TaskEnvironment from these tasks because typed binding eliminates their remaining environment usage.

Adds a task-author guide with these tasks linked as migration examples.

Testing

  • Full Debug build
  • VerifyFileHash_Tests, ZipDirectory_Tests, and GetFileHash_Tests
  • net11.0 and net472

Notes

Stacked on #7, which contains the typed-parameter infrastructure fixes and dedicated regression tests.

The public task-property type changes are intentionally source- and binary-breaking for direct .NET callers; package validation reports CP0002.

@OvesN OvesN changed the title Add typed task parameter samples Migrate existing tasks to typed task parameters Aug 11, 2026
Migrate VerifyFileHash, ZipDirectory, and GetFileHash and document the task-author workflow.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@OvesN
OvesN force-pushed the dev/veronikao/typed-task-parameter-examples branch from 89352f7 to 3f34c64 Compare August 18, 2026 13:28
@OvesN
OvesN changed the base branch from main to dev/veronikao/typed-parameter-infrastructure-fixes August 18, 2026 13:28
OvesN added a commit to dotnet/msbuild that referenced this pull request Aug 26, 2026
### Context

These issues were found while migrating real in-box tasks to typed
parameters. Direct task tests passed, but real MSBuild binding,
malformed inputs, logging, event forwarding, and binlog replay exposed
infrastructure gaps.

### Changes Made

- **Malformed typed-item paths could escape as unhandled exceptions.**
`TaskItem<T>` derives path values from `FullPath`; malformed values
could throw `InvalidOperationException`, bypassing normal
parameter-binding error handling. The constructor now converts this to
`ArgumentException`, allowing MSBuild to report MSB4030.

  Real-world reproduction:

  ```xml
  <GetFileHash Files="bad%00path" />
  ```

Before the fix, binding `ITaskItem<AbsolutePath>[]` could terminate the
node with an unhandled exception while evaluating `FullPath`. After the
fix, the project receives:

  ```text
MSB4030: "bad path" is an invalid value for the "Files" parameter of the
"GetFileHash" task.
  ```

- **Logging of `AbsolutePath` task parameters could crash or inflate
paths.**
`ItemGroupLoggingHelper` treated `AbsolutePath` as an arbitrary value
type and called `Convert.ChangeType`, which throws because
`AbsolutePath` is not `IConvertible`. Now we log absolute path
correctly, using originally passed path in logs
`AbsolutePath.OriginalValue`.

  Real-world reproduction:

  ```xml
  <VerifyFileHash File="input.txt"
Hash="3306EA2566F10A3C4071D8BADFB92A83D4F1D428555B4936D21C10F4F775B351"
/>
  ```

With task-input logging enabled, MSBuild attempted to format the bound
`AbsolutePath` and failed with:

  ```text
  InvalidCastException: Object must implement IConvertible.
  MSB4166: Child node exited prematurely.
  ```

  The fixed output remains relative:

  ```text
  Task Parameter:File=input.txt
  ```

- **Forwarded task-parameter events lost relative path values.**
`TaskParameterEventArgs` serialized `AbsolutePath` through `ToString()`,
replacing a value such as `input.txt` with its absolute form. Forwarding
now serializes `OriginalValue`.

  Real-world example:

  ```text
  Originating node: Task Parameter:File=input.txt
  Receiving node:   Task Parameter:File=C:\repo\input.txt
  ```

A distributed logger could therefore observe a different value depending
on which node produced the event. Forwarded events now retain
`input.txt`.

- **Binlog task-parameter serialization lost relative path values.**
`BuildEventArgsWriter` had the same `ToString()` behavior, so replayed
binlogs differed from live output. Binlog serialization now preserves
`OriginalValue`.

  Real-world example:

  ```text
  Live build:      Task Parameter:File=input.txt
  Replayed binlog: Task Parameter:File=C:\repo\input.txt
  ```

The live and replayed event streams now contain the same relative value.

### Testing

Each fix has a dedicated regression test:

- `FromITaskItem_InvalidPath_ThrowsArgumentException`
- `AbsolutePathTaskParameterTextUsesOriginalValue`
- `TaskParameterEventForwardingPreservesAbsolutePathOriginalValue`
- `BinaryLogSerializationPreservesAbsolutePathOriginalValue`
- `BinaryLogSerializationWritesEmptyItemSpecForDefaultAbsolutePath`

All dedicated tests pass on net11.0 and net472. The full Debug build
also succeeds.

### Notes

This PR contains only typed-parameter infrastructure fixes. The task
migrations and user documentation are in the stacked PR
[OvesN#6](OvesN#6).

Co-authored-by: Copilot Autofix powered by AI <175728472+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.

1 participant