自动构建NuGet包,包括引用的依赖项

drz*_*aus 64 build-automation visual-studio nuget nuget-package

我想运行本地/内部NuGet存储库.我想我已经想出了如何"重用"现有的NuGet包,方法是将它们包含在使用NuGet的虚拟项目中,并扫描包文件以获取我的本地缓存.nupkg文件,但......

如何.nupkg从项目中创建nuget package(),自动包含所有 dll依赖项,而不仅仅是通过NuGet获取的依赖项?

特别:

  1. 创建解决方案
  2. 添加一个新项目
  3. 添加对各种.dll文件/其他项目的引用< - 这是缺少的部分
  4. 通过包管理器/ cmdline/whatever添加NuGet包
  5. 东西自动创造了.nupkg

从我发现的,你应该做的事情

  • 手动编辑您.csproj要添加的文件<BuildPackage>true</BuildPackage>以包含依赖项
  • 手动创建一个.nuspec文件并手动列出你的依赖项(类似吗?)
  • 手动运行nuget pack您的.nuspec文件

但一切都是手工的,这是愚蠢的.即使是半自动解决方案仍然是笨拙或半手动:

我会满足于.nuspec从项目引用中自动创建清单的东西.然后理论上+ nuget构建事件可以汇总到构建项目/ nuget包中,这是我真正想要看到的.

Jul*_*ian 64

您的观点#3(添加对各种.dll文件/其他项目的引用< - 这是缺失的部分)确实包含两个不同的问题:(1)添加对各种dll文件的引用,以及(2)添加对其他项目的引用同样的解决方案.

NuGet 2.5开始,这里的数字(2)得到了一些额外的支持.在为项目创建NuGet包时,您可以添加一个选项以包含对同一解决方案中其他项目的引用:

nuget pack projectfile.csproj -IncludeReferencedProjects
Run Code Online (Sandbox Code Playgroud)

如果projectfile.csproj引用解决方案中也作为NuGet包公开的任何其他项目,则这些项目的NuGet包将作为依赖项添加.如果它引用了您的解决方案中没有将自己暴露为NuGet包的项目,那么它们的dll将包含在此NuGet包中.

至于(1),如果你发现自己经常在你的项目中添加不能作为NuGet包使用的dll,你可以用这些文件创建你自己的(内部)NuGet包.如果您随后将这些dll作为NuGet包而不是直接添加到文件中,则此NuGet包将成为项目的NuGet包中的依赖项.

  • 是否有与“.csproj”等效的“IncludeReferencedProjects”? (27认同)
  • 它不会自动获取bin目录中的任何内容,你必须明确指定它,如下所示:`<file src ="bin\release\*.dll"target ="lib"/>` (6认同)
  • *叹气*#1对我的口味来说仍然过于手动.实际上,"用这些文件创建你自己的(内部)NuGet包"是我正在尝试做的 - 这个问题的重点是我想自动将非NuGet .dll汇总到一个NuGet包中.不通过并在`.nuspec`中手动列出每个dll,我认为这是你的建议? (3认同)
  • 值得注意的是,如果被引用的项目碰巧有一个nuspec文件,那么nuget会将其视为一个包而不包含在lib文件夹中,但会将其添加到包依赖项中 (2认同)

joe*_*elc 13

我找到了一篇关于这个主题的写得很好的文章。我对某些具有依赖关系层次结构的包有同样的问题,到目前为止,我一直将每个包作为单独的 NuGet 包上传(这真是浪费时间)

我刚刚测试了在这里找到的解决方案:https : //dev.to/wabbbit/include-both-nuget-package-references-and-project-reference-dll-using-dotnet-pack-2d8p

在使用 NuGet 包资源管理器检查 NuGet 包后,确实存在引用项目生成的 DLL。我将通过实际将此包提交给 NuGet 并对其进行测试来进行测试。

这是我的来源,以防它对您有所帮助:https : //github.com/jchristn/NuGetPackTest

和测试 NuGet 包:https : //www.nuget.org/packages/NuGetPackTest/1.0.0

该解决方案似乎运行良好。我不知道当有多层引用时它会是什么样子,我敢肯定它会变得非常多毛而且非常快。

在此处输入图片说明

来自 NuGetPackTest 库的 .csproj,它引用了项目 TestLibrary(为简洁起见,删除了部分)

<Project Sdk="Microsoft.NET.Sdk">
 
  <PropertyGroup>
    <TargetFrameworks>netstandard2.0;netcoreapp3.0;netcoreapp3.1;net461</TargetFrameworks>
    ...
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>

    <!-- added this line -->
    <TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
  </PropertyGroup>

  <ItemGroup>

    <!-- modified this ProjectReference to include the children ReferenceOutputAssembly and IncludeAssets -->
    <ProjectReference Include="..\TestLibrary\TestLibrary.csproj">
      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
      <IncludeAssets>TestLibrary.dll</IncludeAssets>
    </ProjectReference>
  </ItemGroup>

  <!-- added this section -->
  <Target DependsOnTargets="ResolveReferences" Name="CopyProjectReferencesToPackage">
    <ItemGroup>
      <BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))"/>
    </ItemGroup>
  </Target>
  
</Project>
Run Code Online (Sandbox Code Playgroud)

  • 这立即解决了我的问题。我按照链接中提到的说明进行操作,并且成功了。很高兴在您的答案中添加要点。 (2认同)
  • 此解决方案不会将参考项目的 nuget 依赖项添加为依赖项。因此,您必须将子项目中添加的所有 nuget 依赖项添加到将成为 nuget 包的主项目中。至少这就是我遇到的情况,包括在另一个项目中创建的 nuget 包会导致“程序集或文件未找到”问题。 (2认同)

Joh*_*zen 5

对于其他Google员工,如果您使用NuGet.targets文件运行NuGet Pack,则可以使用以下命令:

<Target Name="PrePackage" BeforeTargets="BuildPackage">
  <PropertyGroup>
    <BuildCommand>$(BuildCommand) -IncludeReferencedProjects</BuildCommand>
  </PropertyGroup>
</Target>
Run Code Online (Sandbox Code Playgroud)

  • 听起来很有希望,但没有足够的信息来实际实施。您所说的 NuGet.targets 文件是什么?我通常熟悉构建目标文件,但不熟悉这个特定的用例 (12认同)
  • 投赞成票,因为老化时间不是投反对票的有效标准 (4认同)

Pai*_*tal 5

我通过将整个 TargetDir 添加到 nuget 包中解决了这个问题。

只需将其添加到 .csproj 中:

<Target Name="IncludeAllFilesInTargetDir" AfterTargets="Build">
  <ItemGroup>
    <None Include="$(TargetDir)\**">
      <Pack>true</Pack>
      <PackagePath>tools</PackagePath>
    </None>
  </ItemGroup>
</Target>
Run Code Online (Sandbox Code Playgroud)