Sdk: "content" folders are not published if they don't contain at least one file

Created on 13 Feb 2016  路  13Comments  路  Source: dotnet/sdk

If I specify a content folder in project.json that doesn't contain any files ...

"content": [ 
    "Views", 
    "wwwroot",
    "logs"
],

(logs in this case is an empty folder) ... the published output doesn't include the folder ...

capture1

If I put a file in the logs folder (test.txt in this case), it publishes the folder ...

capture2

I don't think it should work that way. If I specify an empty content folder (or a series of nested empty folders), then I should get folders in the published output that match what I'm requesting.

Bug question

All 13 comments

Is this actually because this is the "legacy" way that it was handled in ASP.NET? This has always been an issue and the Visual Studio Team never provided a solution to it , other than placing a dummy file into the directory.

With that said, I think that @GuardRex makes a valid point in that if we go through the trouble of specifying a content folder in the project.json file then it should honor that on publishing.

@davidfowl @piotrpMSFT this seems like a reasonable expectation to me, actually. Thoughts?

The team is actively working on enabling MSBuild and the component affected will be superseded by the new project system, so I am closing this issue.

In case anyone stumbles in here looking for the "how-to" on creating the Logs folder (or any other content folder for that matter) with MSBuild and csproj, do this ...

When I started, dotnet migrate attempted to provide me with an entry to output my Logs folder. In the <ItemGroup>, where you see the <Compile ... /> and <EmbeddedResource ... /> entries, it added ...

<Content Include="Logs\*" Exclude="Logs\*.log">
  <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>

It added the Exclude attribute because in my publishOptions I had excluded any log files that were produced as a result of Debug runs out of the published output. There was no point in sending any of those to the server.

However, that section didn't work. If the Logs folder is empty or if the Logs folder contained only *.log files, MSBuild would not create an empty folder in my published output.

If you end up with such a section in your csproj, you can remove it. It's useless for creating an empty Logs folder (or any other folder for that matter) in published output.

Instead, try using an AfterPublish target ...

<Target Name="AfterPublish">
  <MakeDir Directories="$(PublishDir)Logs" Condition="!Exists('$(PublishDir)Logs')" />
</Target>

... just inside the closing </Project> tag. It must come after the Import for the Microsoft.CSharp.targets entry.

[Thanks to @gulbanana for pointing me in the right direction to get this solved.]

@piotrpMSFT [EDIT] Nevermind. I got it ...

<Target Name="MyAfterPublish" AfterTargets="AfterPublish">
  <MakeDir Directories="$(PublishDir)Logs" Condition="!Exists('$(PublishDir)Logs')" />
</Target>

I just ran into the same problem with todays dotnet core tooling. Any folder not created prior to dotnet publish call will not be published. My case is that I have prepublish tasks running that generate some files, but these files are not published due to the folders did not exists prior to calling dotnet publish.

@pksorensen Not sure if this will help in your case, but I needed an empty folder, and Content Include would only help me when there was a dummy file present in the folder, so I started using this ...

<Target Name="CreateLogsFolder" AfterTargets="AfterPublish">
  <MakeDir Directories="$(PublishDir)Logs" Condition="!Exists('$(PublishDir)Logs')" />
</Target>

... so perhaps a Copy command in there instead of a MakeDir would work for you?

i solved it by adding mkdir commands in my build pipeline. just expected the tooling to include those files generated in prepublish steps.

@pksorensen can you share your project? Or a simple repro somewhere?

/cc @nguerrera @srivatsn

here is a repro: https://github.com/pksorensen/dotnet-cli-publish-repro and you can run dotnet publish -o c:\test\out to see that it do not publish a artifacts folder, even though the prepublish scripts generate the folder.

@pksorensen ah, I see you are using project.json tooling. This issue has been fixed in the MSBuild-based tooling (just verified, it works).

@blackdwarf I am now on 2017 RC and this is still an issue.

Any files created in the targets below that didnt exists before, will not be published.

 <Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
    <Exec Command="npm run tsc" />
    <Exec Command="grunt packLib" />
  </Target>

or

 <Target Name="MyPrePublishTarget" BeforeTargets="Publish">
    <Exec Command="npm run tsc" />
    <Exec Command="grunt packLib" />

will not be published

with the following condent include.

<Content Include="wwwroot\**" />

@pksorensen this is a known issue (the globs are evaluated before the PrepareForPublish target runs): https://github.com/aspnet/websdk/issues/114
There is a workaround described in https://github.com/aspnet/websdk/issues/114#issuecomment-280076533

Was this page helpful?
0 / 5 - 0 ratings