【问题标题】:Azure Pipelines: "Error NETSDK1004: Assets file '...\project.assets.json' not found." in Pipeline when caching Nuget packages with Cache@2 taskAzure Pipelines:“错误 NETSDK1004:找不到资产文件 '...\project.assets.json'。”在使用 Cache@2 任务缓存 Nuget 包时在管道中
【发布时间】:2021-01-28 19:38:13
【问题描述】:

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

我正在使用 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 包还原以生成此文件。

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

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

【问题讨论】:

  • 嗨 urig,您对此案还有其他顾虑吗?
  • @PatrickLu-MSFT 谢谢。看到我没有找到关于如何缓存 project.assets.json 文件以及 nuget 包的说明,我唯一的问题是 我不能使用 Cache@2 任务来缓存 Microsoft 托管的 nuget 包代理。这对我来说没有意义,但我想我只能放弃缓存,因为我目前无法切换到自托管代理。

标签: .net .net-core azure-devops nuget azure-devops-pipelines


【解决方案1】:

更新:

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

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

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

更多详情请看这篇博客:


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

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

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

当这种情况发生时,我不得不增加我的缓存键并且 环境变量强制刷新缓存,然后执行以下操作 构建工程。

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

【讨论】:

  • 感谢@PatrickLu-MSFT。你写的有道理。你能详细说明我如何缓存project.assets.json 文件吗?我需要对我的azure-pipelines.yml 文件进行哪些更改?
  • @urig 根据您的 YAML 文件,pool: vmImage: 'windows-latest' 您正在使用主机代理,恐怕它无法做到这一点。对于您的方案(减少构建时间),建议您仍然涉及 NuGet 还原,但更改为自托管代理以运行您的管道。给您带来的不便,我们深表歉意。
猜你喜欢
  • 1970-01-01
  • 2021-08-19
  • 1970-01-01
  • 1970-01-01
  • 2018-07-04
  • 1970-01-01
  • 2019-05-01
  • 1970-01-01
  • 2020-03-31
相关资源
最近更新 更多