When publishing a WebApi that references a dependency NuGet package, the XML comment files for dependency packages are not copied to the Publish folder.
This happens in the official Microsoft Docker builds.
FROM microsoft/dotnet:2.1-sdk AS build-env
ARG VERSION
WORKDIR /app
COPY . ./
RUN dotnet restore
RUN dotnet publish /p:Version=${VERSION} -c Release -o out
RUN ls -lR ~/.nuget/packages
RUN ls -lR /app/customer/out
The NuGet cache folder contains the following for the dependency package, notice the XML is not extracted.
/root/.nuget/packages/tp.net.core:
total 0
drwxr-xr-x. 3 root root 117 Feb 15 13:48 1.0.82
/root/.nuget/packages/tp.net.core/1.0.82:
total 288
-rw-r--r--. 1 root root 281585 Feb 15 13:48 tp.net.core.1.0.82.nupkg
-rw-r--r--. 1 root root 88 Feb 15 13:48 tp.net.core.1.0.82.nupkg.sha512
-rwxrw-rw-. 1 root root 4447 Feb 14 14:59 tp.net.core.nuspec
drwxr-xr-x. 3 root root 28 Feb 15 13:48 lib
/root/.nuget/packages/tp.net.core/1.0.82/lib:
total 0
drwxr-xr-x. 2 root root 54 Feb 15 13:48 netstandard2.0
/root/.nuget/packages/tp.net.core/1.0.82/lib/netstandard2.0:
total 624
-rwxrw-rw-. 1 root root 460800 Feb 14 14:59 TP.Net.Core.dll
-rwxrw-rw-. 1 root root 173892 Feb 14 14:59 TP.Net.Core.pdb
/app/customer/out only contains the DLL and the PDB
I tried microsoft/dotnet:2.1-sdk, microsoft/dotnet:2.1-sdk-alpine, microsoft/dotnet:2.2-sdk, all showed the same behaviour.
Publishing from a Windows Desktop, or MacOs desktop gets the correct result, with the dependency package's XML file extracted and copied into the publish folder
Contents of the nupkg
Metadata:
id: TP.Net.Core
version: 1.0.82
authors: TP.Net.Core
owners: TP.Net.Core
requireLicenseAcceptance: 'false'
description: Package Description
copyright: '2018'
Dependencies:
.NETStandard2.0:
...
Contents:
- File: _rels/.rels
- File: [Content_Types].xml
- File: TP.Net.Core.nuspec
- File: lib/netstandard2.0/TP.Net.Core.dll
- File: lib/netstandard2.0/TP.Net.Core.pdb
- File: lib/netstandard2.0/TP.Net.Core.xml
- File: package/services/metadata/core-properties/0a83a049e8a84378843f907cf66f8d8f.psmdcp
NuGet product used (NuGet.exe | VS UI | Package Manager Console | dotnet.exe):
dotnet.exe
NuGet version (x.x.x.xxx):
dotnet nuget --version
NuGet Command Line
4.8.1.0
dotnet.exe --version (if appropriate):
dotnet --version
2.1.403
VS version (if appropriate):
OS version (i.e. win10 v1607 (14393.321)):
Worked before? If so, with which NuGet version:
create a netstandard2.0 class lib, create a NuGet package, publish it (Nexus, NuGet)
add properties to the project
<GenerateDocumentationFile>true</GenerateDocumentationFile>
create a console app, reference the class lib
Add the following target to the console app project
<Target Name="_ResolvePublishNuGetPackagePdbsAndXml" AfterTargets="RunResolvePublishAssemblies">
<ItemGroup>
<ResolvedFileToPublish Include="@(ResolvedAssembliesToPublish->'%(RootDir)%(Directory)%(Filename).pdb')" RelativePath="$([System.IO.Path]::ChangeExtension(%(ResolvedAssembliesToPublish.DestinationSubPath), '.pdb'))" DestinationSubPath="$([System.IO.Path]::ChangeExtension(%(ResolvedAssembliesToPublish.DestinationSubPath), '.pdb'))" Condition="'%(ResolvedAssembliesToPublish.PackageName)' != '' and Exists('%(RootDir)%(Directory)%(Filename).pdb')" />
<ResolvedFileToPublish Include="@(ResolvedAssembliesToPublish->'%(RootDir)%(Directory)%(Filename).xml')" RelativePath="$([System.IO.Path]::ChangeExtension(%(ResolvedAssembliesToPublish.DestinationSubPath), '.xml'))" DestinationSubPath="$([System.IO.Path]::ChangeExtension(%(ResolvedAssembliesToPublish.DestinationSubPath), '.xml'))" Condition="'%(ResolvedAssembliesToPublish.PackageName)' != '' and Exists('%(RootDir)%(Directory)%(Filename).xml')" />
</ItemGroup>
</Target>
Publish the project in Visual Studio/Rider/VsCode, the XML file for the class lib is published
Build the project using Docker.
FROM microsoft/dotnet:2.1-sdk AS build-env
ARG VERSION
WORKDIR /app
COPY . ./
RUN dotnet publish /p:Version=${VERSION} -c Release -o out
FROM microsoft/dotnet:2.1-aspnetcore-runtime
WORKDIR /
COPY --from=build-env /app/customer/out .
ENTRYPOINT ["dotnet", "customer.dll"]
Examine the image, notice the XML file for the class library is missing
verbose logs added below
Please include verbose logs (NuGet.exe
project added below
Example using a console app and Newtonsoft.Json as the dependency package.
Mac, publish extracts DLL,PDB,XML
Docker I only see DLL, PDB
Logs
I found this interesting, maybe you will too. NuGet is clearly doing something different inside a container.
Ran the same test using the latest Microsoft bionic (Ubuntu) Docker image, and then on my Ubuntu Bionic desktop.
Bionic Docker Image logs
Bionic Desktop logs
I managed to stumble onto the following information...
https://github.com/JetBrains/teamcity-docker-agent/issues/42
https://docs.microsoft.com/en-us/nuget/tools/cli-ref-environment-variables
NUGET_XMLDOC_MODE=skip
setting comes from the original docker images provided by Microsoft,
This is causing it to skip extracting the XML file, only in Docker.
Adding
ENV NUGET_XMLDOC_MODE=none
to my Dockerfile corrects this issue.
FYI, if you split up your docker builds in stages that separate restore
, build
, and publish
then it is important to note that:
ENV NUGET_XMLDOC_MODE=none
needs to be set before the restore
stage
Most helpful comment
I managed to stumble onto the following information...
https://github.com/JetBrains/teamcity-docker-agent/issues/42
https://docs.microsoft.com/en-us/nuget/tools/cli-ref-environment-variables
This is causing it to skip extracting the XML file, only in Docker.
Adding
to my Dockerfile corrects this issue.