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

dotnet publish does not copy the documentation file with csproj #795

Closed
livarcocc opened this Issue Feb 2, 2017 · 47 comments

Comments

Projects
None yet
@livarcocc
Member

livarcocc commented Feb 2, 2017

Steps to reproduce

Have a solution with multiple projects
The main "web" project has the GenerateDocumentationFile set to true

Expected behavior

When I run dotnet publish of the main "web" project, I expect that the XML documentation file is copied into the publishing folder. (Note the build will generate the file as it should.)

Actual behavior

When I run dotnet publish of the main "web" project, it does not copy the XML documentation file to the psublish folder.

My workaround

My current workaround is to update the csproj of the main web project and manually copy the file:
<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish"> <ItemGroup> <DocFile Include="bin\**\**\PROJECT_XYZ.xml" /> </ItemGroup> <Copy SourceFiles="@(DocFile)" DestinationFolder="$(PublishDir)" SkipUnchangedFiles="false" /> </Target>

Environment data

.NET Command Line Tools (1.0.0-rc3-004530)

Product Information:
Version: 1.0.0-rc3-004530
Commit SHA-1 hash: 0de3338607

Runtime Environment:
OS Name: Windows
OS Version: 6.3.9600
OS Platform: Windows
RID: win81-x64
Base Path: C:\Program Files\dotnet\sdk\1.0.0-rc3-004530

This issue has been copied over from dotnet/cli#5562.

@davkean

This comment has been minimized.

Show comment
Hide comment
@davkean

davkean Feb 3, 2017

Member

@masterjs What's the expectation around this? Why do you expect the XML file to be published - it's a dev artefact.

Member

davkean commented Feb 3, 2017

@masterjs What's the expectation around this? Why do you expect the XML file to be published - it's a dev artefact.

@masterjs

This comment has been minimized.

Show comment
Hide comment
@masterjs

masterjs Feb 3, 2017

Hello @davkean ,
My project is a big WebAPI netcore and like many API, I'm using Swagger whom needs the XML documentation file if I want to have a good documentation for my API. Also, it use to work when I was using .xproj.

Also, another of my project (solution with multiple projects) has the flag GenerateDocumentationFile turned On and somehow that one is copied over.

So in a nutshell, it use to work and now I see two different things contradicting themselves.

thank you,
JS

masterjs commented Feb 3, 2017

Hello @davkean ,
My project is a big WebAPI netcore and like many API, I'm using Swagger whom needs the XML documentation file if I want to have a good documentation for my API. Also, it use to work when I was using .xproj.

Also, another of my project (solution with multiple projects) has the flag GenerateDocumentationFile turned On and somehow that one is copied over.

So in a nutshell, it use to work and now I see two different things contradicting themselves.

thank you,
JS

@eerhardt

This comment has been minimized.

Show comment
Hide comment
@eerhardt

eerhardt Feb 4, 2017

Member

Do you also expect that P2P references' doc files are published? What about doc files from NuGet packages?

I think since documentation files aren't typically used at runtime, they shouldn't be published by default.

Projects that need this behavior can add their own target that runs during publish and adds the documentation file to the @(ResolvedFileToPublish) item, which will copy the xml file to the publish directory. It isn't necessarily behavior that the core SDK has to provide.

Member

eerhardt commented Feb 4, 2017

Do you also expect that P2P references' doc files are published? What about doc files from NuGet packages?

I think since documentation files aren't typically used at runtime, they shouldn't be published by default.

Projects that need this behavior can add their own target that runs during publish and adds the documentation file to the @(ResolvedFileToPublish) item, which will copy the xml file to the publish directory. It isn't necessarily behavior that the core SDK has to provide.

@masterjs

This comment has been minimized.

Show comment
Hide comment
@masterjs

masterjs Feb 4, 2017

For my case, since It's for a web api I only care about the generated documentation. I dont mind and understand if it needs a little bit more work like I did for my work-around. The main problem was that it was a different behavior from xproj when I migrated to csproj and the documentation file of other projects was still copied.

masterjs commented Feb 4, 2017

For my case, since It's for a web api I only care about the generated documentation. I dont mind and understand if it needs a little bit more work like I did for my work-around. The main problem was that it was a different behavior from xproj when I migrated to csproj and the documentation file of other projects was still copied.

@dasMulli

This comment has been minimized.

Show comment
Hide comment
@dasMulli

dasMulli Feb 4, 2017

Contributor

Documentation files are what Swashbuckle can use at runtime to enrich the generated Swagger API description. It's nice for Web API projects because you just need to write a documentation once that works for IntelliSense, doc generation tools AND runtime Swagger generation, making it more than just a dev artifact. So it does make sense to publish it with the application in some scenarios.

Contributor

dasMulli commented Feb 4, 2017

