-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Ensure that tool packages can still publish normally with dotnet publish.
#50445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ensure that tool packages can still publish normally with dotnet publish.
#50445
Conversation
There was a problem hiding this 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 fixes an issue where PackTool.targets were incorrectly modifying properties that affected tool publishing behavior, not just packaging. The fix restructures the targets to ensure tool-specific modifications only activate during pack operations.
Key changes:
- Moves tool-specific property modifications from global scope to pack-specific targets
- Adds
_IsPackingproperty to PackCommand and related test framework classes - Updates file-based program support to include
dotnet packfunctionality
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets | Restructures targets to move property modifications into pack-specific scope |
| src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets | Removes PackAsTool condition from runtime identifier inference |
| src/Cli/dotnet/Commands/Pack/PackCommand.cs | Adds file-based program support and refactors command creation |
| test/Microsoft.NET.TestFramework/Commands/*.cs | Adds _IsPacking and _IsPublishing properties to test commands |
| test/dotnet.Tests/CommandTests/Run/RunFileTests.cs | Adds comprehensive tests for pack functionality with file-based programs |
| test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAToolProject.cs | Adds regression test for normal publish behavior |
| eng/Version.Details.xml | Updates Microsoft.Testing.Platform and MSTest package versions |
src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets
Show resolved
Hide resolved
8644cd8 to
dedfaf5
Compare
| <_PackToolPublishDependency Condition=" $(_ToolPackageShouldIncludeImplementation) and '$(GeneratePackageOnBuild)' != 'true' and $(IsPublishable) == 'true' ">Publish</_PackToolPublishDependency> | ||
| <!-- BUT builds that GeneratePackageOnBuild can't directly rely on Publish since Publish would trigger Build, causing an infinite loop. --> | ||
| <!-- To get around this, we try a bit of a workaround: since we can't set NoBuild=true and call Publish that way, we instead trigger all of the | ||
| dependencies of the no-build Publish Target, _PublishNoBuildAlternative --> | ||
| <_PackToolPublishDependency Condition=" '$(_ToolPackageShouldIncludeImplementation)' != '' and '$(GeneratePackageOnBuild)' == 'true' and $(IsPublishable) == 'true' ">$(_PublishNoBuildAlternativeDependsOn)</_PackToolPublishDependency> | ||
| <_PackToolPublishDependency Condition=" $(_ToolPackageShouldIncludeImplementation) and '$(GeneratePackageOnBuild)' == 'true' and $(IsPublishable) == 'true' ">$(_PublishNoBuildAlternativeDependsOn)</_PackToolPublishDependency> | ||
| <!-- No implementation required? Then don't call either target. --> | ||
| <_PackToolPublishDependency Condition="!$(_ToolPackageShouldIncludeImplementation)"></_PackToolPublishDependency> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these three sets were actually a big part of the problem - they were incorrectly checking _ToolPackageShouldIncludeImplementation in a way that caused even top-level non-implementation packages to call Publish - which then causes the negative impacts observed by properties like PublishAot, etc. The final clause here explicitly makes sure that we end up calling no Publish-related Target if we don't need a tool implementation.
| <PreferNativeArm64 Condition="'$(PreferNativeArm64)'==''">false</PreferNativeArm64> | ||
| <SignAssembly Condition="'$(SignAssembly)'==''">false</SignAssembly> | ||
| <DelaySign Condition="'$(DelaySign)'==''">false</DelaySign> | ||
| <!-- TODO: should we set _IsPacking=true on the NuGet Pack targets when they hook up the 'generate package on build' stuff --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dsplaisted / @zivkan I think this is potentially a thing that we should dig into.
Here's the relevant part of the Pack Targets:
<Target Name="_PackAsBuildAfterTarget"
AfterTargets="Build"
Condition="'$(GeneratePackageOnBuild)' == 'true' AND '$(IsInnerBuild)' != 'true'"
DependsOnTargets="Pack">
</Target>
<Target Name="_CleanPackageFiles"
DependsOnTargets="_GetOutputItemsFromPack"
AfterTargets="Clean"
Condition="'$(GeneratePackageOnBuild)' == 'true' AND '$(IsInnerBuild)' != 'true'">
<ItemGroup>
<_PackageFilesToDelete Include="@(_OutputPackItems)"/>
</ItemGroup>
<Delete Files="@(_PackageFilesToDelete)"/>
</Target>It sucks to keep propagating _IsPacking, but I think we might need to. Ideally sometime after the build runs but before the 'hook' NuGet _PackAsBuildAfterTarget ties into the Pack DependsOnTargets?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we can successfully set _IsPacking in these targets, as there are evaluation-time properties in Microsoft.NET.PackTool.targets that depend on the _IsPacking value.
8695a37 to
630278d
Compare
… due to release schedules
…operty-set Condition check instead of simply not importing the targets at all when not packaging
…ckages to call Publish unecessarily
630278d to
ad63e78
Compare
|
per @dsplaisted the three remaining test failures are actually related to PrunePackageReferences and the way we construct some SDK layout stuff, not this PR. I'd be ok with merging this as a result. |
|
The test errors should be fixed by #50661. |
|
@dsplaisted it's finally ready! |
dotnet publish.
dsplaisted
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, and not as complicated as I had feared.
I think it would be good to get rid of all the HELIX_WORKITEM_UPLOAD_ROOT ibnlog-gathering code from the tests.
| <PublishSelfContained Condition="!$(_IsRidSpecific) and !$(_IsImplicitRestore) and $(_IsPacking)">false</PublishSelfContained> | ||
| <SelfContained Condition="!$(_IsRidSpecific) and !$(_IsImplicitRestore) and $(_IsPacking)">false</SelfContained> | ||
| <PublishTrimmed Condition="!$(_IsRidSpecific) and !$(_IsImplicitRestore) and $(_IsPacking)">false</PublishTrimmed> | ||
| <PublishReadyToRun Condition="!$(_IsRidSpecific) and !$(_IsImplicitRestore) and $(_IsPacking)">false</PublishReadyToRun> | ||
| <PublishSingleFile Condition="!$(_IsRidSpecific) and !$(_IsImplicitRestore) and $(_IsPacking)">false</PublishSingleFile> | ||
| <PublishAot Condition="!$(_IsRidSpecific) and !$(_IsImplicitRestore) and $(_IsPacking)">false</PublishAot> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same condition is repeated here for a bunch of properties. Would it make sense to put these in a separate PropertyGroup with the condition just once on the PropertyGroup?
And if we do that it might make sense to avoid creating our own _IsImplicitRestore property or forcing _IsPacking to have a value if it's not set.
|
|
||
| <!-- inner builds and non-RID-specific outer builds need publish content--> | ||
| <_PackToolPublishDependency Condition=" '$(_ToolPackageShouldIncludeImplementation)' != '' and '$(GeneratePackageOnBuild)' != 'true' and $(IsPublishable) == 'true' ">Publish</_PackToolPublishDependency> | ||
| <_PackToolPublishDependency Condition=" $(_ToolPackageShouldIncludeImplementation) and '$(GeneratePackageOnBuild)' != 'true' and $(IsPublishable) == 'true' ">Publish</_PackToolPublishDependency> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't comment the exact line since you didn't change it here, but would it make sense to change this:
<_ToolPackageShouldIncludeImplementation Condition=" '$(_ToolPackageShouldIncludeImplementation)' == '' And '$(PackAsTool)' == 'true' And
('$(_UserSpecifiedToolPackageRids)' == ''
or '$(RuntimeIdentifier)' != '')">true</_ToolPackageShouldIncludeImplementation>to this?
<_ToolPackageShouldIncludeImplementation Condition=" '$(_ToolPackageShouldIncludeImplementation)' == '' And '$(PackAsTool)' == 'true' And
('$(_HasRIDSpecificTools)' != 'true'
or '$(RuntimeIdentifier)' != '')">true</_ToolPackageShouldIncludeImplementation>Basically use the derived _HasRIDSpecificTools property. I think the result would be the same and this would be a bit easier to understand.
| <PreferNativeArm64 Condition="'$(PreferNativeArm64)'==''">false</PreferNativeArm64> | ||
| <SignAssembly Condition="'$(SignAssembly)'==''">false</SignAssembly> | ||
| <DelaySign Condition="'$(DelaySign)'==''">false</DelaySign> | ||
| <!-- TODO: should we set _IsPacking=true on the NuGet Pack targets when they hook up the 'generate package on build' stuff --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we can successfully set _IsPacking in these targets, as there are evaluation-time properties in Microsoft.NET.PackTool.targets that depend on the _IsPacking value.
| var binlogDestPath = Environment.GetEnvironmentVariable("HELIX_WORKITEM_UPLOAD_ROOT") is { } ciOutputRoot && Environment.GetEnvironmentVariable("HELIX_WORKITEM_ID") is { } helixGuid ? | ||
| Path.Combine(ciOutputRoot, "binlog", helixGuid, $"{nameof(It_cleans_the_project_successfully_with_static_graph_and_isolation)}.binlog") : | ||
| "./msbuild.binlog"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be removed in favor of the logic that's now built in to TestCommand.
Fixes #50435
The PackTool.targets were modifying critical properties of the tool package project that impacted the way the tool would be published, not just packed.
To fix this, we needed to make sure pathways that are called during 'normal publishing' and 'packaging' could distinguish between the two. This meant
Almost all of this is super gross, and I believe that the more correct way to structure all of this would be to push more of this overriding into Targets that set Properties less-conditionally and more clearly, but that pathway led to a lot of follow-on changes that were even harder to reason about, and I want to make sure we can get this in for RC2 so folks aren't blocked.