2013-02-12 152 views
10

我一直在将我们的库项目转换为NuGet包并将它们托管在内部的NuGet Feed上。这非常有效,并削减了开发人员重新创建帮助类和“重新发明轮子”的能力。另一个巨大的优势是其他团队现在可以使用我们项目中的“发布”库。基本上迄今为止这是一场巨大的胜利。是否可以同时使用本地NuGet存储库和远程存储库

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

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

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

这里是我使用创建本地包之后生成任务:

<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控件的单元测试是有限的,因此在提交代码并开始构建过程之前,开发人员仍然有责任检查测试项目中的控件。

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

回答

11

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

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

虽然您也可以使用NuGet软件包还原附带的.nuget\NuGet.targets文件来找到MSBuild解决方案(无需这些配置修改),但您的方法一看起来一切正常。 通过在<PackageSources>元素中添加它们来定义您的提要,然后(可能基于Build配置Debug | Release),您可以切换要用于<RestoreCommand>的回购。

+0

我更新了问题,并添加了我认为你的建议。请看看我已经添加的附加评论,并让我知道你的意见。 – 2013-02-13 13:44:23

+0

我注意到你仍然在两个构建配置中都包含官方的nuget feed,所以你的构建服务器也会在nuget.org上查看包。实际上,因为它是名单中的第一名,它首先在nuget.org上查看,然后在第二个pkg源上查看。不确定那是你想要的?你为什么不在你的本地仓库上复制nuget.org的依赖关系? – 2013-02-13 14:11:57

+0

我们在我们的解决方案中使用第三方项目,例如log4net。我想为这些包使用nuget存储库。我的目标是如果我的开发人员没有任何额外的依赖关系设置,他们就可以开始执行代码。 – 2013-02-13 16:16:45

相关问题