Documentation files are what Swashbuckle can use at runtime to enrich the generated Swagger API description. It's nice for Web API projects because you just need to write a documentation once that works for IntelliSense, doc generation tools AND runtime Swagger generation, making it more than just a dev artifact. So it does make sense to publish it with the application in some scenarios.

@srivatsn srivatsn modified the milestones: 1.0 RTM, 1.1 Feb 6, 2017

@filipw

This comment has been minimized.

Show comment
Hide comment
@filipw

filipw Feb 20, 2017

I agree, it's necessary for situations like auto-generated Swagger.
It also worked for project.json so it's really a breaking change for folks migrating to csproj

filipw commented Feb 20, 2017

I agree, it's necessary for situations like auto-generated Swagger.
It also worked for project.json so it's really a breaking change for folks migrating to csproj

@dasMulli

This comment has been minimized.

Show comment
Hide comment
@dasMulli

dasMulli Feb 20, 2017

Contributor

using xml comments for swagger is already documented on docs.microsoft.com by @spboyer so maybe the doc would need to be updated that this won't work with the 1.0 tooling when published?

Contributor

dasMulli commented Feb 20, 2017

using xml comments for swagger is already documented on docs.microsoft.com by @spboyer so maybe the doc would need to be updated that this won't work with the 1.0 tooling when published?

@spboyer

This comment has been minimized.

Show comment
Hide comment
@spboyer

spboyer Feb 20, 2017

The swagger doc has been updated in the csproj branch, will be pushing that to live when RTM is released approx Mar 7

spboyer commented Feb 20, 2017

The swagger doc has been updated in the csproj branch, will be pushing that to live when RTM is released approx Mar 7

@spboyer

This comment has been minimized.

Show comment
Hide comment
@spboyer

spboyer Mar 3, 2017

You can modify the csproj file to add the necessary files to pipeline that MSBuild needs to package up for the publish process. To add the Swagger files add the following snippet to the end of you *.csproj file before </Project>

  <Target Name="SwaggerFile">
    <ItemGroup>
      <_CustomFiles Include="bin\(Configuration)\(Platform)\*.xml" />
      <FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
        <DestinationRelativePath>%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
      </FilesForPackagingFromProject>
    </ItemGroup>
  </Target>

  <PropertyGroup>
      <CopyAllFilesToSingleFolderForPackageDependsOn>
        SwaggerFile;
        $(CopyAllFilesToSingleFolderForPackageDependsOn);
      </CopyAllFilesToSingleFolderForPackageDependsOn>
  </PropertyGroup>

This copies the documentation file to the root of the project prior to the MSBUILD process running . dotnet publish will place the file in whatever output location you specify and configuration.

cc:/ @sayedihashimi

spboyer commented Mar 3, 2017

You can modify the csproj file to add the necessary files to pipeline that MSBuild needs to package up for the publish process. To add the Swagger files add the following snippet to the end of you *.csproj file before </Project>

  <Target Name="SwaggerFile">
    <ItemGroup>
      <_CustomFiles Include="bin\(Configuration)\(Platform)\*.xml" />
      <FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
        <DestinationRelativePath>%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
      </FilesForPackagingFromProject>
    </ItemGroup>
  </Target>

  <PropertyGroup>
      <CopyAllFilesToSingleFolderForPackageDependsOn>
        SwaggerFile;
        $(CopyAllFilesToSingleFolderForPackageDependsOn);
      </CopyAllFilesToSingleFolderForPackageDependsOn>
  </PropertyGroup>

This copies the documentation file to the root of the project prior to the MSBUILD process running . dotnet publish will place the file in whatever output location you specify and configuration.

cc:/ @sayedihashimi

@spboyer

This comment has been minimized.

Show comment
Hide comment

spboyer commented Mar 3, 2017

@natemcmaster

This comment has been minimized.

Show comment
Hide comment
@natemcmaster

natemcmaster Mar 3, 2017

Member

@spboyer probably not. Those docs are focused on converting project.json to MSBuild. When I wrote the docs, I only included the breaking changes between PJ and csproj that were relevant to the format of the file. I made a followup post to address breaking changes. It might be worth added an official doc with similar content.

Member

natemcmaster commented Mar 3, 2017

@spboyer probably not. Those docs are focused on converting project.json to MSBuild. When I wrote the docs, I only included the breaking changes between PJ and csproj that were relevant to the format of the file. I made a followup post to address breaking changes. It might be worth added an official doc with similar content.

@eerhardt

This comment has been minimized.

Show comment
Hide comment
@eerhardt

eerhardt Mar 3, 2017

Member

IMO - this highlights the main advantage of moving from project.json to MSBuild. No longer does the core build logic need to take care of every scenario. If the core build logic doesn't work for your scenario, you have the full power to make it work.

What is even better, is someone can make a "SwaggerTools" NuGet package that will inject this MSBuild logic into a project. Then all app projects need to do is add a <PackageReference> to that new package, and they get this functionality.

Member

eerhardt commented Mar 3, 2017

