快取 NuGet 套件

Azure DevOps 服務 |Azure DevOps Server |Azure DevOps Server 2022

管線快取透過儲存相依項,供未來運行重複使用,協助縮短建置時間。 在本文中,您將瞭解如何使用 快取工作 來快取和還原 NuGet 套件。

注意

傳統釋出管線不支援管線快取。

先決條件

產品 規格要求
Azure DevOps - Azure DevOps 專案。
- 權限:
    - 若要授與專案中所有管線的存取權,您必須是 Project Administrators 群組的成員,。

鎖定依賴項

設定快取工作之前,您必須鎖定專案的相依性,併產生 package.lock.json 檔案。 唯一的快取密鑰衍生自此鎖定檔案內容的哈希,以確保組建之間的一致性。

若要鎖定專案的相依性,請將 RestorePackagesWithLockFile 屬性新增至 csproj 檔案,並將它設定為 true 。 當您執行 nuget restore時,它會在專案的根目錄中產生 packages.lock.json 檔案。 請務必將packages.lock.json檔案納入您的原始程式碼。

<PropertyGroup>
  <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>

注意

如果你使用套件鎖定檔案,可以考慮在 global.json 檔案中指定精確的 .NET SDK 版本,並將 rollForward 設為 disable。 這有助於防止當 .NET SDK 版本間隱含依賴性差異時,導致鎖定還原失敗。 更多資訊請參見 .NET SDK global.json。

快取 NuGet 套件

若要快取 NuGet 套件,請定義管線變數,以指向執行管線之代理程式上的套件位置。

在下列範例中,packages.lock.json 的內容會哈希以產生動態快取索引鍵。 這可確保每當檔案變更時,就會建立新的快取索引鍵。

顯示如何在 Azure Pipelines 中產生快取密鑰的螢幕快照。

variables:
  NUGET_PACKAGES: $(Pipeline.Workspace)/.nuget/packages

- task: Cache@2
  displayName: Cache v2 task 
  inputs:
    key: 'nuget | "$(Agent.OS)" | **/packages.lock.json,!**/bin/**,!**/obj/**'
    restoreKeys: |
       nuget | "$(Agent.OS)"
       nuget
    path: '$(NUGET_PACKAGES)'
    cacheHitVar: 'CACHE_RESTORED'

注意

快取是固定的,一旦建立快取,就無法修改其內容。

還原快取

只有在 CACHE_RESTORED 變數 false時,才會執行以下任務。 這表示,如果發生快取叫用時(快取中已有可用的套件),則會略過還原步驟以節省時間和資源。 如果找不到任何快取,還原指令會執行以下載必要的相依性。

- task: NuGetCommand@2
  condition: ne(variables.CACHE_RESTORED, true)
  inputs:
    command: 'restore'
    restoreSolution: '**/*.sln'

注意

如果您使用 Ubuntu 24.04 或更新版本,則必須搭配 .NET CLI 使用 NuGetAuthenticate 工作,而不是使用 NuGetCommand@2 工作。 如需詳細資訊,請參閱 支援較新的Ubuntu裝載映像。

處理「找不到project.assets.json」錯誤

如果您在建置工作期間遇到 「找不到project.assets.json」錯誤,請從還原工作中移除條件 condition: ne(variables.CACHE_RESTORED, true)。 這可確保還原命令會執行併產生 project.assets.json 檔案。 還原工作不會重新下載已存在於對應資料夾中的套件。

注意

管線可以包含多個快取工作,而相同管線內的作業和工作可以存取和共用相同的快取。

表現比較

管線快取可大幅縮短還原相依性所需的時間,進而加快建置速度。 下列比較說明快取對兩個不同管線的執行時間所造成的影響:

  • 沒有快取(右):還原任務大約需要 41 秒。

  • 快取(左):我們已將快取工作新增至第二個管線,並將還原工作設定為只在發生快取遺漏時執行。 在此情況下,還原工作只會在8秒內完成。

顯示管線效能的螢幕快照,其中不含快取。

以下是完整的 YAML 管線以供參考:

pool:
  vmImage: 'windows-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'
  NUGET_PACKAGES: $(Pipeline.Workspace)/.nuget/packages

steps:
- task: NuGetToolInstaller@1
  displayName: 'NuGet tool installer'

- task: Cache@2
  displayName: 'NuGet Cache'
  inputs:
    key: 'nuget | "$(Agent.OS)" | **/packages.lock.json,!**/bin/**,!**/obj/**'
    restoreKeys: |
       nuget | "$(Agent.OS)"
       nuget
    path: '$(NUGET_PACKAGES)'
    cacheHitVar: 'CACHE_RESTORED'

- task: NuGetCommand@2
  displayName: 'NuGet restore'
  condition: ne(variables.CACHE_RESTORED, true)
  inputs:
    command: 'restore'
    restoreSolution: '$(solution)'

- task: VSBuild@1
  displayName: 'Visual Studio Build'
  inputs:
    solution: '$(solution)'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'

此方法也適用於 .NET Core 專案,前提是您的專案使用 packages.lock.json 來鎖定套件版本。 您可以將 RestorePackagesWithLockFile 設定為 * Csproj* 檔案中的 True,或執行下列命令來啟用此功能:dotnet restore --use-lock-file。