共用方式為


快取 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>

快取 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