mirror of
https://git.bjxgj.com/xgj/xgj-actions.git
synced 2025-10-14 06:33:37 +08:00
11 KiB
11 KiB
npm 依赖安装与缓存 Action
这个 GitHub Action 自动处理 npm 依赖的缓存和安装,支持多种包管理器(npm、pnpm、yarn),可以大幅提升 CI/CD 流水线的执行速度。
✨ 特性
- 🚀 智能缓存: 自动缓存 node_modules,避免重复安装
- 📦 多包管理器支持: 支持 npm、pnpm、yarn,自动检测标准锁文件
- 🎯 灵活配置: 可自定义缓存前缀、安装命令等
- 🔑 精确 hash 控制: 支持自定义缓存 hash,确保依赖变化时缓存失效
- 🔄 Git 集成: 可选的 git stash 功能
- 📊 详细输出: 提供缓存命中状态和使用的缓存 key
- 🧰 自动安装 pnpm: 当选择
package-manager: pnpm
时,自动通过pnpm/action-setup@v4
确保 pnpm 可用(可指定版本) - 🗜️ 缓存 pnpm 二进制: 在安装前缓存 Corepack 的 pnpm 二进制目录,避免重复下载 pnpm 本体(对封闭/慢网环境更友好)
📋 输入参数
参数名 | 描述 | 是否必需 | 默认值 |
---|---|---|---|
package-manager |
包管理器类型 (npm/pnpm/yarn) | 否 | npm |
pnpm-version |
pnpm 版本(package-manager: pnpm 时生效) |
否 | 9 |
cache-mode |
缓存模式(node_modules 或 store ) |
否 | node_modules |
cache-prefix |
缓存前缀名称 | 否 | modules |
node-modules-path |
node_modules 目录路径 | 否 | node_modules |
force-install |
是否强制安装 | 否 | false |
enable-git-stash |
安装后是否执行 git stash | 否 | false |
install-command |
自定义安装命令(覆盖默认) | 否 | '' |
install-args |
附加到默认安装命令的参数(当未提供 install-command 时生效) |
否 | '' |
cache-hash |
缓存 hash 值(推荐使用) | 否 | 自动计算 |
📤 输出参数
参数名 | 描述 |
---|---|
cache-hit |
是否命中缓存 (true/false) |
cache-key |
使用的缓存 key |
cache-path |
缓存路径(用于调试与复用) |
💡 重要提示
强烈推荐使用 cache-hash
参数!
使用 cache-hash
参数有以下优势:
- ✅ 精确控制: 让你完全控制缓存失效的条件
- ✅ 环境兼容: 避免在不同容器环境中 hash 计算不一致的问题
- ✅ 灵活组合: 可以组合多个文件的 hash(如
package.json
+package-lock.json
+.nvmrc
) - ✅ 调试友好: 在 workflow 中可以清楚看到使用的 hash 值
# 推荐用法
with:
cache-hash: ${{ hashFiles('package-lock.json') }}
如果不提供 cache-hash
,action 会自动使用 package.json
作为 fallback,但不如手动指定精确。
🚀 使用方法
基础用法 (npm)
- name: 安装npm依赖
uses: actions/xgj/npm-install@v1
使用 pnpm
- name: 安装pnpm依赖
uses: actions/xgj/npm-install@v1
with:
package-manager: "pnpm"
# 可选:指定 pnpm 版本(默认 9)
pnpm-version: "9"
# 可选:切换为包管理器 store 缓存,提升复用率(首次仍需安装链接)
# cache-mode: "store"
# 可选:附加安装参数(当未设置 install-command 时生效)
# 例如:保持锁文件严格、忽略可选依赖
install-args: "--frozen-lockfile --no-optional"
强制安装 + Git Stash
- name: 强制安装依赖并stash
uses: actions/xgj/npm-install@v1
with:
package-manager: "npm"
force-install: "true"
enable-git-stash: "true"
自定义缓存配置
- name: 自定义缓存安装
uses: actions/xgj/npm-install@v1
with:
package-manager: "yarn"
cache-prefix: "my-project"
node-modules-path: "./frontend/node_modules"
自定义安装命令
- name: 使用自定义命令安装
uses: actions/xgj/npm-install@v1
with:
install-command: "npm ci --only=production"
仅附加参数(不覆盖命令)
# npm 示例:追加只生产依赖
- name: 安装(npm,仅生产依赖)
uses: actions/xgj/npm-install@v1
with:
package-manager: npm
install-args: "--only=production"
# pnpm 示例:严格锁文件 + 忽略可选依赖
- name: 安装(pnpm,严格锁文件)
uses: actions/xgj/npm-install@v1
with:
package-manager: pnpm
install-args: "--frozen-lockfile --no-optional"
# yarn 示例:纯安装(禁用脚本)
- name: 安装(yarn,禁用脚本)
uses: actions/xgj/npm-install@v1
with:
package-manager: yarn
install-args: "--ignore-scripts"
使用自定义缓存 hash(推荐用法)
# 推荐:手动指定缓存hash,确保精确的缓存管理
- name: 安装npm依赖
uses: actions/xgj/npm-install@v1
with:
package-manager: "npm"
cache-hash: ${{ hashFiles('package-lock.json') }}
# pnpm项目
- name: 安装pnpm依赖
uses: actions/xgj/npm-install@v1
with:
package-manager: "pnpm"
cache-hash: ${{ hashFiles('pnpm-lock.yaml') }}
# 多文件hash组合
- name: 安装依赖(多文件hash)
uses: actions/xgj/npm-install@v1
with:
package-manager: "npm"
cache-hash: ${{ hashFiles('package.json', 'package-lock.json', '.nvmrc') }}
检查缓存状态
- name: 安装依赖
id: install-deps
uses: actions/xgj/npm-install@v1
with:
package-manager: "pnpm"
- name: 根据缓存状态执行操作
if: steps.install-deps.outputs.cache-hit != 'true'
run: |
echo "依赖已重新安装,执行额外步骤"
npm run build:fresh
📝 完整工作流示例
name: CI Pipeline
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 设置Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
- name: 安装依赖
id: deps
uses: actions/xgj/npm-install@v1
with:
package-manager: "pnpm"
force-install: "false"
- name: 运行测试
run: pnpm test
- name: 构建项目
if: steps.deps.outputs.cache-hit != 'true'
run: pnpm build
🔧 工作原理
- 缓存 Key 生成: 根据包管理器类型和 lock 文件生成唯一的缓存 key
- 缓存检查: 使用
actions/cache@v4
检查是否存在匹配的缓存 - 自动安装 pnpm(如需): 当
package-manager=pnpm
时,使用pnpm/action-setup@v4
确保 pnpm 已安装- 在此之前,本 Action 会使用
actions/cache@v4
缓存 Corepack 的 pnpm 二进制目录,命中后无需再次从外网拉取 pnpm 本体
- 在此之前,本 Action 会使用
- 缓存路径确定:
- 当
cache-mode=node_modules
时,缓存node_modules
(可用node-modules-path
定义目录)。 - 当
cache-mode=store
时,缓存包管理器的全局存储:npm
→~/.npm
,pnpm
→ 通过pnpm store path
动态获取,yarn
→~/.cache/yarn
。
- 当
- 条件安装: 仅在缓存未命中时执行依赖安装
- 可选操作: 根据配置执行 git stash 等额外操作
说明:缓存 key 中包含 OS、包管理器(以及 pnpm 的版本)、缓存模式与自定义前缀,避免跨包管理器/模式的缓存误用。
🎯 最佳实践
1. 选择合适的包管理器
# 推荐:根据项目实际使用的包管理器
- uses: actions/xgj/npm-install@v1
with:
package-manager: "pnpm" # 如果项目使用pnpm
### 1.1 选择合适的缓存模式
```yaml
# 追求最快的安装且目录较稳定:缓存 node_modules(默认)
- uses: actions/xgj/npm-install@v1
with:
package-manager: pnpm
cache-mode: node_modules
# 追求更高的通用性和复用率:缓存包管理器 store(首次仍需 install 链接)
- uses: actions/xgj/npm-install@v1
with:
package-manager: pnpm
cache-mode: store
2. 合理使用强制安装
# 仅在必要时使用强制安装
- uses: actions/xgj/npm-install@v1
with:
force-install: "true" # 仅用于解决依赖冲突
3. 自定义缓存前缀避免冲突
# 为不同项目使用不同的缓存前缀
- uses: actions/xgj/npm-install@v1
with:
cache-prefix: "frontend-app"
4. 利用输出参数优化流程
- name: 安装依赖
id: install
uses: actions/xgj/npm-install@v1
# 仅在重新安装依赖时执行某些步骤
- name: 重建缓存
if: steps.install.outputs.cache-hit != 'true'
run: npm run build:cache
# 调试:打印缓存路径(可用于后续步骤复用路径)
- name: 打印缓存路径
run: echo "Cache path is: ${{ steps.install.outputs.cache-path }}"
🚨 注意事项
- Git Stash: 启用
enable-git-stash
会在安装后执行git stash
,请确保这符合你的工作流需求 - 缓存大小: node_modules 可能很大,请关注 GitHub Actions 的缓存限制
- Lock 文件: 确保 lock 文件已提交到仓库,这是缓存 key 生成的基础
- 权限: 某些自定义安装命令可能需要额外的权限
- 跨包管理器缓存隔离: 缓存 key 与 restore-keys 均包含包管理器、版本(pnpm)与模式,切换包管理器/模式时会触发一次干净安装,避免污染
🛡️ 封闭网络/慢网优化
在网络较差或对外网络受限的环境中,建议:
- 本 Action 已默认缓存 pnpm 二进制(Corepack 缓存目录),首次成功后后续运行将跳过 pnpm 下载。
- 缓存路径(按 OS 区分,Action 会全部尝试):
- Linux:
~/.cache/corepack
- macOS:
~/Library/Caches/CorePack
与~/Library/Caches/Corepack
- Windows:
C:\Users\runneradmin\AppData\Local\Corepack\cache
- Linux:
- 缓存 key:
${{ runner.os }}-corepack-pnpm-${{ inputs.pnpm-version }}
- 缓存路径(按 OS 区分,Action 会全部尝试):
- 将 registry 指向内网镜像或近源镜像,并(如需)配置
NODE_AUTH_TOKEN
。 - 适当降低并发、调大超时与重试,例如设置:
pnpm config set network-concurrency 1
与对应的npm config set network-timeout ...
等。 - 使用
cache-mode: store
并确保pnpm store path
被缓存(Action 默认已处理)。首次成功安装后,后续基本本地链接即可。
🔍 故障排除
缓存未命中
如果缓存总是未命中,检查:
- lock 文件是否存在且已提交
- package.json 或 lock 文件是否有变更
- 缓存前缀是否与之前一致
- 是否切换了包管理器或
cache-mode
(切换会生成不同的 key 与前缀)
pnpm store 路径
当 cache-mode=store
且 package-manager=pnpm
时,本 Action 会通过 pnpm store path
动态解析缓存目录;若命令不可用,则回退到 ~/.pnpm-store
。
安装失败
如果安装失败,尝试:
- 启用
force-install
- 使用自定义安装命令
- 检查 Node.js 版本兼容性
Git Stash 问题
如果 git stash 出现问题:
- 确保工作目录有可 stash 的变更
- 考虑禁用
enable-git-stash
- 在 action 之前确保 git 配置正确