IMO - this highlights the main advantage of moving from project.json to MSBuild. No longer does the core build logic need to take care of every scenario. If the core build logic doesn't work for your scenario, you have the full power to make it work.

What is even better, is someone can make a "SwaggerTools" NuGet package that will inject this MSBuild logic into a project. Then all app projects need to do is add a <PackageReference> to that new package, and they get this functionality.

@natemcmaster

This comment has been minimized.

Show comment
Hide comment
@natemcmaster

natemcmaster Mar 3, 2017

Member

this highlights the main advantage of moving from project.json to MSBuild

+1. MSBuild extensibility is awesome.

But back to the main point of this issue. Should the SDK include xml docs in the published output by default?

My vote: yes.

Member

natemcmaster commented Mar 3, 2017

this highlights the main advantage of moving from project.json to MSBuild

+1. MSBuild extensibility is awesome.

But back to the main point of this issue. Should the SDK include xml docs in the published output by default?

My vote: yes.

@sayedihashimi

This comment has been minimized.

Show comment
Hide comment
@sayedihashimi

sayedihashimi Mar 3, 2017

Member

Sometimes the xml files can be large. Do we have any numbers on the size/time impact for publishing if we did this?

Update: just read through the comments, it seems like the proposal is to include the generated xml file for the project, without xml files for dependencies. That sounds like a good idea to me.

Member

sayedihashimi commented Mar 3, 2017

Sometimes the xml files can be large. Do we have any numbers on the size/time impact for publishing if we did this?

Update: just read through the comments, it seems like the proposal is to include the generated xml file for the project, without xml files for dependencies. That sounds like a good idea to me.

@dasMulli

This comment has been minimized.

Show comment
Hide comment
@dasMulli

dasMulli Mar 14, 2017

Contributor

@spboyer, cc @guardrex: another workaround would be to use the $(DocumentationFile) property to emit items that are respected during publish like this:

<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<Target Name="IncludeDocFile" BeforeTargets="PrepareForPublish">
  <ItemGroup Condition=" '$(DocumentationFile)' != '' ">
    <_DocumentationFile Include="$(DocumentationFile)" />
    <ContentWithTargetPath Include="@(_DocumentationFile->'%(FullPath)')"
                           RelativePath="%(_DocumentationFile.Identity)"
                           TargetPath="%(_DocumentationFile.Filename)%(_DocumentationFile.Extension)"
                           CopyToPublishDirectory="PreserveNewest" />
  </ItemGroup>
</Target>

If more files are needed, more _DocumentationFile items using a pattern could be used.

Contributor

dasMulli commented Mar 14, 2017

@spboyer, cc @guardrex: another workaround would be to use the $(DocumentationFile) property to emit items that are respected during publish like this:

<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<Target Name="IncludeDocFile" BeforeTargets="PrepareForPublish">
  <ItemGroup Condition=" '$(DocumentationFile)' != '' ">
    <_DocumentationFile Include="$(DocumentationFile)" />
    <ContentWithTargetPath Include="@(_DocumentationFile->'%(FullPath)')"
                           RelativePath="%(_DocumentationFile.Identity)"
                           TargetPath="%(_DocumentationFile.Filename)%(_DocumentationFile.Extension)"
                           CopyToPublishDirectory="PreserveNewest" />
  </ItemGroup>
</Target>

If more files are needed, more _DocumentationFile items using a pattern could be used.

@billpratt

This comment has been minimized.

Show comment
Hide comment
@billpratt

billpratt Mar 21, 2017

Is this bug actively being worked on? For now we are using csproj work arounds listed above but not ideal.

Is this bug actively being worked on? For now we are using csproj work arounds listed above but not ideal.

@livarcocc

This comment has been minimized.

Show comment
Hide comment
@livarcocc

livarcocc Mar 21, 2017

Member

I am not sure about turning this on by default, though maybe we should have a more accessible way to have this on during publish.

Member

livarcocc commented Mar 21, 2017

I am not sure about turning this on by default, though maybe we should have a more accessible way to have this on during publish.

@billpratt

This comment has been minimized.

Show comment
Hide comment
@billpratt

billpratt Mar 22, 2017

@spboyer

This comment has been minimized.

Show comment
Hide comment
@spboyer

spboyer Mar 22, 2017

In Visual Studio, we should have the option either in the Properties of the project where you enable the xml documentation file and/or right click action to include the file in the output or publish location which then creates the entry in .csproj like @dasMulli put above.

For non-VS users, documentation noting how to do this or simplifying the entry in .csproj via a flag maybe a good/better solution.

Proposed : requires change to tooling

<PropertyGroup>
  <GenerateDocumentationFile
        CopyToPublishDirectory="PreserveNewest" 
        Option="true" />
</PropertyGroup>

cc:/ @sayedihashimi

spboyer commented Mar 22, 2017

