7

我有一个 .net core 3.1 解决方案,其中包含多个 Web 和类库项目。所有包都使用文件<PackageReference>中的格式.csproj

我正在使用 Azure DevOps Pipelines 构建解决方案,我想通过缓存 Nuget 包而不是在每次运行时从 nuget.org 恢复它们来减少构建时间。

根据文档和博客文章的一些指导,我已经:

  1. 将此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>
    
  2. 在我的解决方案中添加了一个Directory.Build.props文件,以便对于每个项目,packages.lock.json在构建时都会生成一个。

    <Project>
      <PropertyGroup>
        <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
        <DisableImplicitNuGetFallbackFolder>true</DisableImplicitNuGetFallbackFolder>
      </PropertyGroup>
    </Project>
    
  3. 将生成的packages.lock.json文件添加到 git。

  4. 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 包还原以生成此文件。

当这种情况发生时,我不得不增加我的缓存键和环境变量来强制刷新缓存,然后下面的构建工作。

我的问题是 -为什么会发生这种情况,我该如何解决它,以便我的构建不再如此不稳定?

4

1 回答 1

3

更新:

如果恢复和保存缓存的时间少于从头开始再次生成输出的时间,缓存可以有效地缩短构建时间。因此,缓存可能并非在所有情况下都有效,并且实际上可能对构建时间产生负面影响。

由于project.assets.json 需要在构建机器上重新生成,并且即使不需要下载包,也需要使用此共享缓存的解析路径。

对于这种情况,为了提高性能,您可以在自托管代理上运行管道或将这些包直接推送到 DevOps 存储库。

更多细节请看这个博客:


根据您的描述和错误信息, NUGET_PACKAGES: $(Pipeline.Workspace)/.nuget/packages.

看起来您没有缓存导致此问题的 project.assets.json。

当您的构建工具未设置为对设置为使用的项目进行恢复时会发生此问题,PackageReference并且packages.config主要影响 Net Core 和 Netstandard 新样式项目。

发生这种情况时,我被迫增加我的缓存键和环境变量以强制刷新缓存,然后以下构建工作。

实际上,当您强制使用新密钥时,它与密钥无关。Azure DevOps 服务未使用您的缓存包并强制“运行新的 NuGet 还原”。并且在完整的恢复过程中,这个文件生成成功。从而构建也成功。

于 2020-10-15T08:36:08.343 回答