我正在将Azure Pipelines与托管版本一起使用来构建Web项目。我们的构建时间达到了10-15分钟,其中大部分时间(5-10分钟)花在了npm install
上。为了加快速度,我尝试使用Cache
任务(https://docs.microsoft.com/en-us/azure/devops/pipelines/caching/?view=azure-devops)。
但是,运行自动添加的任务Post-job: Cache
时,它总是会出现以下错误:
##[error]The system cannot find the file specified
主机服务器是Windows Server 2017。
这是我的整个构建YAML
# 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'
缓存任务输出:
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
职位:缓存输出:
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
如何修复我的构建定义以便缓存起作用?
答案 0 :(得分:1)
昨天,我可以使用以下方法使它在自托管的计算机代理上完全没有问题:
- 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'
今天,今天尝试在托管代理上工作,这丝毫不减。 Aggh,回到磨板。无论如何,也许可以在自托管管道上为您工作
答案 1 :(得分:1)
@Levi Lu-MSFT就在他的comment中,但有一个陷阱。
@FLabranche在他的answer中有一个可行的解决方案,但我认为推理并不正确。
问题
npm install
和@Cache
任务正在不同位置寻找npm缓存。考虑管道首次运行时的流程:
@Cache
任务:因为还没有缓存,所以不执行任何操作。npm i
(或npm ci
)任务:在node_modules/
中安装软件包并在默认位置更新npm缓存。在Linux / Mac上,默认位置为~/.npm
,在Windows上,默认位置为%AppData%/npm-cache
。在Linux托管的云代理上,绝对路径为/home/vsts/.npm
。@Cache
任务(隐式添加):读取在用户提供的位置上找到的npm缓存,以将其存储以备将来使用。用户提供的位置由npm_config_cache: $(Pipeline.Workspace)/.npm
变量设置。在Linux托管的云代理上,绝对路径为/home/vsts/work/1/.npm
。结果,@Cache
任务失败,并显示tar: /home/vsts/work/1/.npm: Cannot open: No such file or directory
。
解决方案
使npm install
和@Cache
任务使用相同的npm缓存位置。
Levi Lu建议的一个选项是用npm config set cache $(npm_config_cache) --global
更新npm配置,但是它不能在管道中工作(至少对我在Azure托管的Linux代理中不起作用):{ {1}}
Error: EACCES: permission denied, open '/usr/local/etc/npmrc'
更新单个呼叫的npm缓存位置,在这种情况下它确实起作用。不过,由于npm ci --cache $(npm_config_cache)
选项甚至在npm网站上都没有记录,因此感觉有点骇人听闻。
所有这些代码都对我有用:
--cache
答案 2 :(得分:0)
您可以登录Windows Server 2017服务器并检查是否已创建文件夹$(Pipeline.Workspace)/。npm并将依赖项存储在其中。
我复制并测试了您的Yaml。它适用于本地代理(win2019)和云代理。您可以尝试在具有较新系统的云代理或其他代理上运行管道,以检查是否是导致此错误的代理。
答案 3 :(得分:0)
在两个任务之间,使用package-lock.json生成的密钥有所不同。 修改文件时会发生这种情况。在这里,它们被您的npm安装任务修改了。
在将“缓存”任务配置为回退到最新的缓存条目时,可以使用restoreKeys选项。 而且我认为您不需要执行'npm install'任务。
您可以尝试替换它吗?
- 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: 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
答案 4 :(得分:0)