我有一个.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>
将生成的packages.lock.json
文件添加到git。
将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软件包还原以生成此文件。
发生这种情况时,我被迫增加缓存键和环境变量以强制刷新缓存,然后进行以下构建。
我的问题是-为什么会发生这种情况,我该如何解决它,以使我的构建不再如此脆弱?
答案 0 :(得分:2)
更新:
如果恢复和保存缓存的时间少于从头开始生成输出的时间,则缓存可以有效地缩短构建时间。因此,缓存可能无法在所有情况下都有效,并且实际上可能会对构建时间产生负面影响。
由于需要在生成器上重新生成project.assets.json ,并具有指向此共享缓存的已解析路径,即使无需下载任何软件包也是如此。
在这种情况下,要提高性能,您可以在自托管代理上运行管道,或将这些软件包直接推送到DevOps存储库。
更多详细信息,请访问此博客:
根据您的描述和错误信息,NUGET_PACKAGES: $(Pipeline.Workspace)/.nuget/packages
。
好像您没有缓存导致此问题的project.assets.json。
如果您的构建工具未设置为对设置为使用PackageReference
和packages.config
的项目进行还原,并且主要影响Net Core和Netstandard新样式项目,则会发生此问题。
发生这种情况时,我被迫增加缓存键,然后 环境变量以强制刷新缓存,然后执行以下操作 构建作品。
实际上,当您强制使用新密钥时,它与密钥无关。 Azure DevOps服务未使用您的缓存程序包,并强制“运行新的NuGet还原”。在完整的还原过程中,此文件生成成功。因此构建也成功。