TFS 无法还原 NuGet 包

TFS Can't Restore NuGet Package

我让 TFS 进行了一些持续集成构建。今天,它打破了一种解决方案。似乎找不到 AutoMapper。其他包都可以找到。

几个相关点:

这来自 TFS 日志:

D:\Program Files\Microsoft Team Foundation Server 12.0\Tools\nuget.exe restore "C:\Builds\MyCompany Web\FclQuoteWcfService\src\FclQuoteWcfService.sln" -NonInteractive
Installing 'EntityFramework 6.1.3'.
Installing 'InternalPackage 1.0'.
Successfully installed 'InternalPackage 1.0'.
Successfully installed 'EntityFramework 6.1.3'.
Unable to find version '3.3.1' of package 'AutoMapper'.
C:\Program Files (x86)\MSBuild.0\bin\amd64\MSBuild.exe /nologo /noconsolelogger "C:\Builds\MyCompany Web\FclQuoteWcfService\src\FclQuoteWcfService.sln" /nr:False /fl /flp:"logfile=C:\Builds\MyCompany Web\FclQuoteWcfService\src\FclQuoteWcfService.log;encoding=Unicode;verbosity=normal" /p:SkipInvalidConfigurations=true /m /p:OutDir="C:\Builds\MyCompany Web\FclQuoteWcfService\bin\" /p:VCBuildOverride="C:\Builds\MyCompany Web\FclQuoteWcfService\src\FclQuoteWcfService.sln.vsprops" /dl:WorkflowCentralLogger,"D:\Program Files\Microsoft Team Foundation Server 12.0\Tools\Microsoft.TeamFoundation.Build.Server.Logger.dll";"Verbosity=Normal;BuildUri=vstfs:///Build/Build/230;IgnoreDuplicateProjects=False;InformationNodeId=12;TargetsNotLogged=GetNativeManifest,GetCopyToOutputDirectoryItems,GetTargetPath;TFSUrl=http://ctidev2k8:8080/tfs/MyCompany;"*WorkflowForwardingLogger,"D:\Program Files\Microsoft Team Foundation Server 12.0\Tools\Microsoft.TeamFoundation.Build.Server.Logger.dll";"Verbosity=Normal;" /p:BuildId="9aa9f8af-c9b9-4d0a-ba06-7cc959231d8e,vstfs:///Build/Build/230" /p:BuildLabel="FclQuoteWcfService_20150330.2" /p:BuildTimestamp="Mon, 30 Mar 2015 20:40:07 GMT" /p:BuildSourceVersion="LFclQuoteWcfService_20150330.2@$/MyCompany Web" /p:BuildDefinition="FclQuoteWcfService"
 Exception Message: MSBuild error 1 has ended this build. You can find more specific information about the cause of this error in above messages. (type BuildProcessTerminateException) Exception Stack Trace: at System.Activities.Statements.Throw.Execute(CodeActivityContext context) at System.Activities.CodeActivity.InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager) at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation)

这个我也看到了。它似乎在 NuGet 包恢复切换到内部源时立即被触发。一旦这样做,就不会切换回官方 nuget.org 提要,而是继续在内部提要上查找包。

确保两个包源都添加到您的 NuGet.config 文件中。还要确保两个来源都是 'active'。

<configuration>
    <packageSources>
        <add key="nuget.org"
             value="https://www.nuget.org/api/v2/" />
        <add key="example.com"
             value="http://example.com/feed/nuget/" />
    </packageSources>
    <activePackageSource>
        <add key="All"
             value="(Aggregate source)" />
    </activePackageSource>
</configuration>

请参阅 NuGet configuration file 文档。

除了 Matt 的回答之外,我还想强调以下来自 NuGet 文档的隐藏内容:

NuGet config files are treated in the following priority order (closest to the folder nuget.exe runs from wins), for example assuming the solution directory is c:\a\b\c:

  • c:\a\b\c\.nuget\nuget.config - This file is only used for solution level packages, and is not supported in nuget 3.0 - 3.4
  • c:\a\b\c\nuget.config
  • c:\a\b\nuget.config
  • c:\a\nuget.config
  • c:\nuget.config
  • User specific config file, %AppData%\NuGet\nuget.config.
  • Or the user specified file thru option -ConfigFile.

这可以解释在特定情况下的一些奇怪行为,在这种情况下,恢复会或不会选择配置的提要,具体取决于您是使用 nuget 2.x 还是 3.x

进行恢复

编辑:我发现 yet another reason why packages might not be detected:

I have package "A" with version 1.1.1.0 .

Prior 3.4 this command works well:

nuget install A -version 1.1.1.0

With NuGet 3.4 RC I get:

An error occurred while retrieving package metadata for 'A.1.1.1' from source 'N'. An error occurred while retrieving package metadata for 'A.1.1.1' from source 'N'. Data at the root level is invalid. Line 1, position 1.

...

The client treats 1.1, 1.1.0, 1.01.0 and 1.1.0.0 as the same version using SemVer rules. The reason non-normalized versions were special cased in the past is because for v2 http calls the client would first send the version string exactly as the user specified it

马特的回答让我走上了正确的轨道,但我们不使用内部提要,所以我不得不做更多的挖掘工作。这个答案至少适用于在 Visual Studio 2015 中创建并由 TFS 2015.

构建的项目

在 Visual Studio 中,打开 NuGet 包管理器设置(工具菜单 > NuGet 包管理器 > 包管理器设置)。从左侧的选项列表中选择 "Package Sources"。

在解决方案的根目录创建 nuget.config 文件。这应该是与“.sln”解决方案文件相同的文件夹位置。将以下内容复制到配置文件中:

<configuration>
    <packageSources>

    </packageSources>
    <activePackageSource>
        <add key="All"
             value="(Aggregate source)" />
    </activePackageSource>
</configuration>

<packageSources> 标签内,为 "Package Sources" 选项 window 中列出的每个来源创建一个 <add key="" value="" /> 条目。键是 URL 上方显示的源名称,值是 URL 本身。包括 "Available package sources" 和 "Machine-wide package sources" 中列出的那些。我没有为本地文件系统创建一个条目,因为它没有在这个解决方案中使用。根据上面的屏幕截图,完整的配置文件现在包含以下内容:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
        <add key="nuget.org"
             value="https://api.nuget.org/v3/index.json" />
        <add key="Microsoft and .NET"
             value="https://www.nuget.org/api/v2/curated-feeds/microsoftdotnet/" />
    </packageSources>
    <activePackageSource>
        <add key="All"
             value="(Aggregate source)" />
    </activePackageSource>
</configuration>

nuget.config 文件提交到源代码管理后,TFS 能够下载所有必需的 NuGet 包并成功构建解决方案。