In Visual Studio, we should have the option either in the Properties of the project where you enable the xml documentation file and/or right click action to include the file in the output or publish location which then creates the entry in .csproj like @dasMulli put above.

For non-VS users, documentation noting how to do this or simplifying the entry in .csproj via a flag maybe a good/better solution.

Proposed : requires change to tooling

<PropertyGroup>
  <GenerateDocumentationFile
        CopyToPublishDirectory="PreserveNewest" 
        Option="true" />
</PropertyGroup>

cc:/ @sayedihashimi

@dasMulli

This comment has been minimized.

Show comment
Hide comment
@dasMulli

dasMulli Mar 22, 2017

Contributor

I'd like to see a more built-in solution like building SDK support for:

<PropertyGroup>
  <PublishDocumentationFile>true</PublishDocumentationFile>
  <!-- Next one is a nice to have -->
  <PublishDependencyDocumentationFiles>true</PublishDependencyDocumentationFiles>
</PropertyGroup>

This would be easy for tooling (=> checkbox) and hand-editing csproj files. Defaults could also be set easily via the SDK, WebSDK or NuGet packages (Swashbuckle).

Contributor

dasMulli commented Mar 22, 2017

I'd like to see a more built-in solution like building SDK support for:

<PropertyGroup>
  <PublishDocumentationFile>true</PublishDocumentationFile>
  <!-- Next one is a nice to have -->
  <PublishDependencyDocumentationFiles>true</PublishDependencyDocumentationFiles>
</PropertyGroup>

This would be easy for tooling (=> checkbox) and hand-editing csproj files. Defaults could also be set easily via the SDK, WebSDK or NuGet packages (Swashbuckle).

@jchadwick

This comment has been minimized.

Show comment
Hide comment
@jchadwick

jchadwick Mar 28, 2017

@spboyer For what it's worth, your workaround above (CopyAllFilesToSingleFolderForPackageDependsOn) is not working for me - the xml file does not get copied. Are you sure that's correct?

@spboyer For what it's worth, your workaround above (CopyAllFilesToSingleFolderForPackageDependsOn) is not working for me - the xml file does not get copied. Are you sure that's correct?

@jbegithub

This comment has been minimized.

Show comment
Hide comment
@jbegithub

jbegithub Mar 28, 2017

@jchadwick +1
CopyAllFilesToSingleFolderForPackageDependsOn doesn't work for me either, is it platform independet?

@jchadwick +1
CopyAllFilesToSingleFolderForPackageDependsOn doesn't work for me either, is it platform independet?

@dasMulli

This comment has been minimized.

Show comment
Hide comment
@dasMulli

dasMulli Mar 28, 2017

Contributor

afaik, CopyAllFilesToSingleFolderForPackageDependsOn is a thing of the (now "old") webdepoy target files, the .net sdk now uses a different publishing process.

Contributor

dasMulli commented Mar 28, 2017

afaik, CopyAllFilesToSingleFolderForPackageDependsOn is a thing of the (now "old") webdepoy target files, the .net sdk now uses a different publishing process.

@jbegithub

This comment has been minimized.

Show comment
Hide comment
@jbegithub

jbegithub Mar 28, 2017

Ok, but I guess there's still no build in way to get the xml-documentation file copied to the published dir.?
Any other workaround to accomplish this?

Ok, but I guess there's still no build in way to get the xml-documentation file copied to the published dir.?
Any other workaround to accomplish this?

@spboyer

This comment has been minimized.

Show comment
Hide comment
@spboyer

spboyer Mar 28, 2017

@jchadwick it does work - make sure you are doing this one -> #795 (comment) and not the proposed one

spboyer commented Mar 28, 2017

@jchadwick it does work - make sure you are doing this one -> #795 (comment) and not the proposed one

@jbegithub

This comment has been minimized.

Show comment
Hide comment
@jbegithub

jbegithub Mar 28, 2017

doesn't work for me on ubuntu, ended up using a python oneliner:
<Target Name="MyPostCompileTarget" AfterTargets="Publish"> <Exec Command="python -c %22from shutil import copyfile; copyfile('$(OutDir)/doc.xml', '$(PublishDir)/doc.xml')%22 " /> </Target>

doesn't work for me on ubuntu, ended up using a python oneliner:
<Target Name="MyPostCompileTarget" AfterTargets="Publish"> <Exec Command="python -c %22from shutil import copyfile; copyfile('$(OutDir)/doc.xml', '$(PublishDir)/doc.xml')%22 " /> </Target>

@billpratt

This comment has been minimized.

Show comment
Hide comment
@billpratt

billpratt Mar 28, 2017

This works for me. Verified on Windows, macOS and Ubuntu

<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
    <ItemGroup>
      <DocFile Include="bin\$(Configuration)\$(TargetFramework)\*.xml" />
    </ItemGroup>
    <Copy SourceFiles="@(DocFile)" DestinationFolder="$(PublishDir)" SkipUnchangedFiles="false" />
  </Target>

