4
votes

Azure Pipelines «Cache @ 2» échoue avec «## [erreur] Le système ne trouve pas le fichier spécifié»

J'utilise Azure Pipelines avec des versions hébergées pour créer un projet Web. Nos temps de construction atteignaient 10 à 15 minutes, la plupart (5 à 10 minutes) du temps passé à npm install . Pour accélérer cela, j'essaie d'utiliser la tâche Cache ( https://docs.microsoft.com/en-us/azure/devops/pipelines/caching/?view=azure-devops ).

Cependant, lorsque la tâche ajoutée automatiquement Post-job: Cache s'exécute, elle génère toujours des erreurs avec:

Starting: Cache
==============================================================================
Task         : Cache
Description  : Cache files between runs
Version      : 2.0.0
Author       : Microsoft Corporation
Help         : https://aka.ms/pipeline-caching-docs
==============================================================================
Resolving key:
 - npm               [string]
 - "Windows_NT"      [string]
 - package-lock.json [file] --> 2F208E865E6510DE6EEAA6DB0CB7F87B323386881F42EB63E18ED1C0D88CA84E
Resolved to: npm|"Windows_NT"|OQo0ApWAY09wL/ZLr6fxlRIZ5qcoTrNLUv1k6i6GO9Q=
Information, ApplicationInsightsTelemetrySender will correlate events with X-TFS-Session zzzzz
Information, Getting a pipeline cache artifact with one of the following fingerprints:
Information, Fingerprint: `npm|"Windows_NT"|OQo0ApWAY09wL/ZLr6fxlRIZ5qcoTrNLUv1k6i6GO9Q=`
Information, There is a cache miss.
Information, ApplicationInsightsTelemetrySender correlated 1 events with X-TFS-Session zzzzz
##[error]The system cannot find the file specified
Finishing: Cache

Le serveur hôte est Windows Server 2017.

Voici ma version complète de YAML

Starting: Cache
==============================================================================
Task         : Cache
Description  : Cache files between runs
Version      : 2.0.0
Author       : Microsoft Corporation
Help         : https://aka.ms/pipeline-caching-docs
==============================================================================
Resolving key:
 - npm               [string]
 - "Windows_NT"      [string]
 - package-lock.json [file] --> F93EFA0B87737CC825F422E1116A9E72DFB5A26F609ADA41CC7F80A039B17299
Resolved to: npm|"Windows_NT"|rbCoKv9PzjbAOWAsH9Pgr3Il2ZhErdZTzV08Qdl3Mz8=
Information, ApplicationInsightsTelemetrySender will correlate events with X-TFS-Session zzzzz
Information, Getting a pipeline cache artifact with one of the following fingerprints:
Information, Fingerprint: `npm|"Windows_NT"|rbCoKv9PzjbAOWAsH9Pgr3Il2ZhErdZTzV08Qdl3Mz8=`
Information, There is a cache miss.
Information, ApplicationInsightsTelemetrySender correlated 1 events with X-TFS-Session zzzzz
Finishing: Cache

Sortie de la tâche de cache:

# Node.js with Vue
# Build a Node.js project that uses Vue.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript

trigger:
- develop

pool:
  name: Default

variables:
  FONTAWESOME_NPM_AUTH_TOKEN: $(FONTAWESOME_NPM_AUTH_TOKEN_VARIABLE)
  npm_config_cache: $(Pipeline.Workspace)/.npm


steps:
- task: DutchWorkzToolsAllVariables@1

- task: NodeTool@0
  inputs:
    versionSpec: '10.x'
  displayName: 'Install Node.js'


- task: Cache@2
  inputs:
    key: 'npm | "$(Agent.OS)" | package-lock.json'
    path: $(npm_config_cache)
    cacheHitVar: NPM_CACHE_RESTORED

- task: Npm@1
  displayName: 'npm install'
  inputs:
    command: 'install'
  condition: ne(variables.NPM_CACHE_RESTORED, 'true')


