Partager via


Mise en cache du pipeline

Azure DevOps Services

La mise en cache du pipeline peut aider à réduire le temps de génération en réutilisant les dépendances téléchargées à partir des exécutions précédentes, ce qui évite de devoir recréer ou télécharger à nouveau les mêmes fichiers. Cela est particulièrement utile dans les scénarios où les mêmes dépendances sont téléchargées à plusieurs reprises au début de chaque exécution. Il s’agit souvent d’un processus fastidieux impliquant des centaines ou des milliers d’appels réseau.

La mise en cache est la plus efficace lorsque le temps nécessaire à la restauration et à l’enregistrement du cache est inférieur au temps nécessaire pour régénérer les fichiers. Toutefois, dans certains cas, la mise en cache peut ne pas fournir d’avantages en matière de performances et peut même avoir un impact négatif sur le temps de génération. Il est important d’évaluer votre scénario spécifique pour déterminer si la mise en cache est la bonne approche.

Remarque

La mise en cache des pipelines n’est pas prise en charge pour les pipelines de déploiement classiques.

Quand utiliser des artefacts de pipeline versus la mise en cache de pipeline

La mise en cache de pipeline et la gestion des artefacts de pipeline exécutent des fonctions similaires, mais ces fonctions sont destinées à différents scénarios et ne doivent pas être utilisées interchangeablement.

  • Utilisez des artefacts de pipeline : lorsque vous devez prendre des fichiers spécifiques générés par un travail et les partager avec d’autres travaux (et ces autres travaux échoueront probablement sans eux).

  • Utilisez la mise en cache du pipeline : lorsque vous souhaitez améliorer le temps de génération en réutilisant les fichiers des exécutions précédentes (le fait de ne pas avoir ces fichiers ne compromettra pas la capacité de la tâche à s'exécuter).

Remarque

La mise en cache de pipeline et les artefacts de pipeline sont disponibles gratuitement pour tous les niveaux (gratuits et payants). Pour plus d’informations, consultez la consommation de stockage des artefacts.

Configurations requises pour l'agent auto-hébergé

Les exécutables suivants doivent se trouver dans un dossier répertorié dans la variable d’environnement PATH . Notez que ces exigences s’appliquent uniquement aux agents auto-hébergés, car les agents hébergés sont préinstallés avec le logiciel nécessaire.

Logiciel d’archivage / Plateforme Fenêtres Linux Mac
GNU Tar Obligatoire Obligatoire Non
BSD Tar Non Non Obligatoire
7-Fermeture éclair Recommandé Non Non

Tâche de cache : fonctionnement

La mise en cache est ajoutée à un pipeline en ajoutant la tâche cache à la steps section d’un travail.

Pendant l’exécution du pipeline, lorsqu’une étape de cache est rencontrée, la tâche tente de restaurer le cache en fonction des entrées fournies. Si aucun cache n’est trouvé, l’étape se termine et l’étape suivante du travail est exécutée.

Une fois toutes les étapes du travail exécutées avec succès, une étape spéciale « Post-job : Cache » est automatiquement ajoutée et déclenchée pour chaque étape de « cache de restauration » qui n’a pas été ignorée. Cette étape est chargée d’enregistrer le cache.

Remarque

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

Configurer la tâche cache

La tâche cache comporte deux arguments requis : chemin d’accès et clé :

  1. chemin d’accès : chemin d’accès au dossier que vous souhaitez mettre en cache. Il peut s’agir d’un chemin absolu ou relatif. Les chemins relatifs sont résolus par rapport à $(System.DefaultWorkingDirectory).

    Conseil

    Vous pouvez utiliser des variables prédéfinies pour stocker le chemin d’accès au dossier que vous souhaitez mettre en cache. Toutefois, les caractères génériques ne sont pas pris en charge.

  2. clé : définit l’identificateur du cache que vous souhaitez restaurer ou enregistrer. La clé est composée d’une combinaison de valeurs de chaîne, de chemins d’accès de fichier ou de modèles de fichier, avec chaque segment séparé par un | caractère.

    • Chaînes :
      Valeur fixe (par exemple, le nom du cache ou un nom d’outil) ou extraite d’une variable d’environnement (par exemple, le système d’exploitation actuel ou le nom du travail).

    • Chemins d’accès aux fichiers :
      Chemin d’accès à un fichier spécifique dont le contenu sera haché. Le fichier doit exister au moment de l’exécution de la tâche. Tout segment qui ressemble à un chemin d’accès de fichier est traité comme tel, donc soyez prudent, en particulier lors de l’utilisation de segments contenant ., car cela peut entraîner des échecs de « fichier n’existe pas ».

      Conseil

      Pour éviter qu’un segment de chaîne de type chemin d’accès ne soit traité comme un chemin d’accès de fichier, encapsulez-le avec des guillemets doubles, par exemple : "my.key" | $(Agent.OS) | key.file

    • Modèles de fichiers :
      Liste de motifs génériques de style glob, séparée par des virgules, qui doivent correspondre à au moins un fichier. Exemples:

      • **/yarn.lock: tous les fichiers yarn.lock sous le répertoire sources.
      • */asset.json, !bin/**: tous les fichiersasset.json situés dans un répertoire sous le répertoire sources, à l’exception de ceux du répertoire bin .

Le contenu d’un fichier identifié par un chemin d’accès ou un modèle de fichier est haché pour générer une clé de cache dynamique. Cela est utile lorsque votre projet contient des fichiers qui identifient de manière unique ce qui est mis en cache. Par exemple, les fichiers tels que package-lock.json, yarn.lock, Gemfile.lockou Pipfile.lock sont souvent référencés dans une clé de cache, car ils représentent un ensemble unique de dépendances. Les chemins d’accès relatifs ou les modèles de fichiers sont résolus par rapport à $(System.DefaultWorkingDirectory).

  • Exemple :

L’exemple suivant montre comment mettre en cache les packages Yarn :

variables:
  YARN_CACHE_FOLDER: $(Pipeline.Workspace)/s/.yarn

steps:
- task: Cache@2
  inputs:
    key: '"yarn" | "$(Agent.OS)" | yarn.lock'
    restoreKeys: |
       "yarn" | "$(Agent.OS)"
       "yarn"
    path: $(YARN_CACHE_FOLDER)
  displayName: Cache Yarn packages

- script: yarn --frozen-lockfile

Dans cet exemple, la clé de cache se compose de trois parties : une chaîne statique (« yarn »), le système d’exploitation sur lequel le travail s’exécute (étant donné que le cache est unique par système d’exploitation) et le hachage du yarn.lock fichier (qui identifie de manière unique les dépendances).

Lors de la première exécution après l’ajout de la tâche, l’étape du cache signale une « absence de cache », car le cache identifié par cette clé n’existe pas. Après la dernière étape, un cache sera créé à partir des fichiers de $(Pipeline.Workspace)/s/.yarn et chargé. Lors de la prochaine exécution, l’étape du cache signale un « accès au cache » et le contenu du cache sera téléchargé et restauré.

Lors de l’utilisation de checkout: self, le dépôt est extrait à $(Pipeline.Workspace)/s, et votre dossier .yarn résidera probablement dans le dépôt lui-même.

Remarque

Pipeline.Workspace est le chemin local de l’agent exécutant votre pipeline où tous les répertoires sont créés. Cette variable a la même valeur que Agent.BuildDirectory. Si vous n’utilisez checkout: selfpas, veillez à mettre à jour la YARN_CACHE_FOLDER variable pour qu’elle pointe vers l’emplacement de .yarn votre dépôt.

Utiliser des clés de restauration

restoreKeys vous permet d’interroger plusieurs clés exactes ou préfixes de clé. Il est utilisé comme solution de repli lorsque l’élément spécifié key ne génère pas de résultat. Une clé de restauration recherche une clé par préfixe et retourne l’entrée de cache la plus récente. Cela est utile lorsque le pipeline ne trouve pas une correspondance exacte, mais souhaite toujours utiliser un accès partiel au cache.

Pour spécifier plusieurs clés de restauration, répertoriez-les sur des lignes distinctes. L’ordre dans lequel les clés de restauration sont essayées est de haut en bas.

  • Exemple :

Voici un exemple d’utilisation des clés de restauration pour mettre en cache les packages Yarn :

variables:
  YARN_CACHE_FOLDER: $(Pipeline.Workspace)/.yarn

steps:
- task: Cache@2
  inputs:
    key: '"yarn" | "$(Agent.OS)" | yarn.lock'
    restoreKeys: |
       yarn | "$(Agent.OS)"
       yarn
    path: $(YARN_CACHE_FOLDER)
  displayName: Cache Yarn packages

- script: yarn --frozen-lockfile

Dans cet exemple, la tâche de cache tente d’abord de restaurer la clé spécifiée. Si la clé n’existe pas dans le cache, elle tente la première clé de restauration : yarn | $(Agent.OS). Cela recherche les clés de cache qui correspondent exactement ou commencent par ce préfixe.

Une correspondance de préfixe peut se produire si le hachage du yarn.lock fichier a changé. Par exemple, si le cache contient la clé yarn | $(Agent.OS) | old-yarn.lock (où old-yarn.lock possède un hachage différent de celui actuel yarn.lock), cette clé de restauration entraîne un accès partiel au cache.

Si la première clé de restauration ne donne pas de correspondance, la clé de restauration suivante (yarn) recherche toute clé de cache qui commence par yarn. Pour les correspondances de préfixe, le processus de restauration retourne l’entrée de cache la plus récente créée.

Remarque

Un pipeline peut inclure plusieurs tâches de mise en cache et il n’existe aucune limite de stockage pour la mise en cache. Les travaux et les tâches au sein du même pipeline peuvent accéder au même cache et les partager.

Utiliser la condition de restauration

Dans certains scénarios, vous pouvez exécuter des étapes de manière conditionnelle en fonction de la restauration réussie du cache. Par exemple, vous pouvez ignorer une étape qui installe les dépendances si le cache a été restauré. Cela peut être obtenu à l’aide de l’argument cacheHitVar .

La définition de cette entrée sur le nom d’une variable d’environnement entraîne la définition true de la variable lorsqu’il y a un accès au cache, inexact si une clé de restauration génère un accès partiel au cache et false si aucun cache n’est trouvé. Vous pouvez ensuite référencer cette variable dans une condition d’étape ou dans un script.

Voici un exemple où l’étape install-deps.sh est ignorée lorsque le cache est restauré :

steps:
- task: Cache@2
  inputs:
    key: mykey | mylockfile
    restoreKeys: mykey
    path: $(Pipeline.Workspace)/mycache
    cacheHitVar: CACHE_RESTORED

- script: install-deps.sh
  condition: ne(variables.CACHE_RESTORED, 'true')

- script: build.sh

Isolation et sécurité du cache

Pour garantir l’isolation entre les caches de différents pipelines et différentes branches, chaque cache est stocké dans un conteneur logique appelé scope. Les étendues agissent comme une limite de sécurité qui garantit :

  • Les travaux d’un pipeline ne peuvent pas accéder aux caches d’un autre pipeline.

  • Les tâches de création de demandes de tirage peuvent accéder aux caches de la branche cible (pour le même pipeline), mais ne peuvent pas créer de caches dans la portée de la branche cible.

Lorsqu’une étape de cache est rencontrée lors d’une exécution, le cache identifié par la clé est demandé auprès du serveur. Le serveur recherche ensuite un cache avec cette clé dans les étendues accessibles par la tâche et retourne le cache (si disponible). Pendant l’enregistrement du cache (à la fin du travail), un cache est écrit dans l’étendue représentant le pipeline et la branche.

Exécutions CI, manuelles et planifiées

Portée Lire Écrire
Branche source Oui Oui
branche main Oui Non
branche master Oui Non

Exécutions de demande de tirage

Portée Lire Écrire
Branche source Oui Non
Branche cible Oui Non
Branche intermédiaire (par exemple, refs/pull/1/merge) Oui Oui
branche main Oui Non
branche master Oui Non

Exécutions de duplication de demande de tirage

Branche Lire Écrire
Branche cible Oui Non
Branche intermédiaire (par exemple, refs/pull/1/merge) Oui Oui
branche main Oui Non
branche master Oui Non

Conseil

Étant donné que les caches sont déjà limités à un projet, un pipeline et une branche, il n’est pas nécessaire d’inclure des identificateurs de projet, de pipeline ou de branche dans la clé de cache.

Exemples

Pour les projets Ruby utilisant Bundler, remplacez la BUNDLE_PATH variable d’environnement pour définir le chemin d’accès où Bundler recherche des gemmes.

Exemple :

variables:
  BUNDLE_PATH: $(Pipeline.Workspace)/.bundle

steps:
- task: Cache@2
  displayName: Bundler caching
  inputs:
    key: 'gems | "$(Agent.OS)" | Gemfile.lock'
    path: $(BUNDLE_PATH)
    restoreKeys: | 
      gems | "$(Agent.OS)"
      gems   

Problèmes connus et commentaires

Si vous rencontrez des problèmes lors de la configuration de la mise en cache dans votre pipeline, consultez la liste des problèmes ouverts dans le microsoft/azure-pipelines-tasks référentiel. Si vous ne voyez pas votre problème répertorié, créez-en un et fournissez les informations nécessaires sur votre scénario.

Q&R

Q : Puis-je effacer un cache ?

R : L’effacement d’un cache n’est pas pris en charge. Toutefois, vous pouvez éviter les accès sur les caches existants en ajoutant une chaîne littérale (par exemple version2) à votre clé de cache. Par exemple, modifiez la clé de cache suivante à partir de ceci :

key: 'yarn | "$(Agent.OS)" | yarn.lock'

À cet effet :

key: 'version2 | yarn | "$(Agent.OS)" | yarn.lock'

Q : Quand un cache expire-t-il ?

R : Les caches expirent après sept jours d’absence d’activité.

Q : Quand le cache est-il chargé ?

R : Un cache est créé à partir de votre spécification path et téléchargé après la dernière étape du travail. Pour plus d’informations, consultez l’exemple .

Q : Existe-t-il une limite sur la taille d’un cache ?

R : Il n’existe aucune limite appliquée à la taille des caches individuels ou à la taille totale du cache au sein d’une organisation.