1
votes

I am using Sdk projects targeting .NET Framework 4.7.2. The project structure is:

SmokeTests
 |
 +--UITests
 |   |
 |   +--Common
 |
 + NonUITests
     |
     +--Common

where:

  • the SmokeTests project references both UITests and NonUITests using ProjectReferences
  • UITests and NonUITests both reference Common using a ProjectReference
  • UITests, NonUITests and Common reference some NuGet packages using PackageReferences
  • the SmokeTests project has no source code, but it does have some content files.

I use the SmokeTests project as a roll up project. When I build it, its bin\debug\net472 directory contains all the binaries and symbols I want to have in the nuget package, i.e.:

  • The NuGet dependencies of UITests, NonUITests and Common
  • The dlls of UITests, NonUITests and Common
  • The PDBs

The SmokeTests csproj looks like this:

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

  <PropertyGroup>
    <TargetFramework>net472</TargetFramework>
    <PackageId>SmokeTests</PackageId>
    <NoPackageAnalysis>true</NoPackageAnalysis>
    <IncludeBuildOutput>true</IncludeBuildOutput>
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
    <ContentTargetFolders>content</ContentTargetFolders>
  </PropertyGroup>

  <ItemGroup>
    <Content Include="**\*.ps1" Exclude="PSTests\run.ps1" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\NonUITests\NonUITests.csproj" />
    <ProjectReference Include="..\UITests\UITests.csproj" />
  </ItemGroup>

</Project>

I also have a Directory.Build.props file:

<Project>

  <PropertyGroup>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
    <AllowedReferenceRelatedFileExtensions>.pdb</AllowedReferenceRelatedFileExtensions>

    <Version>$([System.Text.RegularExpressions.Regex]::Match($(BuildName), `\d+\.\d+(?:.\d+)?(?:.\d+)?`))</Version>
    <Version Condition="'$(Version)' == ''">1.0.0.0</Version>
    <SourceRevisionId>$(Revision)</SourceRevisionId>
    <Company>My Company, Inc.</Company>
    <Copyright>Copyright © $([System.DateTime]::Now.Year) by My Company, Inc. All rights reserved.</Copyright>
    <Product>Smoke Tests</Product>
    <NeutralLanguage>en-US</NeutralLanguage>
  </PropertyGroup>

</Project>

When I build the solution, the produced SmokeTests.1.0.0.nupkg file does not contain any of the binaries, except the SmokeTests.dll itself. Clearly not what I want.

How can I get everything from bin\debug\net472 into the produced NuGet package without specifying a nuspec file?

I can always hack an after build step that would manipulate the nupkg file, but I want a proper way to do it.

EDIT 1

Judging by the amount of responses either the question is plain stupid or nobody uses .Net core. Posted it here as well - https://social.msdn.microsoft.com/Forums/vstudio/en-US/aa25cb08-ff95-4d81-b0c3-9c4a395f9999/how-to-pack-the-products-from-multiple-projects-into-one-nuget-without-any-nuspec-file?forum=msbuild

Could it be that SO lost its charm?

EDIT 2

I added the following properties to PublicLib.csproj to produce a NuGet package:

<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>$(AssemblyName)</PackageId>
<NoPackageAnalysis>true</NoPackageAnalysis>
<IncludeBuildOutput>true</IncludeBuildOutput>
<AllowedOutputExtensionsInPackageBuildOutputFolder>.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>

And it almost works, here is the content of the PublicLib.1.0.0.nupkg\lib\netstandard2.0 folder:

enter image description here

But IncludedLib.pdb is missing.

1
I guess nobody knows ...mark
I need to check your workaround. The reason I need project references is that the nuget package is to be consumed by octopus, which by design requires all the dependencies inside the NuGet. Now, I know I can use octopack, but that requires nuspec file and octopack itself is another dependency of the build. I want to avoid both. Does it make sense now? If so, could you provide an answer with a code sample, so that I could credit you?mark
@MartinUllrich - do you think you could improve your sample to include the pdb of the included project as well?mark

1 Answers

5
votes

So, after long hours of inspecting the NuGet.Build.Tasks.Pack.targets I have arrived at the following code for my roll up project SmokeTests:

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

  <PropertyGroup>
    <TargetFramework>net472</TargetFramework>

    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
    <PackageId>$(AssemblyName)</PackageId>
    <NoPackageAnalysis>true</NoPackageAnalysis>
    <IncludeBuildOutput>true</IncludeBuildOutput>
    <AllowedOutputExtensionsInPackageBuildOutputFolder>.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
    <ContentTargetFolders>content</ContentTargetFolders>

    <GenerateNuspecDependsOn>MyCustomizePacking</GenerateNuspecDependsOn>
  </PropertyGroup>

  <Target Name="MyCustomizePacking" Returns="@(NuGetPackInput);@(_BuildOutputInPackage);@(_TargetPathsToSymbols)">
    <ItemGroup>
      <NuGetPackInput Remove="@(BuiltProjectOutputGroupKeyOutput);@(DebugSymbolsProjectOutputGroupOutput)"/>
      <_BuildOutputInPackage Remove="@(BuiltProjectOutputGroupKeyOutput)"/>
      <_TargetPathsToSymbols Remove="@(DebugSymbolsProjectOutputGroupOutput)"/>

      <NuGetPackInput Include="@(ReferenceCopyLocalPaths);@(AllItemsFullPathWithTargetPath)" />
      <_BuildOutputInPackage Include="%(ReferenceCopyLocalPaths.Identity)" >
        <TargetFramework>$(TargetFramework)</TargetFramework>
      </_BuildOutputInPackage>
      <_BuildOutputInPackage Include="%(AllItemsFullPathWithTargetPath.Identity)" >
        <TargetFramework>$(TargetFramework)</TargetFramework>
      </_BuildOutputInPackage>
    </ItemGroup>
  </Target>

  <ItemGroup>
    <Content Include="**\*.ps1" Exclude="PSTests\run.ps1" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\NonUITests\NonUITests.csproj" />
    <ProjectReference Include="..\UITests\UITests.csproj" />
  </ItemGroup>

</Project>

The only way I could find to pack all my project and package references into the NuGet was to hook into the process through GenerateNuspecDependsOn by injecting my target MyCustomizePacking. This target does the following:

  1. Remove the SmokeTests.dll and SmokeTests.pdb from the relevant item groups, because this is a roll up project with no code on its own, I do not need its dll or pdb inside the package.
  2. Include @(ReferenceCopyLocalPaths) and @(AllItemsFullPathWithTargetPath) in the relevant item groups.

Seems to work,but I am not happy with my implementation. I wish there was better support for this.