Mettre en cache des packages NuGet

Azure DevOps Services

Avec la mise en cache du pipeline, vous pouvez réduire votre temps de génération en mettant en cache vos dépendances à réutiliser dans les exécutions ultérieures. Dans cet article, vous allez apprendre à utiliser la tâche Cache pour mettre en cache et restaurer vos packages NuGet.

Remarque

La mise en cache de pipeline est prise en charge dans des tâches de pool d’agents pour les pipelines YAML et classique. Toutefois, elle n’est pas prise en charge dans les pipelines de mise en production classique.

Verrouiller les dépendances

Pour configurer la tâche de cache, nous devons d’abord verrouiller les dépendances de notre projet et créer un fichier package.lock.json. Le hachage du contenu de ce fichier nous sert à générer une clé unique pour notre cache.

Pour verrouiller les dépendances de votre projet, définissez la propriété RestorePackagesWithLockFile dans votre fichier csproj sur true. La restauration NuGet génère un fichier de verrouillage packages.lock.json dans le répertoire racine de votre projet. Assurez-vous d’archiver votre fichier packages.lock.json dans votre code source.

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

Mettre en cache des packages NuGet

Nous devons créer une variable de pipeline afin de pointer vers l’emplacement de nos packages sur l’agent qui exécute le pipeline.

Dans cet exemple, le contenu du fichier packages.lock.json est haché pour produire une clé de cache dynamique. Cela garantit que chaque fois que le fichier est modifié, une nouvelle clé de cache est générée.

Capture d’écran illustrant comment la clé de cache est générée dans 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'

Remarque

Les caches sont immuables : une fois qu’un cache est créé, son contenu ne peut plus être modifié.

Restaurer le cache

Cette tâche s’exécute uniquement si la variable CACHE_RESTORED est false.

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

Si l’erreur « project.assets.json introuvable » s'affiche pendant votre tâche de génération, vous pouvez la résoudre en supprimant la condition condition: ne(variables.CACHE_RESTORED, true) de votre tâche de restauration. Cela entraîne l'exécution de la commande de restauration, qui génère votre fichier project.assets.json. La tâche de restauration ne télécharge pas les packages déjà présents dans votre dossier correspondant.

Remarque

Un pipeline peut contenir une ou plusieurs tâches de mise en cache, et les travaux et les tâches contenus au sein d'un même pipeline peuvent accéder au même cache et le partager.

Comparaison entre les performances

La mise en cache de pipeline est un excellent moyen d’accélérer l’exécution de votre pipeline. Voici une comparaison des performances de deux pipelines placés côte à côte. Avant d’ajouter la tâche de mise en cache (à droite), la tâche de restauration a pris environ 41 secondes. Nous avons ajouté la tâche de mise en cache à un deuxième pipeline (à gauche) et configuré la tâche de restauration pour s’exécuter lorsqu’un échec d’accès au cache se produit. La tâche de restauration dans ce cas a pris 8 secondes.

Capture d’écran illustrant les performances du pipeline avec et sans mise en cache.

Voici le pipeline YAML complet pour référence :

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