Migrate Microsoft.TestPlatform.CLI from nuspec to MSBuild pack (final batch) - #16149
Merged
Jakub Jareš (nohwnd) merged 13 commits intoJun 24, 2026
Conversation
Remove the hand-crafted .nuspec file for Microsoft.TestPlatform.VsTestConsole.TranslationLayer and use MSBuild pack properties instead. - Remove NuspecFile/NuspecBasePath/NuspecProperty items - ObjectModel stays a real NuGet dependency; Common, CoreUtilities and CommunicationUtilities are marked PrivateAssets=all (bundled, not deps) - Use TargetsForTfmSpecificContentInPackage to bundle Common and CommunicationUtilities DLLs plus satellite resources (incl. CoreUtilities resources) and the TranslationLayer XML doc into lib/<tfm> - Add PackageReadmeFile and None items for README.md and ThirdPartyNotices.txt - Delete Microsoft.TestPlatform.VsTestConsole.TranslationLayer.nuspec Package contents verified identical to the previous nuspec output (175 files). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the hand-crafted .nuspec file for Microsoft.TestPlatform.Internal.Uwp and use MSBuild pack properties instead. - Remove NuspecFile/NuspecBasePath properties - Set IncludeBuildOutput=false (the package ships bundled DLLs, not its own Internal.Uwp assembly) and SuppressDependenciesWhenPacking=true (no deps) - Mark both ProjectReferences PrivateAssets=all - Add NoWarn=NU5128 (bundled-only package with an empty dependency group) - Use TargetsForTfmSpecificContentInPackage to bundle ObjectModel, CoreUtilities, CrossPlatEngine, CommunicationUtilities, Utilities, Common and PlatformAbstractions DLLs plus ObjectModel and CoreUtilities satellite resources into lib/netstandard2.0 - Add PackageReadmeFile and None item for README.md - Delete Microsoft.TestPlatform.Internal.Uwp.nuspec Package contents verified identical to the previous nuspec output (39 files). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the hand-crafted .nuspec file for Microsoft.NET.Test.Sdk and use MSBuild pack properties instead. - Multi-target net8.0;net462 so pack emits the per-framework dependency groups - Express dependencies via ProjectReferences to the sibling packable projects: net8.0 depends on TestHost + CodeCoverage, net462 on CodeCoverage only - IncludeBuildOutput=false (build/targets-only package, ships no own assembly) and NoWarn=NU5128 - Ship the props/targets into build\<tfm> and buildMultiTargeting\<tfm> and the _._ lib stubs via Pack-enabled None items with explicit PackagePath - Add PackageReadmeFile for README.md - Delete Microsoft.NET.Test.Sdk.nuspec Package file list verified identical to the previous nuspec output (26 files) and the net8.0/net462 dependency groups match. The only difference is that the old nuspec's empty native0.0 dependency group is no longer emitted: MSBuild pack only generates dependency groups for real build target frameworks. This is behaviorally equivalent because the group carried no dependencies and lib/native/_._ still marks the package compatible with native test projects. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the hand-crafted .nuspec file for Microsoft.CodeCoverage and use MSBuild pack properties instead. - IncludeBuildOutput=false (the package ships only build\ tooling and a bundled content tree, not its own assembly) and SuppressDependenciesWhenPacking=true - Ship README.md, ThirdPartyNotices.txt (root + build\netstandard2.0) and the Microsoft.CodeCoverage props/targets via Pack-enabled None items - Bundle the Microsoft.Internal.CodeCoverage content tree (code coverage tools, instrumentation engines and shims, pre-laid-out as build\ + lib\ + PACKAGE.md) at the package root via TargetsForTfmSpecificContentInPackage. This runs in the inner per-TFM build because the package path property is only defined there, gated to a single TFM so the content ships once, with PackagePath=%(RecursiveDir) preserving the folder structure - NoWarn the package-analysis warnings that fire for a build\-only tooling package - Delete Microsoft.CodeCoverage.nuspec Package file list verified identical to the previous nuspec output (81 files). The only difference is the dependency metadata: the old nuspec declared two empty dependency groups (net462, net8.0); MSBuild pack with SuppressDependenciesWhenPacking omits the <dependencies> element entirely. This is behaviorally equivalent because the package has no NuGet dependencies and the old groups were empty. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the hand-crafted .nuspec file for Microsoft.TestPlatform.TestHost and use
MSBuild pack properties instead.
- IncludeBuildOutput=false (the package bundles the testhost runtime output, not
its own TestHost assembly)
- ObjectModel is a real net8.0 dependency (conditioned to the .NET build so the
net462 group stays empty, matching the old nuspec)
- testhost / testhost.x86 project references are kept to produce the bundled
output but removed from the resolved dependency list (PrivateAssets is not
honored for these exe references), so they do not leak as NuGet dependencies
- Bundle via TargetsForTfmSpecificContentInPackage (net8.0 inner build): platform
assemblies + CommunicationUtilities/CrossPlatEngine/Common satellites into
lib\net8.0, msdia140 natives into lib\net8.0\{x86,x64,arm64}, the testhost
launchers into build\net8.0\{x64,x86} and the props/targets into build\net8.0
- Ship README.md, ThirdPartyNotices.txt and the lib\net462\_._ stub via Pack items
- Delete Microsoft.TestPlatform.TestHost.nuspec
Package contents and dependency groups verified identical to the previous nuspec
output (65 files; net8.0 -> ObjectModel, net462 empty).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the hand-written 535-line Microsoft.TestPlatform.nuspec with MSBuild pack: the 487 <file> elements are translated to <None Pack=true> items that map the same build outputs to the same package paths, producing a byte-identical 553-file layout (verified against the pre-change package). - Remove NuspecFile/NuspecBasePath and the NuspecProperty ItemGroup - IncludeBuildOutput=false (container project, ships no assembly of its own) - SuppressDependenciesWhenPacking=true (package has no NuGet dependencies) - Add PackageReadmeFile and explicit None items for README, LICENSE_VS.txt (PackageLicenseFullPath is not auto-packed) and ThirdPartyNotices.txt - Clear the inherited MIT PackageLicenseExpression so the file license applies - NoWarn NU5100/NU5109/NU5118/NU5128 (assemblies/content outside lib, no deps) - Recursive ** globs reproduced with folder PackagePath (RecursiveDir preserved) - Delete Microsoft.TestPlatform.nuspec Pack now auto-adds a benign <frameworkAssemblies> entry (System.Runtime.InteropServices.RuntimeInformation for net48/net481) that the old nuspec omitted; it does not affect the packaged files. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…d pack Replace the hand-written 657-line Microsoft.TestPlatform.Portable.nuspec with MSBuild pack: the 601 <file> elements are translated to <None Pack=true> items that map the same build outputs to the same package paths, producing a byte-identical 608-file layout (verified against the pre-change package). - Remove NuspecFile/NuspecBasePath and the NuspecProperty ItemGroup - IncludeBuildOutput=false, SuppressDependenciesWhenPacking=true (container, no deps) - Add PackageReadmeFile and explicit None items for README and LICENSE_VS.txt - Clear the inherited MIT PackageLicenseExpression so the file license applies - NoWarn NU5100/NU5109/NU5118 (NU5128 was already present) - Delete Microsoft.TestPlatform.Portable.nuspec Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a comment documenting the existing UTF-8 console-encoding behavior. This is a comment-only change with no functional impact; it exists to exercise the full CI pipeline (code-path checks are skipped for doc-only changes). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…msbuild-pack-final-batch
Replaces the three hand-written nuspec variants (Microsoft.TestPlatform.CLI.nuspec / .sourcebuild.nuspec / .sourcebuild.product.nuspec) with csproj-based packaging, completing the migration started in microsoft#16125 / microsoft#16132 (issue microsoft#15650). Each <file src target> element is translated to a <None Pack="true" PackagePath="..."> item. Because everything ships under contentFiles, every content item carries BuildAction=None / PackageCopyToOutput=true / PackageFlatten=false so pack emits per-file <contentFiles> entries that are functionally equivalent to the original generic "**/*.*" copyToOutput/flatten/buildAction wildcard. The Windows full content (net10.0 layout + net46x/net4x TestHostNetFramework hosts) is gated on (!DotNetBuildSourceOnly and Windows); the cross-platform $(NetCurrent) content (mirroring the two identical sourcebuild nuspecs) is gated on (DotNetBuildSourceOnly or non-Windows). Container settings IncludeBuildOutput=false and SuppressDependenciesWhenPacking=true are used (the package ships no assembly of its own and has no NuGet dependencies). The existing ProjectReference, PackageReference and CopyFiles staging logic is unchanged. Validation: a clean `build.cmd -c Release -pack` produces a CLI package whose file list is byte-for-byte identical to the pre-migration package (483 entries, no eng/expected-*.json drift). The auto-added <frameworkAssemblies> entry is benign and not part of the file-list oracle. The sourcebuild/VMR variants only execute under -DotNetBuildSourceOnly / VMR builds and cannot be exercised by a local Windows build; they are translated faithfully but validated only by inspection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Azat Mukhametshin (azat-msft)
marked this pull request as draft
June 22, 2026 10:43
Copilot started reviewing on behalf of
Azat Mukhametshin (azat-msft)
June 22, 2026 10:45
View session
Contributor
There was a problem hiding this comment.
Pull request overview
This PR completes the migration of Microsoft.TestPlatform.CLI (and the remaining container packages in this stacked branch) from hand-authored .nuspec files to SDK-style MSBuild packing, translating file lists into Pack="true" items and removing the legacy nuspec variants.
Changes:
- Migrates
Microsoft.TestPlatform.CLIpackaging to csproj-authoredcontentFiles(withPackageCopyToOutput/PackageFlattensemantics) and deletes the three CLI.nuspecvariants. - Migrates remaining container/tooling packages (e.g.,
Microsoft.CodeCoverage,Microsoft.NET.Test.Sdk,TestHost,Internal.Uwp, TranslationLayer) off.nuspecto MSBuild pack patterns. - Minor comment addition in
vstest.consoleclarifying UTF-8 console encoding behavior behind a feature flag.
Reviewed changes
Copilot reviewed 17 out of 19 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/vstest.console/Program.cs | Adds an explanatory comment about UTF-8 console output being controlled by a feature flag. |
| src/package/Microsoft.TestPlatform/Microsoft.TestPlatform.nuspec | Removes legacy nuspec as part of MSBuild-pack migration. |
| src/package/Microsoft.TestPlatform.TestHost/Microsoft.TestPlatform.TestHost.nuspec | Removes legacy nuspec as part of MSBuild-pack migration. |
| src/package/Microsoft.TestPlatform.TestHost/Microsoft.TestPlatform.TestHost.csproj | Switches TestHost package authoring to MSBuild pack, bundling runtime outputs via TargetsForTfmSpecificContentInPackage. |
| src/package/Microsoft.TestPlatform.Portable/Microsoft.TestPlatform.Portable.nuspec | Removes legacy nuspec as part of MSBuild-pack migration. |
| src/package/Microsoft.TestPlatform.Internal.Uwp/Microsoft.TestPlatform.Internal.Uwp.nuspec | Removes legacy nuspec as part of MSBuild-pack migration. |
| src/package/Microsoft.TestPlatform.Internal.Uwp/Microsoft.TestPlatform.Internal.Uwp.csproj | Switches Internal.Uwp to MSBuild pack bundling (no build output, no dependencies). |
| src/package/Microsoft.TestPlatform.CLI/Microsoft.TestPlatform.CLI.nuspec | Removes legacy nuspec (Windows variant) as part of CLI migration. |
| src/package/Microsoft.TestPlatform.CLI/Microsoft.TestPlatform.CLI.sourcebuild.nuspec | Removes legacy nuspec (source-build variant) as part of CLI migration. |
| src/package/Microsoft.TestPlatform.CLI/Microsoft.TestPlatform.CLI.sourcebuild.product.nuspec | Removes legacy nuspec (VMR variant) as part of CLI migration. |
| src/package/Microsoft.NET.Test.Sdk/Microsoft.NET.Test.Sdk.nuspec | Removes legacy nuspec as part of MSBuild-pack migration. |
| src/package/Microsoft.NET.Test.Sdk/Microsoft.NET.Test.Sdk.csproj | Switches the SDK package to MSBuild pack with explicit build/buildMultiTargeting assets and per-TFM deps. |
| src/package/Microsoft.CodeCoverage/Microsoft.CodeCoverage.nuspec | Removes legacy nuspec as part of MSBuild-pack migration. |
| src/package/Microsoft.CodeCoverage/Microsoft.CodeCoverage.csproj | Switches CodeCoverage tooling package to MSBuild pack, including bundled Microsoft.Internal.CodeCoverage content. |
| src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Microsoft.TestPlatform.VsTestConsole.TranslationLayer.nuspec | Removes legacy nuspec as part of MSBuild-pack migration. |
| src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Microsoft.TestPlatform.VsTestConsole.TranslationLayer.csproj | Switches TranslationLayer to MSBuild pack while bundling select assemblies/resources into the nupkg. |
…time The initial CLI migration used MSBuild item wildcards in static <ItemGroup>s (`net462\System*.dll` for the Windows variant and the `**\*.resources.dll` source-build resource globs). Static item wildcards are expanded during project *evaluation*, which happens before the referenced projects' outputs have been copied into this project's OutputPath. On a clean CI build the folders are empty at that point, so the wildcards matched nothing and the Windows CLI package shipped 100 fewer files (383 instead of 483), failing verify-nupkgs.ps1. Locally the bug was masked because a prior build had already populated the output folders. Explicit (non-wildcard) <None> includes are literal items resolved at pack time, so: - The Windows `net462\System*.dll` glob is expanded into explicit <None> items (matching the pattern already used by Microsoft.TestPlatform.csproj). - The source-build localized satellite resources (which cannot be enumerated from a Windows build) are moved into a TargetsForTfmSpecificContentInPackage target, the repo's established pack-time content hook (see Microsoft.CodeCoverage.csproj). It is gated to $(NetCurrent) so the content is added exactly once, and %(RecursiveDir) preserves the language sub-folders. Validated with a clean `build.cmd -c Release -pack` (artifacts/bin and artifacts/packages deleted first to reproduce the CI state): the CLI package is again byte-for-byte identical to the pre-migration package (483 entries) with no eng/expected-*.json drift. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot started reviewing on behalf of
Azat Mukhametshin (azat-msft)
June 22, 2026 15:38
View session
…-time TFM scoping Addresses PR review feedback and a package-diff regression. 1. Casing fix (real bug). The runtime provider assembly is `Microsoft.TestPlatform.TestHostRuntimeProvider.dll` (capital `H`), but two `<None Include>` items copied a casing typo from the old nuspec's `src` attribute and used lowercase `TesthostRuntimeProvider.dll`. NuGet nuspec packing used the real on-disk name (capital `H`), whereas MSBuild pack ships the literal `Include` casing, so the new Windows package shipped the DLL as `Testhost...` and on case-sensitive filesystems (source-build / non-Windows) the literal include would not match the built file at all, dropping the DLL. Both occurrences (net10.0 Windows item and the $(NetCurrent) source-build item) are corrected to `TestHost`. The earlier byte-identical check missed this because PowerShell's Compare-Object is case-insensitive; an ordinal comparison now shows the package matches the pre-migration layout exactly (483 entries, zero case-sensitive diffs). 2. Pack-time resource globs (review comments, no code change needed). The reviewer flagged that the `$(OutputPath)**` resource globs in `_IncludeCliSourceBuildResources` could span other TFM subfolders. They cannot: the target runs via TargetsForTfmSpecificContentInPackage in the inner per-TFM build, where `$(OutputPath)` already resolves to the per-TFM directory (e.g. `...\Release\net11.0\`), so the globs only ever match that single TFM and `%(RecursiveDir)` is just the language folder (cs, de, ...). Verified empirically. Added a comment documenting this. Validated with a clean `build.cmd -c Release -pack` (artifacts deleted first): build succeeds, verification passes, no eng/expected-*.json drift, CLI package byte/layout-identical to the pre-migration package under an ordinal (case-sensitive) comparison. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Azat Mukhametshin (azat-msft)
marked this pull request as ready for review
June 23, 2026 14:25
Copilot started reviewing on behalf of
Azat Mukhametshin (azat-msft)
June 23, 2026 14:26
View session
|
|
||
| internal static int Run(string[]? args, UiLanguageOverride uiLanguageOverride) | ||
| { | ||
| // Console output is switched to UTF-8 unless the feature flag opts out. |
Member
There was a problem hiding this comment.
Suggested change
| // Console output is switched to UTF-8 unless the feature flag opts out. |
Unrelated.
Jakub Jareš (nohwnd)
approved these changes
Jun 24, 2026
github-actions Bot
added a commit
to azat-msft/vstest
that referenced
this pull request
Jun 24, 2026
… batch) (microsoft#16149) * Migrate TranslationLayer package from nuspec to MSBuild pack Remove the hand-crafted .nuspec file for Microsoft.TestPlatform.VsTestConsole.TranslationLayer and use MSBuild pack properties instead. - Remove NuspecFile/NuspecBasePath/NuspecProperty items - ObjectModel stays a real NuGet dependency; Common, CoreUtilities and CommunicationUtilities are marked PrivateAssets=all (bundled, not deps) - Use TargetsForTfmSpecificContentInPackage to bundle Common and CommunicationUtilities DLLs plus satellite resources (incl. CoreUtilities resources) and the TranslationLayer XML doc into lib/<tfm> - Add PackageReadmeFile and None items for README.md and ThirdPartyNotices.txt - Delete Microsoft.TestPlatform.VsTestConsole.TranslationLayer.nuspec Package contents verified identical to the previous nuspec output (175 files). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Migrate Internal.Uwp package from nuspec to MSBuild pack Remove the hand-crafted .nuspec file for Microsoft.TestPlatform.Internal.Uwp and use MSBuild pack properties instead. - Remove NuspecFile/NuspecBasePath properties - Set IncludeBuildOutput=false (the package ships bundled DLLs, not its own Internal.Uwp assembly) and SuppressDependenciesWhenPacking=true (no deps) - Mark both ProjectReferences PrivateAssets=all - Add NoWarn=NU5128 (bundled-only package with an empty dependency group) - Use TargetsForTfmSpecificContentInPackage to bundle ObjectModel, CoreUtilities, CrossPlatEngine, CommunicationUtilities, Utilities, Common and PlatformAbstractions DLLs plus ObjectModel and CoreUtilities satellite resources into lib/netstandard2.0 - Add PackageReadmeFile and None item for README.md - Delete Microsoft.TestPlatform.Internal.Uwp.nuspec Package contents verified identical to the previous nuspec output (39 files). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Migrate NET.Test.Sdk package from nuspec to MSBuild pack Remove the hand-crafted .nuspec file for Microsoft.NET.Test.Sdk and use MSBuild pack properties instead. - Multi-target net8.0;net462 so pack emits the per-framework dependency groups - Express dependencies via ProjectReferences to the sibling packable projects: net8.0 depends on TestHost + CodeCoverage, net462 on CodeCoverage only - IncludeBuildOutput=false (build/targets-only package, ships no own assembly) and NoWarn=NU5128 - Ship the props/targets into build\<tfm> and buildMultiTargeting\<tfm> and the _._ lib stubs via Pack-enabled None items with explicit PackagePath - Add PackageReadmeFile for README.md - Delete Microsoft.NET.Test.Sdk.nuspec Package file list verified identical to the previous nuspec output (26 files) and the net8.0/net462 dependency groups match. The only difference is that the old nuspec's empty native0.0 dependency group is no longer emitted: MSBuild pack only generates dependency groups for real build target frameworks. This is behaviorally equivalent because the group carried no dependencies and lib/native/_._ still marks the package compatible with native test projects. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Migrate CodeCoverage package from nuspec to MSBuild pack Remove the hand-crafted .nuspec file for Microsoft.CodeCoverage and use MSBuild pack properties instead. - IncludeBuildOutput=false (the package ships only build\ tooling and a bundled content tree, not its own assembly) and SuppressDependenciesWhenPacking=true - Ship README.md, ThirdPartyNotices.txt (root + build\netstandard2.0) and the Microsoft.CodeCoverage props/targets via Pack-enabled None items - Bundle the Microsoft.Internal.CodeCoverage content tree (code coverage tools, instrumentation engines and shims, pre-laid-out as build\ + lib\ + PACKAGE.md) at the package root via TargetsForTfmSpecificContentInPackage. This runs in the inner per-TFM build because the package path property is only defined there, gated to a single TFM so the content ships once, with PackagePath=%(RecursiveDir) preserving the folder structure - NoWarn the package-analysis warnings that fire for a build\-only tooling package - Delete Microsoft.CodeCoverage.nuspec Package file list verified identical to the previous nuspec output (81 files). The only difference is the dependency metadata: the old nuspec declared two empty dependency groups (net462, net8.0); MSBuild pack with SuppressDependenciesWhenPacking omits the <dependencies> element entirely. This is behaviorally equivalent because the package has no NuGet dependencies and the old groups were empty. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Migrate TestHost package from nuspec to MSBuild pack Remove the hand-crafted .nuspec file for Microsoft.TestPlatform.TestHost and use MSBuild pack properties instead. - IncludeBuildOutput=false (the package bundles the testhost runtime output, not its own TestHost assembly) - ObjectModel is a real net8.0 dependency (conditioned to the .NET build so the net462 group stays empty, matching the old nuspec) - testhost / testhost.x86 project references are kept to produce the bundled output but removed from the resolved dependency list (PrivateAssets is not honored for these exe references), so they do not leak as NuGet dependencies - Bundle via TargetsForTfmSpecificContentInPackage (net8.0 inner build): platform assemblies + CommunicationUtilities/CrossPlatEngine/Common satellites into lib\net8.0, msdia140 natives into lib\net8.0\{x86,x64,arm64}, the testhost launchers into build\net8.0\{x64,x86} and the props/targets into build\net8.0 - Ship README.md, ThirdPartyNotices.txt and the lib\net462\_._ stub via Pack items - Delete Microsoft.TestPlatform.TestHost.nuspec Package contents and dependency groups verified identical to the previous nuspec output (65 files; net8.0 -> ObjectModel, net462 empty). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Migrate Microsoft.TestPlatform package from nuspec to MSBuild pack Replace the hand-written 535-line Microsoft.TestPlatform.nuspec with MSBuild pack: the 487 <file> elements are translated to <None Pack=true> items that map the same build outputs to the same package paths, producing a byte-identical 553-file layout (verified against the pre-change package). - Remove NuspecFile/NuspecBasePath and the NuspecProperty ItemGroup - IncludeBuildOutput=false (container project, ships no assembly of its own) - SuppressDependenciesWhenPacking=true (package has no NuGet dependencies) - Add PackageReadmeFile and explicit None items for README, LICENSE_VS.txt (PackageLicenseFullPath is not auto-packed) and ThirdPartyNotices.txt - Clear the inherited MIT PackageLicenseExpression so the file license applies - NoWarn NU5100/NU5109/NU5118/NU5128 (assemblies/content outside lib, no deps) - Recursive ** globs reproduced with folder PackagePath (RecursiveDir preserved) - Delete Microsoft.TestPlatform.nuspec Pack now auto-adds a benign <frameworkAssemblies> entry (System.Runtime.InteropServices.RuntimeInformation for net48/net481) that the old nuspec omitted; it does not affect the packaged files. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Migrate Microsoft.TestPlatform.Portable package from nuspec to MSBuild pack Replace the hand-written 657-line Microsoft.TestPlatform.Portable.nuspec with MSBuild pack: the 601 <file> elements are translated to <None Pack=true> items that map the same build outputs to the same package paths, producing a byte-identical 608-file layout (verified against the pre-change package). - Remove NuspecFile/NuspecBasePath and the NuspecProperty ItemGroup - IncludeBuildOutput=false, SuppressDependenciesWhenPacking=true (container, no deps) - Add PackageReadmeFile and explicit None items for README and LICENSE_VS.txt - Clear the inherited MIT PackageLicenseExpression so the file license applies - NoWarn NU5100/NU5109/NU5118 (NU5128 was already present) - Delete Microsoft.TestPlatform.Portable.nuspec Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add clarifying comment in vstest.console Program.Run (no-op) Add a comment documenting the existing UTF-8 console-encoding behavior. This is a comment-only change with no functional impact; it exists to exercise the full CI pipeline (code-path checks are skipped for doc-only changes). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Migrate Microsoft.TestPlatform.CLI package from nuspec to MSBuild pack Replaces the three hand-written nuspec variants (Microsoft.TestPlatform.CLI.nuspec / .sourcebuild.nuspec / .sourcebuild.product.nuspec) with csproj-based packaging, completing the migration started in microsoft#16125 / microsoft#16132 (issue microsoft#15650). Each <file src target> element is translated to a <None Pack="true" PackagePath="..."> item. Because everything ships under contentFiles, every content item carries BuildAction=None / PackageCopyToOutput=true / PackageFlatten=false so pack emits per-file <contentFiles> entries that are functionally equivalent to the original generic "**/*.*" copyToOutput/flatten/buildAction wildcard. The Windows full content (net10.0 layout + net46x/net4x TestHostNetFramework hosts) is gated on (!DotNetBuildSourceOnly and Windows); the cross-platform $(NetCurrent) content (mirroring the two identical sourcebuild nuspecs) is gated on (DotNetBuildSourceOnly or non-Windows). Container settings IncludeBuildOutput=false and SuppressDependenciesWhenPacking=true are used (the package ships no assembly of its own and has no NuGet dependencies). The existing ProjectReference, PackageReference and CopyFiles staging logic is unchanged. Validation: a clean `build.cmd -c Release -pack` produces a CLI package whose file list is byte-for-byte identical to the pre-migration package (483 entries, no eng/expected-*.json drift). The auto-added <frameworkAssemblies> entry is benign and not part of the file-list oracle. The sourcebuild/VMR variants only execute under -DotNetBuildSourceOnly / VMR builds and cannot be exercised by a local Windows build; they are translated faithfully but validated only by inspection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CLI pack: resolve content wildcards at pack time, not evaluation time The initial CLI migration used MSBuild item wildcards in static <ItemGroup>s (`net462\System*.dll` for the Windows variant and the `**\*.resources.dll` source-build resource globs). Static item wildcards are expanded during project *evaluation*, which happens before the referenced projects' outputs have been copied into this project's OutputPath. On a clean CI build the folders are empty at that point, so the wildcards matched nothing and the Windows CLI package shipped 100 fewer files (383 instead of 483), failing verify-nupkgs.ps1. Locally the bug was masked because a prior build had already populated the output folders. Explicit (non-wildcard) <None> includes are literal items resolved at pack time, so: - The Windows `net462\System*.dll` glob is expanded into explicit <None> items (matching the pattern already used by Microsoft.TestPlatform.csproj). - The source-build localized satellite resources (which cannot be enumerated from a Windows build) are moved into a TargetsForTfmSpecificContentInPackage target, the repo's established pack-time content hook (see Microsoft.CodeCoverage.csproj). It is gated to $(NetCurrent) so the content is added exactly once, and %(RecursiveDir) preserves the language sub-folders. Validated with a clean `build.cmd -c Release -pack` (artifacts/bin and artifacts/packages deleted first to reproduce the CI state): the CLI package is again byte-for-byte identical to the pre-migration package (483 entries) with no eng/expected-*.json drift. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CLI package: correct TestHostRuntimeProvider casing; clarify pack-time TFM scoping Addresses PR review feedback and a package-diff regression. 1. Casing fix (real bug). The runtime provider assembly is `Microsoft.TestPlatform.TestHostRuntimeProvider.dll` (capital `H`), but two `<None Include>` items copied a casing typo from the old nuspec's `src` attribute and used lowercase `TesthostRuntimeProvider.dll`. NuGet nuspec packing used the real on-disk name (capital `H`), whereas MSBuild pack ships the literal `Include` casing, so the new Windows package shipped the DLL as `Testhost...` and on case-sensitive filesystems (source-build / non-Windows) the literal include would not match the built file at all, dropping the DLL. Both occurrences (net10.0 Windows item and the $(NetCurrent) source-build item) are corrected to `TestHost`. The earlier byte-identical check missed this because PowerShell's Compare-Object is case-insensitive; an ordinal comparison now shows the package matches the pre-migration layout exactly (483 entries, zero case-sensitive diffs). 2. Pack-time resource globs (review comments, no code change needed). The reviewer flagged that the `$(OutputPath)**` resource globs in `_IncludeCliSourceBuildResources` could span other TFM subfolders. They cannot: the target runs via TargetsForTfmSpecificContentInPackage in the inner per-TFM build, where `$(OutputPath)` already resolves to the per-TFM directory (e.g. `...\Release\net11.0\`), so the globs only ever match that single TFM and `%(RecursiveDir)` is just the language folder (cs, de, ...). Verified empirically. Added a comment documenting this. Validated with a clean `build.cmd -c Release -pack` (artifacts deleted first): build succeeds, verification passes, no eng/expected-*.json drift, CLI package byte/layout-identical to the pre-migration package under an ordinal (case-sensitive) comparison. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.
Summary
Completes the migration from hand-written
.nuspecfiles to MSBuild pack (csproj-basedpackaging), per #15650. This is the final batch: it migrates the last remaining package,
Microsoft.TestPlatform.CLI, which was explicitly deferred by the earlier batches(#16125 simple packages, #16132 container packages) because it was the riskiest.
What changed for
Microsoft.TestPlatform.CLIThe project previously selected one of three hand-written nuspecs via
<NuspecFile>conditions:Microsoft.TestPlatform.CLI.nuspecnet10.0layout + .NET Framework test hosts)Microsoft.TestPlatform.CLI.sourcebuild.nuspec$(NetCurrent)layout)Microsoft.TestPlatform.CLI.sourcebuild.product.nuspecAll three are replaced by csproj packaging:
<file src=".." target=".." />element becomes a<None Pack="true" PackagePath="..">item.contentFiles, each content item carriesBuildAction=None/PackageCopyToOutput=true/PackageFlatten=false, so pack emits per-file<contentFiles>entries that are functionally equivalent to the original generic<contentFiles><files include="**/*.*" copyToOutput="true" flatten="false" buildAction="None" /></contentFiles>wildcard.
'$(DotNetBuildSourceOnly)' != 'true' and '$(OS)' == 'Windows_NT';the cross-platform
$(NetCurrent)content (covering both identical sourcebuild nuspecs) is gated on'$(DotNetBuildSourceOnly)' == 'true' or '$(OS)' != 'Windows_NT'.IncludeBuildOutput=falseandSuppressDependenciesWhenPacking=trueare used(the package ships no assembly of its own and has no NuGet dependencies).
ProjectReference,PackageReferenceandCopyFilesstaging logic is unchanged.The three
.nuspecfiles are deleted.Validation
A clean
build.cmd -c Release -packproduces a CLI package whose file list is byte-for-byteidentical to the pre-migration package (483 entries), with no
eng/expected-*.jsondrift.The generated nuspec metadata matches the previous one; the only differences are the per-file
contentFilesentries (vs. the single wildcard, functionally equivalent) and a benign auto-added<frameworkAssemblies>entry that is not part of the file-list oracle. The full Release build'snupkg-file-count and DLL-target-framework verification pipeline passes.
Known limitation
The
sourcebuild/sourcebuild.productpaths only execute under-DotNetBuildSourceOnly/ VMRbuilds and cannot be exercised by a local Windows build. They are translated faithfully but
validated by inspection only — worth confirming on a source-build / VMR CI leg before merge.
Closes #15650 (CLI follow-up).