This works for me. Verified on Windows, macOS and Ubuntu

<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
    <ItemGroup>
      <DocFile Include="bin\$(Configuration)\$(TargetFramework)\*.xml" />
    </ItemGroup>
    <Copy SourceFiles="@(DocFile)" DestinationFolder="$(PublishDir)" SkipUnchangedFiles="false" />
  </Target>
@eerhardt

This comment has been minimized.

Show comment
Hide comment
@eerhardt

eerhardt Mar 28, 2017

Member

This Target will work on all platforms and in web and console apps:

  <Target Name="CopyDocumentationFile"
          AfterTargets="ComputeFilesToPublish">
    <ItemGroup>
      <ResolvedFileToPublish Include="@(FinalDocFile)"
                             RelativePath="@(FinalDocFile->'%(Filename)%(Extension)')" />
    </ItemGroup>
  </Target>

ResolvedFileToPublish is the Item that publish uses to know which files to put in the publish folder. The Include is the file's source, and the RelativePath is where inside the publish folder the file should be placed.
ComputeFilesToPublish is exactly as its name implies - it is the Target that gathers all the files to be published.

Member

eerhardt commented Mar 28, 2017

This Target will work on all platforms and in web and console apps:

  <Target Name="CopyDocumentationFile"
          AfterTargets="ComputeFilesToPublish">
    <ItemGroup>
      <ResolvedFileToPublish Include="@(FinalDocFile)"
                             RelativePath="@(FinalDocFile->'%(Filename)%(Extension)')" />
    </ItemGroup>
  </Target>

ResolvedFileToPublish is the Item that publish uses to know which files to put in the publish folder. The Include is the file's source, and the RelativePath is where inside the publish folder the file should be placed.
ComputeFilesToPublish is exactly as its name implies - it is the Target that gathers all the files to be published.

@spboyer

This comment has been minimized.

Show comment
Hide comment
@spboyer

spboyer Mar 28, 2017

@eerhardt has the best option. Created sample project for ref https://github.com/spboyer/copydocfile-example

spboyer commented Mar 28, 2017

@eerhardt has the best option. Created sample project for ref https://github.com/spboyer/copydocfile-example

@thoean

This comment has been minimized.

Show comment
Hide comment
@thoean

thoean Mar 28, 2017

That's our version, which works on Linux, Windows and Mac - similar what @eerhardt provided.

In the main section, ensure the documentation file gets generated:

  <GenerateDocumentationFile>true</GenerateDocumentationFile>

Then a separate target with the copy process:

  <Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
    <ItemGroup>
      <DocFile Include="bin\*\*\MyProject.xml" />
    </ItemGroup>
    <Copy SourceFiles="@(DocFile)" DestinationFolder="$(PublishDir)" SkipUnchangedFiles="false" />
  </Target>

thoean commented Mar 28, 2017

That's our version, which works on Linux, Windows and Mac - similar what @eerhardt provided.

In the main section, ensure the documentation file gets generated:

  <GenerateDocumentationFile>true</GenerateDocumentationFile>

Then a separate target with the copy process:

  <Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
    <ItemGroup>
      <DocFile Include="bin\*\*\MyProject.xml" />
    </ItemGroup>
    <Copy SourceFiles="@(DocFile)" DestinationFolder="$(PublishDir)" SkipUnchangedFiles="false" />
  </Target>
@RehanSaeed

This comment has been minimized.

Show comment
Hide comment
@RehanSaeed

RehanSaeed Mar 29, 2017

What about if you want to include documentation files for other package referenced assemblies. My scenario is that I have moved a shared controller to a NuGet package and want to include it's documentation file in my Swagger page.

What about if you want to include documentation files for other package referenced assemblies. My scenario is that I have moved a shared controller to a NuGet package and want to include it's documentation file in my Swagger page.

@jchadwick

This comment has been minimized.

Show comment
Hide comment
@jchadwick

jchadwick Mar 29, 2017

@spboyer @eerhardt Thanks for the solution and the demo code. This works great. Eager to see this built in!

@spboyer @eerhardt Thanks for the solution and the demo code. This works great. Eager to see this built in!

@vdevappa

This comment has been minimized.

Show comment
Hide comment
@vdevappa

vdevappa Jun 5, 2017

For those having issues with this and service fabric, there is a slight tweak to the .csproj change you need to make to get it to work:

<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish"> <ItemGroup> <DocFile Include="bin\x64\$(Configuration)\$(TargetFramework)\win7-x64\*.xml" /> </ItemGroup> <Copy SourceFiles="@(DocFile)" DestinationFolder="$(PublishDir)" SkipUnchangedFiles="false" /> </Target>

Also remember that sometimes the property group is not completely changed by Visual Studio. Ensure the below lines are present:

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <DocumentationFile>bin\Debug\net462\win7-x64\WebApiSwagger.XML</DocumentationFile> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <DocumentationFile>bin\Debug\net462\win7-x64\WebApiSwagger.XML</DocumentationFile> </PropertyGroup>
I have verified this works.

vdevappa commented Jun 5, 2017

For those having issues with this and service fabric, there is a slight tweak to the .csproj change you need to make to get it to work:

<Target Name="PrepublishScript" BeforeTargets="PrepareForPublish"> <ItemGroup> <DocFile Include="bin\x64\$(Configuration)\$(TargetFramework)\win7-x64\*.xml" /> </ItemGroup> <Copy SourceFiles="@(DocFile)" DestinationFolder="$(PublishDir)" SkipUnchangedFiles="false" /> </Target>

Also remember that sometimes the property group is not completely changed by Visual Studio. Ensure the below lines are present:

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <DocumentationFile>bin\Debug\net462\win7-x64\WebApiSwagger.XML</DocumentationFile> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <DocumentationFile>bin\Debug\net462\win7-x64\WebApiSwagger.XML</DocumentationFile> </PropertyGroup>
I have verified this works.

@nukec

This comment has been minimized.

Show comment
Hide comment
@nukec

nukec Sep 13, 2017

Nothing here suggested works for me. I've tried to use @eerhardt 's answer, nothing is happening. If I click manual publish on project, xml document is added into the publish list.

I am not sure what am I doing wrong this is my .csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup Label="Globals">
    <SccProjectName>SAK</SccProjectName>
    <SccProvider>SAK</SccProvider>
    <SccAuxPath>SAK</SccAuxPath>
    <SccLocalPath>SAK</SccLocalPath>
  </PropertyGroup>

  <PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
	<PreserveCompilationContext>true</PreserveCompilationContext>
    <PackageTargetFallback>portable-net45+win8</PackageTargetFallback>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DocumentationFile>bin\Debug\netcoreapp1.1\Api.xml</DocumentationFile>
  </PropertyGroup>
 
  
  <Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
    <ItemGroup>
      <DocFile Include="bin\*\*\Api.xml" />
    </ItemGroup>

    <Copy SourceFiles="@(DocFile)" DestinationFolder="$(PublishDir)" SkipUnchangedFiles="false" />
  </Target>

  <ItemGroup>
    <Compile Remove="wwwroot\**" />
    <Content Remove="wwwroot\**" />
    <EmbeddedResource Remove="wwwroot\**" />
    <None Remove="wwwroot\**" />
  </ItemGroup>

  <ItemGroup>
    <None Remove="identityserver4_log.txt" />
  </ItemGroup>

  <ItemGroup>
    <Content Include="Api.xml">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="AutoMapper" Version="6.0.2" />
    <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="2.0.1" />
    <PackageReference Include="Carable.Swashbuckle.AspNetCore.DocumentWithCode" Version="0.0.4" />
    <PackageReference Include="Castle.Core" Version="4.1.1" />
    <PackageReference Include="FluentValidation.AspNetCore" Version="7.0.2" />
    <PackageReference Include="IdentityServer4" Version="1.5.2" />
    <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="1.2.1" />
    <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
    <PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Identity" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="1.1.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="1.1.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.2" />
	<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.2" />
    <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.1.2" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="1.1.1" />
    <PackageReference Include="Serilog.Extensions.Logging" Version="1.4.0" />
    <PackageReference Include="Serilog.Extensions.Logging.ApplicationInsights" Version="1.1.0" />
    <PackageReference Include="StructureMap.Microsoft.DependencyInjection" Version="1.3.0" />
  </ItemGroup>
  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0" />
	<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
  </ItemGroup>
  <ItemGroup>
    <WCFMetadata Include="Connected Services" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Views\Default\" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\Api.Business\Api.Business.csproj" />
  </ItemGroup>


</Project>

nukec commented Sep 13, 2017

Nothing here suggested works for me. I've tried to use @eerhardt 's answer, nothing is happening. If I click manual publish on project, xml document is added into the publish list.

