Jenkins没有使用新的MSBuild恢复目标恢复NuGet包

时间:2018-02-21 00:40:26

标签: c# jenkins msbuild nuget

我们有一个.net完整框架WPF应用程序,我们已经从 .net 4.6.2移动到4.7.1 ,同时在csproj文件中更改为 PackageReference 而不是packages.config。

在开发机器上构建似乎很好并且下载和恢复了包,但是当我们使用Jenkins 构建我们的 Windows Server 2012构建服务器时,nuget包似乎无法恢复正确。

我们正在使用 MSBuild v15.5 和最新的“msbuild / restore”命令在构建时恢复软件包。 注意:使用以前调用“nuget restore”的方式有效,但我们应该可以使用msbuild /restore now

包恢复过程似乎正在查看正确的NuGet服务器,并且看起来没有错误地进行恢复(这是在Jenkins上编译的测试解决方案以隔离问题):

Restore:
  Restoring packages for c:\Jenkins\workspace\Test\ConsoleApp1\ConsoleApp1.csproj...
  Committing restore...
  Generating MSBuild file c:\Jenkins\workspace\Test\ConsoleApp1\obj\ConsoleApp1.csproj.nuget.g.props.
  Generating MSBuild file c:\Jenkins\workspace\Test\ConsoleApp1\obj\ConsoleApp1.csproj.nuget.g.targets.
  Writing lock file to disk. Path: c:\Jenkins\workspace\Test\ConsoleApp1\obj\project.assets.json
  Restore completed in 577.05 ms for c:\Jenkins\workspace\Test\ConsoleApp1\ConsoleApp1.csproj.

  NuGet Config files used:
      c:\Jenkins\workspace\Test\NuGet.Config
      C:\Windows\system32\config\systemprofile\AppData\Roaming\NuGet\NuGet.Config

  Feeds used:
      http://devbuild/NuGetHost/nuget
      https://api.nuget.org/v3/index.json
Done Building Project "c:\Jenkins\workspace\Test\ConsoleApp1.sln" (Restore target(s)).

但是当msbuild编译代码时,我们会收到以下错误,看起来NuGet还没有被下载:

CSC : error CS0006: Metadata file 'C:\Windows\system32\config\systemprofile\.nuget\packages\log4net\2.0.8\lib\net45-full\log4net.dll' 
could not be found [c:\Jenkins\workspace\Test\ConsoleApp1\ConsoleApp1.csproj]

知道为什么nuget包没有恢复?

3 个答案:

答案 0 :(得分:27)

经过几个小时的搜索和筛选NuGet发布帖子并过滤掉.net核心噪音后,我有一个解决方法!

根据提出的一些NuGet和msbuild msbuild问题,在使用NuGet(或msbuild / restore)进行恢复时 在Windows Server 2012中的本地系统帐户下,NuGet使用的文件夹无法访问,或者由于32位与64位进程正在运行而是不同的文件夹,因此无法将nugets下载到该本地缓存文件夹。

msbuild想要在编译时查看的这个文件夹似乎是 C:\ Windows \ system32 \ config \ systemprofile \ .nuget \ packages

我们的解决方法是使用系统范围的环境变量 NUGET_PACKAGES 将NuGet包缓存文件夹设置为另一个可访问的文件夹,例如C:\ NugetPackageCache 例如

NUGET_PACKAGES=C:\NugetPackageCache

您还可以通过将构建环境 - >将环境变量注入构建过程 - >属性内容设置为:

,为每个Jenkins项目设置此项目
NUGET_PACKAGES=C:/NugetPackageCache

根据此NuGet issue post的另一个可能的解决方案是将环境变量设置为msbuild正在寻找nuget的文件夹,即

NUGET_PACKAGES=C:\Windows\system32\config\systemprofile\.nuget\packages

注意:环境变量优先于NuGet。他们似乎还没有将NuGet docs更新为mention the precedence

注意:要注入/设置环境变量,我们使用EnvInject Jenkins插件,如下所示:

Jenkins plugin with environment variables

答案 1 :(得分:1)

我们在.NET Framework项目中遇到了非常相似但略有不同的情况,最近在基于Windows的Jenkins服务器上进行了转换,将其都转换为4.7.2并使用<PackageReference>而不是packages.config该服务作为本地系统运行。在我们的案例中,我们发现nuget restore只是 not 在查看我们的私有MyGet提要,因此没有从该源安装我们自己的软件包,这使构建失败。在nuget restore命令后面的“已使用的供稿”列表中未显示它。

在这里受到mips答案的启发(以及从那里链接到的NuGet问题),我发现问题是,尽管将C:\Windows\system32\config\systemprofile\AppData\Roaming\NuGet\NuGet.config列为配置源(实际上是MyGet feed所在的位置)已配置),实际上它使用的是C:\Windows\SysWOW64\config\systemprofile\AppData\Roaming\NuGet\NuGet.config。通过将NuGet.config文件从system32位置复制到SysWOW64位置,可以解决此问题。

无需配置和注入NUGET_PACKAGES环境变量。

答案 2 :(得分:0)

对我们来说,这确实是个问题!

具体的问题是MSBuild实际上正在以下目录中寻找nuget软件包:

C:\Windows\SysWOW64\config\systemprofile\.nuget\packages

即使日志实际上说:

C:\Windows\System32\config\systemprofile\.nuget\packages

由于被调用的msbuild是在64位平台上运行的32位进程,因此当它在System32中查看时,实际上是在查看SysWOW64。

这是由file system redirection完成的。

我们的解决方案是简单地调用位于以下位置的64位版本的MSBuild:

C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin\amd64\MSBuild.exe

注意路径中的 amd64