- task: Npm@1
  displayName: 'npm run build'
  inputs:
    command: 'custom'
    customCommand: 'run build'

- task: CopyFiles@2
  inputs:
    SourceFolder: '$(Build.Repository.LocalPath)\dist'
    Contents: '**'
    TargetFolder: '$(Build.StagingDirectory)'
    CleanTargetFolder: true

- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'    

Post-job: sortie du cache:

##[error]The system cannot find the file specified

Comment puis-je corriger ma définition de build pour que la mise en cache fonctionne?


3 commentaires

Je pense que le problème est celui de la poule et de l'œuf. Fondamentalement, la clé de cache est basée sur le hachage du fichier packages-lock.json , mais le contenu de ce fichier peut changer lors de l' npm install suivante de npm install . Lorsque la tâche de post-génération s'exécute, elle recalcule la clé (?) Et ne parvient pas à trouver le «nouveau» dossier de cache.


Salut @jklemmack Avez-vous essayé la solution fournie par Florian. Cela semble être la bonne réponse.


Au premier abord, la solution de @ Florian-Labranche ne semblait pas fonctionner. J'ai été attiré par d'autres choses pendant un certain temps, mais j'y reviendrai dans quelques semaines. En fin de compte, le pipeline fonctionne (sans la tâche Cache @ 2) ... très lentement.


5 Réponses :


0
votes

Vous pouvez vous connecter à votre serveur Windows Server 2017 et vérifier si le dossier $ (Pipeline.Workspace) /. Npm est créé et les dépendances y sont stockées.

J'ai copié et testé votre yaml. Cela fonctionnait à la fois sur l'agent local (win2019) et les agents cloud. Vous pouvez essayer d'exécuter votre pipeline sur les agents cloud ou d'autres agents avec un système plus récent pour vérifier si c'est l'agent qui cause cette erreur.


2 commentaires

J'ai en fait un répertoire à l'endroit approprié: c:\agent2\_work\40\.npm et il semble rempli de trucs de cache. Alors, pourquoi la tâche générée automatiquement signale-t-elle une erreur, et donc une erreur de construction?


Pourriez-vous essayer d'ajouter une tâche npm supplémentaire avant l'installation de npm pour exécuter npm config set cache $(npm_config_cache) --global pour remplacer la variable d'environnement npm_config_cache sur le chemin $(Pipeline.Workspace)/.npm . Ou exécutez npm install --cache $(npm_config_cache) pour votre tâche d'installation npm.



0
votes

Les clés générées avec votre package-lock.json diffèrent entre les deux tâches. Cela se produit lorsque le fichier est modifié. Ici, ils sont modifiés par votre tâche d'installation npm.

Vous pouvez utiliser l'option restoreKeys lors de la configuration de la tâche Cache pour revenir à la dernière entrée de cache. Et je pense que vous n'avez pas besoin de la tâche «npm install».

Pourriez-vous essayer de remplacer ceci:

- task: Cache@2
  inputs:
    key: 'npm | "$(Agent.OS)" | package-lock.json'
    restoreKeys: |
       npm | "$(Agent.OS)"
       npm
    path: $(npm_config_cache)
  displayName: Cache npm

- script: npm ci --cache $(npm_config_cache)

Par cette définition:

- task: Cache@2
  inputs:
    key: 'npm | "$(Agent.OS)" | package-lock.json'
    path: $(npm_config_cache)
    cacheHitVar: NPM_CACHE_RESTORED

- task: Npm@1
  displayName: 'npm install'
  inputs:
    command: 'install'
  condition: ne(variables.NPM_CACHE_RESTORED, 'true')


1 commentaires

Je ne peux pas commenter le fil de discussion principal, mais pourriez-vous essayer de mélanger Levi Lu et ma solution en utilisant npm ci --cache $(npm_config_cache) au lieu de npm ci ?



