Skip to content

[Broken Build]: Dotnet Publish is not idempotent and deletes required Content #37222

Closed
@EdLichtman

Description

@EdLichtman

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

With certain configuration from prior to net8sdk, I could dotnet publish to my heart's content and everything worked.

Now, if I have a Content[xml][CopyToPublishDirectory:Always] file, then the first time I publish the project, the xml gets copied to the publish directory. The second time I publish the project, the xml is deleted from the publish directory and cannot be republished until I completely clean the directory or change the csproj file.

Expected Behavior

I expect that if I have

<ItemGroup>
    <Content Include="test.xml" CopyToPublishDirectory="Always" CopyToOutputDirectory="Always"/>
</ItemGroup>

in my project, then when I run dotnet publish, my test.xml file comes with me to the final publish location -- every single time I run it.

Steps To Reproduce

Download my source code:
https://github.com/EdLichtman/NUGET_HOME_ISSUES_12941/

Set Powershell Variable

$Csproj = "Path:\To\My\SourceCode\UsingPackagedVulnerability\UsingPackagedVulnerability.csproj

Run the following Powershell

dotnet publish $csproj --nologo --self-contained --configuration Release --framework net6.0 --runtime win-x64 --verbosity minimal

See that in the publish directory, there is a test.xml file.

Run the following Powershell

# Repeat the dotnet publish command above
dotnet publish $csproj --nologo --self-contained --configuration Release --framework net6.0 --runtime win-x64 --verbosity minimal

See that the test.xml file is gone.

Keep repeating the command, and continue to see that it is not publishing the test.xml ever.

Exceptions (if any)

No response

.NET Version

8.0.100

Anything else?

The only workaround is manually deleting the folder contents myself, or changing the csproj file.

If I delete the folder contents myself, then it always reproduces the xml file.

If I set DeleteExistingFiles:true, then it doesn't delete the folder contents before this happens and therefore doesn't solve the problem.

If I set DeleteExistingFiles:false, then it still deletes the test.xml file that I've added. I was curious to see if it was something wrong with the build order where DeleteExistingFiles was run after the test.xml was copied down. This is not the case.

The only workaround I have, which is absolutely unacceptable is to add the following to every single project I have:

  <Target Name="CleanPublishDirectoryBeforePublish" BeforeTargets="Compile">
    <ItemGroup>
      <PublishedFiles Include="$(PublishDir)\*"/>
    </ItemGroup>
    <Delete Files="@(PublishedFiles)"/>
  </Target>

It's unacceptable for a number of reasons, one of which though includes "We don't build during publish". We run dotnet build, then later on we run dotnet publish --no-restore --no-build. So if I don't run compile, then the Clean Target I created won't run during the publish anyway. I tried saying BeforeTargets="Publish", and dotnet publish still deleted the test.xml without recreating it.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions