问题描述
我有一个.net core 3.1解决方案,其中包含多个Web和类库项目。所有软件包都在<packagereference>
文件中使用.csproj
格式。
我正在使用Azure DevOps Pipelines构建解决方案,我想通过缓存Nuget软件包而不是每次运行都从nuget.org还原它们来减少构建时间。
-
将此
nuget.config
文件添加到我的解决方案中,以便始终从nuget.org恢复软件包:<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <clear /> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" /> </packageSources> </configuration>
-
在我的解决方案中添加了一个
Directory.Build.props
文件,因此对于每个项目,在构建时都会生成一个packages.lock.json
。<Project> <PropertyGroup> <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile> <disableImplicitNuGetFallbackFolder>true</disableImplicitNuGetFallbackFolder> </PropertyGroup> </Project>
-
将Cache@2任务集成到我的
azure-pipeline.yml
文件中,如下所示:trigger: - master - users/* pool: vmImage: 'windows-latest' variables: buildConfiguration: 'Debug' NUGET_PACKAGES: $(Pipeline.Workspace)/.nuget/packages steps: - task: Cache@2 displayName: Cache nuget packages inputs: key: 'nuget 5 | "$(Agent.OS)" | **/packages.lock.json,!**/bin/**' restoreKeys: | nuget 5 | "$(Agent.OS)" path: $(NUGET_PACKAGES) cacheHitvar: CACHE_RESTORED5 - task: DotNetCoreCLI@2 displayName: 'Restoring nuget packages ($(buildConfiguration))' condition: ne(variables.CACHE_RESTORED5,'true') inputs: command: 'restore' projects: '**/*.csproj' includeNuGetorg: true arguments: '--configuration $(buildConfiguration)' - task: DotNetCoreCLI@2 displayName: 'Build solution ($(buildConfiguration))' inputs: command: 'build' arguments: '--configuration $(buildConfiguration) --no-restore'
我已经成功地成功运行了管道,因此在第一次运行时,它会从nuget.org还原软件包并将其保存到缓存中,而在随后的运行中,它将从缓存中读取它们。
我的问题是我的构建偶尔会在“构建解决方案”阶段中断,并为每个解决方案项目显示以下错误消息:
## [错误] C:\ Program Files \ dotnet \ sdk \ 3.1.402 \ Sdks \ Microsoft.NET.Sdk \ targets \ Microsoft.PackageDependencyResolution.targets(241,5):错误NETSDK1004:资产文件'D :找不到\\ a \ 1 \ s \ MyProject \ obj \ project.assets.json'。运行NuGet软件包还原以生成此文件。
发生这种情况时,我被迫增加缓存键和环境变量以强制刷新缓存,然后进行以下构建。
我的问题是-为什么会发生这种情况,我该如何解决它,以使我的构建不再如此脆弱?
解决方法
更新:
如果恢复和保存缓存的时间少于从头开始生成输出的时间,则缓存可以有效地缩短构建时间。因此,缓存可能无法在所有情况下都有效,并且实际上可能会对构建时间产生负面影响。
由于需要在生成器上重新生成project.assets.json ,并具有指向此共享缓存的已解析路径,即使无需下载任何软件包也是如此。
在这种情况下,要提高性能,您可以在自托管代理上运行管道,或将这些软件包直接推送到DevOps存储库。
更多详细信息,请访问此博客:
- How can I use msbuild without project.assets.json or nuget restore?
- How to cache the project.assets.json for each project from a solution in AzureDevOps Pipelines?
根据您的描述和错误信息,NUGET_PACKAGES: $(Pipeline.Workspace)/.nuget/packages
。
好像您没有缓存导致此问题的project.assets.json。
如果您的构建工具未设置为对设置为使用PackageReference
和packages.config
的项目进行还原,并且主要影响Net Core和Netstandard新样式项目,则会发生此问题。
发生这种情况时,我被迫增加缓存键,然后 环境变量以强制刷新缓存,然后执行以下操作 构建作品。
实际上,当您强制使用新密钥时,它与密钥无关。 Azure DevOps服务未使用您的缓存程序包,并强制“运行新的NuGet还原”。在完整的还原过程中,此文件生成成功。因此构建也成功。