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?
5 Réponses :
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.
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.
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')
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
?
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'
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.
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é
@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:
@Cache
: ne fait rien puisqu'il n'y a pas encore de cache.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
.@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' ...
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 denpm 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.