Open
Conversation
…support Co-authored-by: JanProvaznik <25267098+JanProvaznik@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Migrate Exec task to TaskEnvironment API
Migrate Exec task to TaskEnvironment API
Feb 2, 2026
JanProvaznik
reviewed
Feb 2, 2026
Member
JanProvaznik
left a comment
There was a problem hiding this comment.
improve testing @copilot
Co-authored-by: JanProvaznik <25267098+JanProvaznik@users.noreply.github.com>
Contributor
Author
Improved testing in dd8d189 with 4 comprehensive tests covering:
Also added |
…gging Co-authored-by: JanProvaznik <25267098+JanProvaznik@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Migrates the Exec task toward MSBuild’s TaskEnvironment API so it can participate safely in the multithreaded (/mt) execution model by avoiding reliance on global process state.
Changes:
- Mark
Execas[MSBuildMultiThreadableTask]and implementIMultiThreadableTaskwith aTaskEnvironmentproperty. - Resolve/default
WorkingDirectoryviaTaskEnvironmentand useAbsolutePathfor type-safe filesystem operations and user-facing logging. - Update/unit-test infrastructure: add a multithreaded
TaskEnvironmenttest helper and update/addExectests to supplyTaskEnvironment.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/UnitTests.Shared/TaskEnvironmentHelper.cs | Adds CreateMultithreadedForTest helper to construct a TaskEnvironment backed by the multithreaded driver for /mt-style tests. |
| src/Tasks/Exec.cs | Converts Exec to an IMultiThreadableTask, switches working directory handling to TaskEnvironment, and uses AbsolutePath for safety/clarity. |
| src/Tasks.UnitTests/Exec_Tests.cs | Ensures tests set TaskEnvironment for Exec instances and adds new tests around working directory resolution behavior. |
- Fix ExecUsesProjectDirectoryAsDefaultWorkingDirectory test to use MultiThreadedTaskEnvironmentDriver with different process CWD - Fix ExecResolvesRelativeWorkingDirectoryWithMultiProcessDriver test to verify correct base directory resolution - Update stale comment about working directory default - Override GetProcessStartInfo to inject TaskEnvironment's virtualized environment variables into spawned processes (critical for /mt mode)
On macOS, /var is a symlink to /private/var. Directory.GetCurrentDirectory() resolves symlinks, so comparing it with the raw temp path fails. Read back the CWD immediately after setting it to get the resolved path for comparison.
…ility The base ToolTask.GetProcessStartInfo applies both the obsolete EnvironmentOverride and EnvironmentVariables. After clearing the environment to replace it with TaskEnvironment's, we must re-apply both — not just EnvironmentVariables — for compatibility with any class deriving from Exec that overrides EnvironmentOverride.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
The Exec task needs to support MSBuild's multithreaded execution model. Tasks that rely on global process state (working directory, environment variables) are not thread-safe and cannot run in parallel.
Changes Made
[MSBuildMultiThreadableTask]attribute and implementIMultiThreadableTaskTaskEnvironmentproperty for thread-safe access to execution environmentDirectory.GetCurrentDirectory()withTaskEnvironment.ProjectDirectoryTaskEnvironment.GetAbsolutePath(WorkingDirectory)for relative path resolution_workingDirectoryfield fromstringtoAbsolutePathtype for type safety.OriginalValuefor logging (user-facing messages) and.Valuefor file system operationsTaskEnvironment = TaskEnvironmentHelper.CreateForTest()TaskEnvironmentHelper.CreateMultithreadedForTest(projectDirectory)helper method for testing with the multithreaded driverTesting
Added 4 comprehensive tests covering both TaskEnvironment drivers and multithreaded scenarios:
ExecResolvesRelativeWorkingDirectoryWithMultiProcessDriver- Tests relative WorkingDirectory resolution with MultiProcessDriverExecUsesProjectDirectoryAsDefaultWorkingDirectory- Tests default working directory when not specifiedExecHandlesAbsoluteWorkingDirectory- Tests absolute WorkingDirectory pathsExecResolvesRelativeWorkingDirectoryRelativeToProjectDirectory- UsesMultiThreadedTaskEnvironmentDriverto test relative path resolution when process CWD differs from project directory (simulating multithreaded mode)All 49 Exec tests pass (1 pre-existing Windows-only failure on Linux, 2 correctly skipped)
Notes
Environment.GetEnvironmentVariable("ComSpec")inCommandProcessorPathis unchanged—it's system-level initialization that occurs once before any task execution, and on Unix it returns just "sh" (not a rooted path).\\server\share) work correctly withAbsolutePathsince they are fully qualified paths andPath.IsPathFullyQualified()returnstruefor them.Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.