I am not sure what am I doing wrong this is my .csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup Label="Globals">
    <SccProjectName>SAK</SccProjectName>
    <SccProvider>SAK</SccProvider>
    <SccAuxPath>SAK</SccAuxPath>
    <SccLocalPath>SAK</SccLocalPath>
  </PropertyGroup>

  <PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
	<PreserveCompilationContext>true</PreserveCompilationContext>
    <PackageTargetFallback>portable-net45+win8</PackageTargetFallback>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DocumentationFile>bin\Debug\netcoreapp1.1\Api.xml</DocumentationFile>
  </PropertyGroup>
 
  
  <Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
    <ItemGroup>
      <DocFile Include="bin\*\*\Api.xml" />
    </ItemGroup>

    <Copy SourceFiles="@(DocFile)" DestinationFolder="$(PublishDir)" SkipUnchangedFiles="false" />
  </Target>

  <ItemGroup>
    <Compile Remove="wwwroot\**" />
    <Content Remove="wwwroot\**" />
    <EmbeddedResource Remove="wwwroot\**" />
    <None Remove="wwwroot\**" />
  </ItemGroup>

  <ItemGroup>
    <None Remove="identityserver4_log.txt" />
  </ItemGroup>

  <ItemGroup>
    <Content Include="Api.xml">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="AutoMapper" Version="6.0.2" />
    <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="2.0.1" />
    <PackageReference Include="Carable.Swashbuckle.AspNetCore.DocumentWithCode" Version="0.0.4" />
    <PackageReference Include="Castle.Core" Version="4.1.1" />
    <PackageReference Include="FluentValidation.AspNetCore" Version="7.0.2" />
    <PackageReference Include="IdentityServer4" Version="1.5.2" />
    <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="1.2.1" />
    <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
    <PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Identity" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="1.1.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="1.1.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.2" />
	<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.2" />
    <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.1.2" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="1.1.1" />
    <PackageReference Include="Serilog.Extensions.Logging" Version="1.4.0" />
    <PackageReference Include="Serilog.Extensions.Logging.ApplicationInsights" Version="1.1.0" />
    <PackageReference Include="StructureMap.Microsoft.DependencyInjection" Version="1.3.0" />
  </ItemGroup>
  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0" />
	<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
  </ItemGroup>
  <ItemGroup>
    <WCFMetadata Include="Connected Services" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Views\Default\" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\Api.Business\Api.Business.csproj" />
  </ItemGroup>


</Project>
@ravetroll

This comment has been minimized.

Show comment
Hide comment
@ravetroll

ravetroll Dec 7, 2017

I found the file was being created on my desktop from VS2017 in the 'Release' Configuration but was not being created in VSTS on release configuration

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> <DocumentationFile>bin\Debug\netcoreapp1.1\Host.xml</DocumentationFile> </PropertyGroup>

I wondered if perhaps the 'AnyCPU' Platform was not being applied in VSTS so I removed that part from my csproj file and it built properly including my documentation file in VSTS in 'Release' so I guess AnyCPU is not the right platform setting or default platform setting in VSTS

<PropertyGroup Condition="'$(Configuration)'=='Release'"> <DocumentationFile>bin\Release\netcoreapp1.1\Host.xml</DocumentationFile> </PropertyGroup>

I found the file was being created on my desktop from VS2017 in the 'Release' Configuration but was not being created in VSTS on release configuration

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> <DocumentationFile>bin\Debug\netcoreapp1.1\Host.xml</DocumentationFile> </PropertyGroup>

I wondered if perhaps the 'AnyCPU' Platform was not being applied in VSTS so I removed that part from my csproj file and it built properly including my documentation file in VSTS in 'Release' so I guess AnyCPU is not the right platform setting or default platform setting in VSTS

<PropertyGroup Condition="'$(Configuration)'=='Release'"> <DocumentationFile>bin\Release\netcoreapp1.1\Host.xml</DocumentationFile> </PropertyGroup>

@pgmolloy

This comment has been minimized.

Show comment
Hide comment
@pgmolloy

pgmolloy Dec 30, 2017

I would like to vote for adding the swagger xml file to the build. My opinion is that the swagger xml file is NOT a doc file but a "necessary component" similar to a web config or an app settings file required by my Azure API to run. When deploying to Azure, my API will not start without the file. Just two cents worth :)

I would like to vote for adding the swagger xml file to the build. My opinion is that the swagger xml file is NOT a doc file but a "necessary component" similar to a web config or an app settings file required by my Azure API to run. When deploying to Azure, my API will not start without the file. Just two cents worth :)

@dasMulli

This comment has been minimized.

Show comment
Hide comment
@dasMulli

dasMulli Dec 30, 2017

Contributor

@pgmolloy does anything not work in your publish scenario? This has been implemented.

For those having trouble getting DocumentationFile to work, I recommend deleting it and letting MSBuild autogenerate a correct path by setting GenerateDocumentationFile instead:

<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
Contributor

dasMulli commented Dec 30, 2017

@pgmolloy does anything not work in your publish scenario? This has been implemented.

For those having trouble getting DocumentationFile to work, I recommend deleting it and letting MSBuild autogenerate a correct path by setting GenerateDocumentationFile instead:

<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
@pgmolloy

This comment has been minimized.

Show comment
Hide comment
@pgmolloy

pgmolloy Dec 31, 2017

Hi Martin, I have finally got this to work. I really don't know what fixed my issue as I decided to delete all swagger tooling and files. Redeployed the API without swagger and made sure all worked fine. I then added swagger tooling and let MSBuild do everything again and wullah all is fine. Thanks Martin for your help. Cheers Peter

Hi Martin, I have finally got this to work. I really don't know what fixed my issue as I decided to delete all swagger tooling and files. Redeployed the API without swagger and made sure all worked fine. I then added swagger tooling and let MSBuild do everything again and wullah all is fine. Thanks Martin for your help. Cheers Peter

