是否可以同时使用本地NuGet存储库和远程存储库

时间:2013-02-12 00:25:15

标签: nuget

我一直在将我们的图书馆项目转换为NuGet包,并在内部NuGet Feed上托管它们。这很有效,并且减少了开发人员重新创建帮助程序类和“重新发明轮子”。另一个巨大优势是其他团队现在可以从我们的项目中使用“已发布”的库。到目前为止,这是一场巨大的胜利。

我们面临的唯一问题是本地构建。我们想要做的是在将构建推送到NuGet提要之前,在我们的消费项目中测试库。我们遇到了一个问题,因为使用这些库的项目被设置为使用本地提要(构建服务器上的包恢复允许我们的主干与最新的“已发布”库一起构建)。

有没有办法让本地构建从本地存储库中获取?我已经开始为创建本地包文件的库进行后构建任务。使用NuGet.config我想我应该能够屏蔽某些存储库,然后屏蔽构建服务器上的配置文件。我的理论是,当使用本地构建时,应该选择本地存储库,并在构建服务器上使用feed。

这可能吗?有没有其他人记录过如何做到这一点?

这是我用于创建本地包的后构建任务:

  <PropertyGroup>
    <PackOutputDir>$([System.IO.Path]::Combine($(SolutionDir), "..\Prerelease"))</PackOutputDir>
    <BuildSpecCommand>$(NuGetCommand) spec $(ProjectFileName) -force -NonInteractive -Verbosity detailed</BuildSpecCommand>
    <PackCommand>$(NuGetCommand) pack $(ProjectFileName) -OutputDirectory "$(PackOutputDir)"</PackCommand>
  </PropertyGroup>
  <Target Name="AfterBuild" Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <Exec Command="$(BuildSpecCommand)" LogStandardErrorAsError="true" Condition=" '$(OS)' == 'Windows_NT' " />
    <Exec Command="$(PackCommand)" LogStandardErrorAsError="true" Condition=" '$(OS)' == 'Windows_NT' " />
  </Target>

我把这个NuGet.config放在我们团队项目的根目录下。此文件隐藏在构建服务器上:

<configuration>
  <packageSources>
    <add key="NuGet official package source" value="https://nuget.org/api/v2/" />
    <add key="TestSource" value="Source\Prerelease" />
  </packageSources>
  <disabledPackageSources>
    <add key="LocalNuGetFeed" value="LocalNuGetFeed" />
  </disabledPackageSources>
  <activePackageSource>
    <add key="All" value="(Aggregate source)"  />
  </activePackageSource>
</configuration>

这是我放在一个文件夹中的NuGet.config,该文件夹应该在构建服务器的层次结构中被选中:

<configuration>
  <packageSources>
    <add key="NuGet official package source" value="https://nuget.org/api/v2/" />
    <add key="LocalNuGetFeed" value="http://team2:12345/nuget" />
  </packageSources>
  <disabledPackageSources>
  </disabledPackageSources>
  <activePackageSource>
    <add key="All" value="(Aggregate source)"  />
  </activePackageSource>
</configuration>

更新 基于提供的答案,我更改了nuget.targets文件。理想情况下,我不想这样做,但如果这是实现我想要完成的目标的最佳方式,那么我对这种类型的编辑很好。

  <ItemGroup Condition=" '$(PackageSources)' == '' And '$Configuration' == 'Release'">
    <PackageSource Include="https://nuget.org/api/v2/" />
    <PackageSource Include="http://team2:12345/nuget/" />
  </ItemGroup>
  <ItemGroup Condition=" '$(PackageSources)' == '' And '$Configuration' != 'Release'">
    <PackageSource Include="https://nuget.org/api/v2/" />
    <PackageSource Include="C:\temp\NuGet\Prerelease" />
  </ItemGroup>

这里的想法是使用之前发布的库项目的构建任务,以便将它们的包输出到磁盘上的临时文件夹。上面的代码应该在nuget.targets文件中,用于那些我们将需要在开发人员在本地计算机上工作时立即对库更新进行任何更改的项目,但构建服务器只会在我们的本地提要期间与我们的本地提要进行通信。团队建设过程。

这是对的吗?

另一个想法...... 在与同事讨论之后,我们提出了另一种可能在实践中更有效的解决方案。我们决定在AvalonDock项目上对其进行建模。当您下载源代码并打开该项目的解决方案时,您不仅会看到构建UI控件的代码,还会看到一个使用所述控件的所有功能的示例项目。

他的想法是,在我们的库项目中,代码只是C#库,单元测试应该足以有效地解决任何问题。推送这些库的构建也是门控的,这意味着只有在构建(和测试)完成时才应用签入。

对于UI控件,他指出了AvalonDock的上述示例。包括使用所有控件的项目应该可以缓解大多数问题。由于UI控件上的单元测试有限,因此在提交代码和启动构建过程之前,仍然需要开发人员负责检查测试项目中的控件。

这种方法的一般意见是什么?

1 个答案:

答案 0 :(得分:12)

您绝对可以一次使用多个存储库。这里的重要部分是您需要定义您希望它们使用的顺序。在恢复/安装软件包时,NuGet将首先查看第一个存储库,如果没有找到它将扫描第二个存储库,依此类推。

如果您需要本地存储库优先于“已发布”存储库,则需要确保本地存储库是列表中的第一个存储库

你的方法一见钟情,虽然你也可以使用NuGet包恢复附带的.nuget\NuGet.targets文件来寻找MSBuild解决方案(没有这些配置修改)。 通过在<PackageSources>元素中添加源来定义您的源,然后(可能基于构建配置调试|发布)您可以切换要在<RestoreCommand>中使用的仓库。