Zwischenspeichern von NuGet-Paketen

Azure DevOps Services

Mit der Pipelinezwischenspeicherung können Sie die Buildzeit reduzieren, indem Sie Ihre Abhängigkeiten zwischenspeichern, die in späteren Ausführungen wiederverwendet werden sollen. In diesem Artikel erfahren Sie, wie Sie die Cacheaufgabe verwenden, um Ihre NuGet-Pakete zwischenzuspeichern und wiederherzustellen.

Hinweis

Die Pipelinezwischenspeicherung wird in Agentpoolaufträgen sowohl für YAML-Pipelines als auch für klassische Pipelines unterstützt. Sie wird jedoch nicht in klassischen Releasepipelines unterstützt.

Sperren von Abhängigkeiten

Um die Cache-Aufgabe einzurichten, müssen wir zuerst die Abhängigkeiten unseres Projekts sperren und eine package.lock.json-Datei erstellen. Wir verwenden den Hash des Inhalts dieser Datei, um einen eindeutigen Schlüssel für unseren Cache zu generieren.

Um die Abhängigkeiten Ihres Projekts zu sperren, legen Sie die Eigenschaft RestorePackagesWithLockFile in Ihrer csproj-Datei auf true fest. Bei der NuGet-Wiederherstellung wird die Sperrdatei packages.lock.json im Stammverzeichnis des Projekts generiert. Überprüfen Sie die Datei packages.lock.json in Ihrem Quellcode.

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

Zwischenspeichern von NuGet-Paketen

Wir müssen eine Pipelinevariable erstellen, die auf den Speicherort unserer Pakete auf dem Agent verweist, der die Pipeline ausführt.

In diesem Beispiel wird der Inhalt der Datei packages.lock.json gehashed, um einen dynamischen Cacheschlüssel zu erzeugen. Dadurch wird sichergestellt, dass jedes Mal, wenn die Datei geändert wird, ein neuer Cacheschlüssel generiert wird.

Screenshot der Generierung des Cacheschlüssels in Azure Pipelines

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

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

Hinweis

Caches sind unveränderlich. Nach der Erstellung eines Cache kann der Inhalt nicht mehr geändert werden.

Wiederherstellen des Cache

Diese Aufgabe wird nur ausgeführt, wenn die CACHE_RESTORED-Variable „false“ ist.

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

Wenn während der Buildaufgabe die Fehlermeldung „'project.assets.json' nicht gefunden“ angezeigt wird, können Sie sie beheben, indem Sie die Bedingung condition: ne(variables.CACHE_RESTORED, true) aus der Wiederherstellungsaufgabe entfernen. Dadurch wird der Wiederherstellungsbefehl ausgeführt und die Datei „project.assets.json“ generiert. Die Wiederherstellungsaufgabe lädt keine Pakete herunter, die bereits in Ihrem entsprechenden Ordner vorhanden sind.

Hinweis

Eine Pipeline kann eine oder mehrere Zwischenspeicherungsaufgaben enthalten, und Aufträge und Aufgaben innerhalb derselben Pipeline können auf denselben Cache zugreifen und diesen gemeinsam nutzen.

Leistungsvergleich

Die Pipelinezwischenspeicherung ist eine hervorragende Möglichkeit, die Pipelineausführung zu beschleunigen. Im Folgenden finden Sie einen direkten Leistungsvergleich für zwei verschiedene Pipelines. Vor dem Hinzufügen der Zwischenspeicherungsaufgabe (rechts) dauerte der Wiederherstellungsvorgang ungefähr 41 Sekunden. Wir haben die Zwischenspeicherungsaufgabe zu einer zweiten Pipeline (links) hinzugefügt und die Wiederherstellungsaufgabe so konfiguriert, dass sie ausgeführt wird, wenn ein Cachefehler auftritt. Der Wiederherstellungsvorgang dauerte in diesem Fall 8 Sekunden.

Screenshot der Pipelineleistung mit und ohne Zwischenspeicherung

Nachfolgend finden Sie die vollständige YAML-Pipeline als Referenz:

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)'