Skip to content

Migrate manifest-handling tasks to TaskEnvironment API#13177

Draft
JanProvaznik wants to merge 2 commits intodotnet:mainfrom
JanProvaznik:resource-manifests-migration
Draft

Migrate manifest-handling tasks to TaskEnvironment API#13177
JanProvaznik wants to merge 2 commits intodotnet:mainfrom
JanProvaznik:resource-manifests-migration

Conversation

@JanProvaznik
Copy link
Member

@JanProvaznik JanProvaznik commented Feb 2, 2026

Migrate manifest-handling tasks to TaskEnvironment API

Summary

This PR migrates manifest-handling MSBuild tasks to support multithreaded execution (-mt mode) by implementing the IMultiThreadableTask interface and using TaskEnvironment for thread-safe file operations.

Fixes #13172

Changes

Tasks Migrated

Task Changes
GenerateManifestBase Base class - added TaskEnvironment, replaced Directory.GetCurrentDirectory() with TaskEnvironment.ProjectDirectory, absolutized InputManifest and OutputManifest paths
GenerateApplicationManifest Absolutized TrustInfoFile path in GetRequestedExecutionLevel()
GenerateDeploymentManifest Inherits from GenerateManifestBase - no additional changes needed
ResolveManifestFiles Added attribute + interface, replaced Path.GetFullPath() calls with TaskEnvironment.GetAbsolutePath()
AddToWin32Manifest Added attribute + interface, absolutized ApplicationManifest and output paths
UpdateManifest Added attribute + interface to both .NET Framework and .NET implementations
CreateManifestResourceName Base class - added TaskEnvironment, absolutized paths before FileExists and FileStream operations
CreateCSharpManifestResourceName Added [MSBuildMultiThreadableTask] attribute
CreateVisualBasicManifestResourceName Added [MSBuildMultiThreadableTask] attribute

Test Updates

Updated unit tests to initialize TaskEnvironment:

  • AddToWin32Manifest_Tests.cs
  • CreateCSharpManifestResourceName_Tests.cs (13 test methods)
  • CreateVisualBasicManifestResourceName_Tests.cs (6 test methods)

Testing

Unit Tests

All 148 manifest-related unit tests pass:

dotnet test src/Tasks.UnitTests/Microsoft.Build.Tasks.UnitTests.csproj --filter "FullyQualifiedName~Manifest"

E2E Tests

Created 5 end-to-end test projects validating behavior in -m -mt mode:

Demo Description Result
1 CreateCSharpManifestResourceName - C# resources ✅ Matches VS MSBuild
2 CreateVisualBasicManifestResourceName - VB resources ✅ Matches VS MSBuild
3 AddToWin32Manifest - PreferNativeArm64 ✅ Matches VS MSBuild
4 Non-resx resources (JSON, XML, binary, text) ✅ Matches VS MSBuild
5 DependentUpon convention with subfolders ✅ Matches VS MSBuild

E2E test package attached: manifest-e2e-tests.zip
manifest-e2e-tests.zip

To run:

# Extract and run
Expand-Archive manifest-e2e-tests.zip -DestinationPath e2e-tests
cd e2e-tests
.\run-tests.ps1  # Full comparison with VS MSBuild
.\run-tests.ps1 -SkipVSComparison  # Quick test with dev MSBuild only

Implementation Notes

manifest-e2e-tests.zip

Pattern Used

[MSBuildMultiThreadableTask]
public class MyTask : Task, IMultiThreadableTask
{
    public TaskEnvironment TaskEnvironment { get; set; }
    
    public override bool Execute()
    {
        // Absolutize paths before file operations
        AbsolutePath absolutePath = TaskEnvironment.GetAbsolutePath(inputPath);
        if (File.Exists(absolutePath))
        {
            // Safe to use in multithreaded context
        }
    }
}

Key Replacements

  • Directory.GetCurrentDirectory()TaskEnvironment.ProjectDirectory
  • Path.GetFullPath(path)TaskEnvironment.GetAbsolutePath(path)
  • All file I/O operations now receive absolute paths

