GitHub Actions工作流中npm缓存未生效问题求助
我希望通过本地缓存npm模块来加速npm install,避免每次重新下载。编写了一个极简的GitHub Actions工作流,仅包含package.json和工作流YAML文件,采用单独的缓存保存与恢复步骤(未使用setup-node的缓存功能)。
package.json内容
{ "name": "workflow-npm-dependency-cache", "version": "0.0.1", "description": "Minimal example of a workflow npm cache", "scripts": { "build": "echo Building...", "test": "echo Testing...", "deploy": "echo Deploying..." }, "dependencies": { "debug": "^4.2.0", "ejs": "^3.1.6", "marked": "^4.2.4", "highlight.js": "^11.7.0" }, "devDependencies": { "chai": "^4.3.6", "chance": "^1.1.8", "cheerio": "^1.0.0-rc.12", "mocha": "^10.0.0", "sinon": "^14.0.0" } }
工作流文件(.github/workflows/buildAndDeploy.yml)
name: Build on: push: branches: - main - fix-* - feature-* workflow_dispatch: env: nodejs_version: ${{ github.event.inputs.nodejs_version || '20.4.0' }} repo_dir: repo cache_name: npm-modules-cache jobs: build: name: Build runs-on: ubuntu-latest steps: - name: Clone Deploy Repository (Latest) uses: actions/checkout@v3 with: path: ${{ env.repo_dir }} - name: Setup NodeJS uses: actions/setup-node@v3 with: node-version: ${{ env.nodejs_version }} - name: List node modules (1) continue-on-error: true run: cd $repo_dir && npm list - name: Restore npm module cache uses: actions/cache/restore@v3 id: cache-npm-restore with: path: ~/.npm key: ${{ runner.os }}-build-${{ env.cache_name }} - name: List node modules (2) if: ${{ steps.cache-npm-restore.outputs.cache-hit == 'true' }} continue-on-error: true run: cd $repo_dir && npm list - name: Install NodeJS modules run: | cd $repo_dir && npm install - name: Save npm module cache if: ${{ steps.cache-npm-restore.outputs.cache-hit != 'true' }} uses: actions/cache/save@v3 id: cache-npm-save with: path: ~/.npm key: ${{ runner.os }}-build-${{ env.cache_name }} - name: List node modules (3) if: ${{ steps.cache-npm-restore.outputs.cache-hit != 'true' }} continue-on-error: true run: cd $repo_dir && npm list - name: Build run: | cd $repo_dir && npm run build - name: Test run: | cd $repo_dir && npm run test deploy: name: Deploy runs-on: ubuntu-latest needs: build steps: - name: Clone Deploy Repository (Latest) uses: actions/checkout@v3 with: path: ${{ env.repo_dir }} - name: List node modules (4) continue-on-error: true run: cd $repo_dir && npm list - name: Restore npm module cache uses: actions/cache/restore@v3 with: path: ~/.npm key: ${{ runner.os }}-build-${{ env.cache_name }} - name: List node modules (5) continue-on-error: true run: cd $repo_dir && npm list - name: Install NodeJS modules run: | cd $repo_dir && npm install - name: Build run: | cd $repo_dir && npm run deploy
运行结果异常情况
build任务成功生成缓存,deploy任务也显示缓存恢复成功,但deploy任务的“List node modules (5)”步骤显示所有模块未存在:
Run cd $repo_dir && npm list npm ERR! code ELSPROBLEMS npm ERR! missing: chai@^4.3.6, required by workflow-npm-dependency-cache@0.0.1 npm ERR! missing: chance@^1.1.8, required by workflow-npm-dependency-cache@0.0.1 npm ERR! missing: cheerio@^1.0.0-rc.12, required by workflow-npm-dependency-cache@0.0.1 npm ERR! missing: debug@^4.2.0, required by workflow-npm-dependency-cache@0.0.1 npm ERR! missing: ejs@^3.1.6, required by workflow-npm-dependency-cache@0.0.1 npm ERR! missing: highlight.js@^11.7.0, required by workflow-npm-dependency-cache@0.0.1 npm ERR! missing: marked@^4.2.4, required by workflow-npm-dependency-cache@0.0.1 npm ERR! missing: mocha@^10.0.0, required by workflow-npm-dependency-cache@0.0.1 npm ERR! missing: sinon@^14.0.0, required by workflow-npm-dependency-cache@0.0.1 workflow-npm-dependency-cache@0.0.1 /home/runner/work/workflow-npm-dependency-cache/workflow-npm-dependency-cache/repo ├── UNMET DEPENDENCY chai@^4.3.6 ├── UNMET DEPENDENCY chance@^1.1.8 ├── UNMET DEPENDENCY cheerio@^1.0.0-rc.12 ├── UNMET DEPENDENCY debug@^4.2.0 ├── UNMET DEPENDENCY ejs@^3.1.6 ├── UNMET DEPENDENCY highlight.js@^11.7.0 ├── UNMET DEPENDENCY marked@^4.2.4 ├── UNMET DEPENDENCY mocha@^10.0.0 └── UNMET DEPENDENCY sinon@^14.0.0
deploy任务的缓存恢复步骤显示成功,但缓存大小仅195B:
Run actions/cache/restore@v3 Received 195 of 195 (100.0%), 0.0 MBs/sec Cache Size: ~0 MB (195 B) /usr/bin/tar -xf /home/runner/work/_temp/b7061dc5-d9d8-46a8-84c4-8ac40b635d39/cache.tzst -P -C /home/runner/work/workflow-npm-dependency-cache/workflow-npm-dependency-cache --use-compress-program unzstd Cache restored successfully Cache restored from key: Linux-build-npm-modules-cache
1. 步骤顺序误解:npm list在install之前执行
deploy任务中“List node modules (5)”步骤是在npm install之前运行的,此时项目的node_modules目录还未生成,因此显示依赖未安装是正常现象,不代表缓存未生效。要验证缓存是否起作用,需要查看npm install步骤的日志,若出现using cached等字样,说明缓存已被使用。
2. 缓存内容为空:缓存路径错误或未捕获实际缓存
缓存大小仅195B,说明build任务保存的~/.npm目录几乎没有实际的包缓存。npm的实际缓存目录通常是~/.npm/_cacache(不同版本可能略有差异),而非整个~/.npm目录。
解决方法:
- 在build任务中添加步骤确认npm缓存路径:
- name: Check npm cache path run: npm config get cache - 将build和deploy任务中缓存的
path参数改为上述命令输出的路径(例如~/.npm/_cacache)。
3. Deploy任务未配置Node.js环境,版本不兼容
build任务使用setup-node指定了Node.js版本20.4.0,但deploy任务未执行该步骤,默认使用runner自带的Node.js/npm版本,版本差异可能导致缓存格式不兼容,无法识别已缓存的内容。
解决方法:
在deploy任务的checkout步骤后添加setup-node步骤:
- name: Setup NodeJS uses: actions/setup-node@v3 with: node-version: ${{ env.nodejs_version }}
4. 缓存键无依赖哈希,无法更新缓存
当前缓存键仅包含系统和缓存名称,当package.json中的依赖变化时,仍会使用旧缓存,导致依赖不匹配。
解决方法:
修改缓存键为包含package-lock.json的哈希值,确保依赖变化时生成新缓存:
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} # 添加fallback键,匹配同系统下的任意npm缓存 restore-keys: | ${{ runner.os }}-npm-
5. 推荐使用setup-node内置缓存(更可靠)
官方setup-node动作内置了npm缓存功能,无需手动管理缓存步骤,会自动处理缓存路径和键的生成,减少出错概率:
- name: Setup NodeJS uses: actions/setup-node@v3 with: node-version: ${{ env.nodejs_version }} cache: 'npm'
内容的提问来源于stack exchange,提问作者vy218