0
votes

Cela semble être lié à ce problème en suspens .

J'ai résolu le problème en basculant le pool d'agents de construction sur hébergé et en utilisant la dernière image de Windows .

pool:
  vmImage: 'windows-latest'


2 commentaires

Inacceptable dans mon cas, car j'ai besoin de faire des builds hébergés. La recherche de tar pourrait cependant être une solution intéressante.


@jklemmack - Avez-vous fait fonctionner le tar? J'essaye d'obtenir le goudron sur le serveur de construction mais je ne peux pas.



1
votes

Hier, j'ai pu le faire fonctionner sans aucun problème sur un agent de machine auto-hébergé en utilisant ceci:

- task: Cache@2
  inputs:
    key: '**/package-lock.json, !**/node_modules/**/package-lock.json, !**/.*/**/package-lock.json'
    path: '$(System.DefaultWorkingDirectory)/node_modules'
  displayName: 'Cache Node Modules'

Aujourd'hui, essayer de travailler sur un agent hébergé aujourd'hui et cela ne coupe pas du tout. Aggh, retour à la planche de meulage. Quoi qu'il en soit, cela pourrait peut-être fonctionner pour vous sur votre pipeline auto-hébergé


0 commentaires

1
votes

@Levi Lu-MSFT avait raison dans son commentaire mais il y a un piège.

@FLabranche a une solution de travail dans sa réponse mais je pense que le raisonnement n'est pas tout à fait correct.

Le problème

npm install et la tâche @Cache recherchent le cache npm à différents emplacements. Considérez le flux lorsque le pipeline s'exécute pour la première fois:

  1. @Cache : ne fait rien puisqu'il n'y a pas encore de cache.
  2. npm i (ou npm ci ): installe les packages dans node_modules/ et met à jour le cache npm à l' emplacement par défaut . L'emplacement par défaut est ~/.npm sous Linux / Mac et %AppData%/npm-cache sous Windows. Sur l'agent cloud hébergé par Linux, le chemin absolu sera /home/vsts/.npm .
  3. (... plus de tâches de votre pipeline)
  4. @Cache post-job @Cache (ajoutée implicitement): lit le cache npm trouvé à l'emplacement fourni par l' utilisateur pour le stocker pour une réutilisation future. L'emplacement fourni par l'utilisateur est défini par la npm_config_cache: $(Pipeline.Workspace)/.npm . Sur l'agent cloud hébergé par Linux, le chemin absolu sera /home/vsts/work/1/.npm .

En conséquence, la tâche @Cache échoue avec tar: /home/vsts/work/1/.npm: Cannot open: No such file or directory .

Solution

Faites en @Cache npm install et la tâche @Cache utilisent le même emplacement de cache npm.

Une option suggérée par Levi Lu est de mettre à jour la configuration npm avec npm config set cache $(npm_config_cache) --global mais cela ne fonctionnera pas dans le pipeline (au moins cela n'a pas fonctionné pour moi dans un agent Linux hébergé par Azure ): Error: EACCES: permission denied, open '/usr/local/etc/npmrc'

npm ci --cache $(npm_config_cache) met à jour l'emplacement du cache npm pour un seul appel et cela fonctionne dans ce cas. Cela semble un peu --cache car l'option --cache n'est même pas documentée sur le site Web de npm.

Dans l'ensemble, ce code a fonctionné pour moi:

variables:
  NPM_CACHE_FOLDER: $(Pipeline.Workspace)/.npm

steps:
- task: Cache@2
  displayName: Cache npm dependencies
  inputs:
    key: 'npm | "$(Agent.OS)" | package-lock.json'
    restoreKeys: |
      npm | "$(Agent.OS)"
      npm
    path: $(NPM_CACHE_FOLDER)

- script: npm ci --cache $(NPM_CACHE_FOLDER)
  displayName: 'Install npm dependencies'

...


0 commentaires