@aeroson

This comment has been minimized.

Show comment
Hide comment
@aeroson

aeroson Feb 14, 2018

None of the above worked for me, ended up including the ,xml file into project with Properties: "Build Action": Content, "Copy to Output Directory": Copy always

aeroson commented Feb 14, 2018

None of the above worked for me, ended up including the ,xml file into project with Properties: "Build Action": Content, "Copy to Output Directory": Copy always

@peterneave

This comment has been minimized.

Show comment
Hide comment
@peterneave

peterneave Feb 14, 2018

Realised that I was calling msbuild with Release configuration (the same way the build agents were). I solved my problem by simply including the DocumentationFile in my project.

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
  <!-- ... -->
  <DocumentationFile>bin\Api.XML</DocumentationFile>
</PropertyGroup>

peterneave commented Feb 14, 2018

Realised that I was calling msbuild with Release configuration (the same way the build agents were). I solved my problem by simply including the DocumentationFile in my project.

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
  <!-- ... -->
  <DocumentationFile>bin\Api.XML</DocumentationFile>
</PropertyGroup>
@djarvis

This comment has been minimized.

Show comment
Hide comment
@djarvis

djarvis Jun 19, 2018

None of any of the entire vastness of suggestions above worked for me. Is there some sort of updated solution that everyone else knows about except for me?

djarvis commented Jun 19, 2018

None of any of the entire vastness of suggestions above worked for me. Is there some sort of updated solution that everyone else knows about except for me?

@dsplaisted

This comment has been minimized.

Show comment
Hide comment
@dsplaisted

dsplaisted Jun 19, 2018

Member

@djarvis With the latest SDK, you should simply be able to set the GenerateDocumentationFile property to true, and the XML files will be published by default

Member

dsplaisted commented Jun 19, 2018

@djarvis With the latest SDK, you should simply be able to set the GenerateDocumentationFile property to true, and the XML files will be published by default

@djarvis

This comment has been minimized.

Show comment
Hide comment
@djarvis

djarvis Jun 20, 2018

@dsplaisted Where do I set this setting? .csproj? .pubxml? Still can't get it to both generate and publish it.

djarvis commented Jun 20, 2018

@dsplaisted Where do I set this setting? .csproj? .pubxml? Still can't get it to both generate and publish it.

@livarcocc

This comment has been minimized.

Show comment
Hide comment
@livarcocc

livarcocc Jun 20, 2018

Member

It is a MSBuild property that you can set in your csproj.

<GenerateDocumentationFile>true</GenerateDocumentationFile>
Member

livarcocc commented Jun 20, 2018

It is a MSBuild property that you can set in your csproj.

<GenerateDocumentationFile>true</GenerateDocumentationFile>
@scottaddie

This comment has been minimized.

Show comment
Hide comment
@scottaddie

scottaddie Jun 22, 2018

Member

@livarcocc Which version of the .NET Core SDK is required to use this MSBuild property? I'd like to get this updated in the ASP.NET Core Swashbuckle doc.

Member

scottaddie commented Jun 22, 2018

@livarcocc Which version of the .NET Core SDK is required to use this MSBuild property? I'd like to get this updated in the ASP.NET Core Swashbuckle doc.

@livarcocc

This comment has been minimized.

Show comment
Hide comment
@livarcocc

livarcocc Jun 22, 2018

Member

I don't remember exactly, but I always recommend installing the latest one, 2.1.300. Otherwise, 2.1.201 should also be a good one, without all the 2.1 changes.

Member

livarcocc commented Jun 22, 2018

I don't remember exactly, but I always recommend installing the latest one, 2.1.300. Otherwise, 2.1.201 should also be a good one, without all the 2.1 changes.

@dasMulli

This comment has been minimized.

Show comment
Hide comment
@dasMulli

dasMulli Jun 22, 2018

Contributor

GenerateDocumentationFile: 1.0.0
But has since had a bug for VB projects. (would output it to a wrong path)

PublishDocumentationFile, PublishReferencesDocumentationFiles: 2.0.0
These both default to true to match the behavior of project references - dotnet publish would copy the xml of <ProjectReference>es but not of the published application. Now copies all documentation by default and introduces these to properties to allow opting out of documentation publishing through these properties - #1062

2.1.300 fixed the VB issue - #1848

Contributor

dasMulli commented Jun 22, 2018

GenerateDocumentationFile: 1.0.0
But has since had a bug for VB projects. (would output it to a wrong path)

PublishDocumentationFile, PublishReferencesDocumentationFiles: 2.0.0
These both default to true to match the behavior of project references - dotnet publish would copy the xml of <ProjectReference>es but not of the published application. Now copies all documentation by default and introduces these to properties to allow opting out of documentation publishing through these properties - #1062

2.1.300 fixed the VB issue - #1848

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment