Partager via


Mettre en cache des packages NuGet

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022

La mise en cache du pipeline permet de réduire le temps de génération en stockant les dépendances pour la réutilisation 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 n'est pas prise en charge dans les pipelines de mise en production classiques.

Conditions préalables

Produit Exigences
Azure DevOps - Un projet Azure DevOps .
- Autorisations :
    - Pour accorder l'accès à tous les pipelines du projet, vous devez être membre du groupe Administrateurs du projet.

Verrouiller les dépendances

Avant de configurer la tâche de cache, vous devez verrouiller les dépendances de votre projet et générer un fichier package.lock.json. La clé de cache unique est dérivée du hachage du contenu de ce fichier de verrou pour garantir la cohérence entre les builds.

Pour verrouiller les dépendances de votre projet, ajoutez la propriété RestorePackagesWithLockFile à votre fichier csproj et définissez-la sur true. Lorsque vous exécutez nuget restore, il génère un fichier packages.lock.json dans le répertoire racine de votre projet. Assurez-vous d’intégrer votre fichier packages.lock.json dans votre code source.

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

Mettre en cache des packages NuGet

Pour mettre en cache les packages NuGet, définissez une variable de pipeline qui pointe vers l’emplacement des packages sur l’agent exécutant le pipeline.

Dans l’exemple ci-dessous, le contenu du packages.lock.json est haché pour générer une clé de cache dynamique. Cela garantit que chaque fois que le fichier change, une nouvelle clé de cache est créée.

Capture d’écran montrant 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 v2 task 
  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

La tâche suivante s’exécute uniquement si la variable CACHE_RESTORED est false. Cela signifie que si un accès au cache se produit (les packages sont déjà disponibles dans le cache), l’étape de restauration est ignorée pour gagner du temps et des ressources. Si aucun cache n’est trouvé, la commande de restauration s’exécute pour télécharger les dépendances nécessaires.

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

Remarque

Si vous utilisez Ubuntu 24.04 ou version ultérieure, vous devez utiliser la tâche NuGetAuthenticate avec l’interface CLI .NET au lieu de la tâche NuGetCommand@2. Consultez la rubrique Prise en charge des nouvelles images hébergées Ubuntu pour plus de détails.

Gérer les erreurs «project.assets.json introuvable »

Si vous rencontrez l’erreur «project.assets.json introuvable » pendant votre tâche de génération, supprimez la condition condition: ne(variables.CACHE_RESTORED, true) de votre tâche de restauration. Cela garantit que la commande de restauration s’exécute et génère le fichier project.assets.json. La tâche de restauration ne rechargera pas les packages qui sont déjà présents dans le dossier correspondant.

Remarque

Un pipeline peut inclure plusieurs tâches de mise en cache, et les emplois et les tâches au sein du même pipeline peuvent accéder et partager le même cache.

Comparaison entre les performances

La mise en cache du pipeline réduit considérablement le temps nécessaire à la restauration des dépendances, ce qui entraîne des builds plus rapides. La comparaison suivante illustre l’impact de la mise en cache sur le temps d’exécution du pipeline pour deux pipelines différents :

  • sans mise en cache (à droite): la tâche de restauration a pris environ 41 secondes.

  • Avec la mise en cache (à gauche): nous avons ajouté la tâche de mise en cache à un deuxième pipeline et configuré la tâche de restauration pour s’exécuter uniquement lorsqu’une absence de cache se produit. La tâche de restauration dans ce cas s’est terminée en seulement 8 secondes.

Capture d’écran montrant 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)'

Cette approche s’applique également aux projets .NET Core, à condition que votre projet utilise packages.lock.json pour verrouiller les versions du package. Vous pouvez l’activer en définissant RestorePackagesWithLockFile sur True dans votre fichier * Csproj*, ou en exécutant la commande suivante : dotnet restore --use-lock-file.