dotnet / dotnet/msbuild

TaskAnalyzer: no diagnostic when a task constructs another ITask without propagating TaskEnvironment

Open
#14,792 0 comments 1 reaction 2 assignees Claimed by @ViktorHofer View on GitHub
Area: Analyzer
Dominant language
C#
Stars
5.5k
Forks
1.5k
Avg merge
1d 8h
Merged PRs (30d)
141

Description

### Summary

A task that constructs another task instance directly does not get `TaskEnvironment` propagated into it. MSBuild only injects into tasks it instantiates itself (`TaskExecutionHost.cs`), so the inner task silently falls back to `TaskEnvironment.Fallback` and resolves paths against the shared node's current directory.

There is no diagnostic for this, and it is invisible to every existing rule because the outer task looks fully migrated.

### Evidence

From dotnet/arcade `ExecWithRetries`:

```csharp
_runningExec = new Exec
{
BuildEngine = BuildEngine,
Command = Command,
WorkingDirectory = WorkingDirectory, // resolved by ToolTask via *its* TaskEnvironment
...
};
```

`Exec` derives from `ToolTask`, which uses `TaskEnvironment` for both `WorkingDirectory` and `GetProcessStartInfo()`. The outer task was annotated, used `TaskEnvironment` correctly everywhere in its own body, and passed the analyzer cleanly — while handing the real work to an inner task that had no environment at all.

The fix is a one-liner, which is what makes the missing diagnostic worth having:

```csharp
_runningExec = new Exec
{
BuildEngine = BuildEngine,
TaskEnvironment = TaskEnvironment, // <-- required
...
};
```

### Proposed rule

Inside a type that is `[MSBuildMultiThreadableTask]`-annotated (or implements `IMultiThreadableTask`), flag an object-creation expression whose type implements `ITask` when `TaskEnvironment` is not assigned — via object initializer, property assignment, or constructor.

Severity: Warning. The false-positive rate should be near zero, since constructing an `ITask` inside a task is rare and always needs this.

Note that `ToolTask.TaskEnvironment` is `public virtual`, so the fix is always expressible; a code fix that adds the initializer entry would be straightforward.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.