jkl*_*ack 6 npm azure-devops azure-pipelines-build-task azure-pipelines
我正在使用带有托管构建的 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
Run Code Online (Sandbox Code Playgroud)
主机服务器是 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'
Run Code Online (Sandbox Code Playgroud)
缓存任务输出:
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
Run Code Online (Sandbox Code Playgroud)
作业后:缓存输出:
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
Run Code Online (Sandbox Code Playgroud)
如何修复我的构建定义以便缓存工作?
@Levi Lu-MSFT 的评论是正确的,但有一个问题。
@FLabranche 在他的回答中有一个可行的解决方案,但我认为推理不太正确。
问题
npm install和@Cache任务正在不同位置寻找 npm 缓存。考虑管道第一次运行时的流程:
@Cache任务:不执行任何操作,因为还没有缓存。npm i(或)任务:在默认位置npm ci安装软件包node_modules/并更新 npm 缓存。默认位置在 Linux/Mac 和Windows 上。在 Linux 托管的云代理上,绝对路径为.~/.npm%AppData%/npm-cache/home/vsts/.npm@Cache找到的 npm 缓存以存储它以供将来重用。用户提供的位置由变量设置。在 Linux 托管的云代理上,绝对路径为.npm_config_cache: $(Pipeline.Workspace)/.npm/home/vsts/work/1/.npm结果,@Cache任务失败并显示tar: /home/vsts/work/1/.npm: Cannot open: No such file or directory。
解决方案
Makenpm install和@Cache任务使用相同的 npm 缓存位置。
Levi Lu 建议的一种选择是更新 npm 配置npm config set cache $(npm_config_cache) --global,但它在管道中不起作用(至少在 Azure 托管的 Linux 代理中对我不起作用):Error: EACCES: permission denied, open '/usr/local/etc/npmrc'
npm ci --cache $(npm_config_cache)更新单个调用的 npm 缓存位置,在这种情况下它确实有效。但感觉有点 hacky,因为--cachenpm 网站上甚至没有记录该选项。
总而言之,这段代码对我有用:
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'
...
Run Code Online (Sandbox Code Playgroud)
您可以登录Windows Server 2017服务器并检查文件夹$(Pipeline.Workspace)/.npm是否已创建以及依赖项是否存储在其中。
我复制并测试了你的 yaml。它适用于本地代理(win2019)和云代理。您可以尝试在云代理或其他具有较新系统的代理上运行管道,以检查是否是导致此错误的代理。