Checklist

  • Tasks annotated with [MSBuildMultiThreadableTask] attribute
  • Tasks implement IMultiThreadableTask where TaskEnvironment is used
  • All file paths absolutized before I/O operations
  • No use of Directory.GetCurrentDirectory() or Environment.CurrentDirectory
  • Unit tests updated with TaskEnvironment = TaskEnvironmentHelper.CreateForTest()
  • E2E tests verify behavior matches VS MSBuild in -m -mt mode

Copilot AI review requested due to automatic review settings February 2, 2026 13:22
@JanProvaznik JanProvaznik marked this pull request as draft February 2, 2026 13:25
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates manifest-handling MSBuild tasks to support multithreaded execution (-mt mode) by implementing the IMultiThreadableTask interface and using TaskEnvironment for thread-safe file operations.

Changes:

  • Added [MSBuildMultiThreadableTask] attribute and IMultiThreadableTask interface to 9 manifest-handling tasks
  • Replaced Directory.GetCurrentDirectory() with TaskEnvironment.ProjectDirectory and Path.GetFullPath() with TaskEnvironment.GetAbsolutePath()
  • Updated 20 unit test methods to initialize TaskEnvironment using TaskEnvironmentHelper.CreateForTest()

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
UpdateManifest.cs Added attribute/interface, absolutized paths for both .NET and .NET Framework implementations
ResolveManifestFiles.cs Added attribute/interface, replaced Path.GetFullPath() with TaskEnvironment.GetAbsolutePath()
GenerateManifestBase.cs Base class - added TaskEnvironment, replaced Directory.GetCurrentDirectory(), absolutized manifest paths
GenerateApplicationManifest.cs Absolutized TrustInfoFile and InputManifest paths using TaskEnvironment
CreateManifestResourceName.cs Base class - added attribute/interface, absolutized paths before file operations
CreateCSharpManifestResourceName.cs Added [MSBuildMultiThreadableTask] attribute
CreateVisualBasicManifestResourceName.cs Added [MSBuildMultiThreadableTask] attribute
AddToWin32Manifest.cs Added attribute/interface, absolutized ApplicationManifest and output paths
CreateCSharpManifestResourceName_Tests.cs Updated 13 test methods with TaskEnvironment initialization
CreateVisualBasicManifestResourceName_Tests.cs Updated 6 test methods with TaskEnvironment initialization
AddToWin32Manifest_Tests.cs Updated 1 test method with TaskEnvironment initialization

@JanProvaznik JanProvaznik force-pushed the resource-manifests-migration branch from 23f07ef to c947264 Compare February 2, 2026 13:34
@JanProvaznik JanProvaznik self-assigned this Feb 2, 2026
Migrate the following tasks to support multithreaded execution (-mt mode):
- GenerateManifestBase (base class for manifest generation)
- GenerateApplicationManifest
- GenerateDeploymentManifest (inherits from GenerateManifestBase)
- ResolveManifestFiles
- AddToWin32Manifest
- UpdateManifest
- CreateManifestResourceName (base class for resource naming)
- CreateCSharpManifestResourceName
- CreateVisualBasicManifestResourceName

Changes:
- Add [MSBuildMultiThreadableTask] attribute to all tasks
- Implement IMultiThreadableTask interface where TaskEnvironment is used
- Replace Directory.GetCurrentDirectory() with TaskEnvironment.ProjectDirectory
- Absolutize all paths before file I/O operations using TaskEnvironment.GetAbsolutePath()
- Update unit tests to set TaskEnvironment = TaskEnvironmentHelper.CreateForTest()

Fixes dotnet#13172
@JanProvaznik JanProvaznik force-pushed the resource-manifests-migration branch from c947264 to e5763fd Compare February 2, 2026 16:19
- Fix ResolveManifestFiles to canonicalize paths for dictionary key matching
  (GetAbsolutePath doesn't canonicalize, so wrap with Path.GetFullPath)
- Add 8 focused tests for TaskEnvironment migration:
  - Empty ItemSpec handling
  - Path with .. segments (canonicalization)
  - Forward/mixed slashes normalization
  - Batch processing error handling
  - Deep nesting and spaces in paths
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.

Migrate Manifest-handling tasks to TaskEnvironment API

1 participant