GitHub Actions cache-dependency-path 怎样按锁文件拆分缓存
来源:17golang原创
时间:2026-11-02 08:50:11 245浏览 收藏
多包仓库里同时维护 frontend/package-lock.json 和 backend/package-lock.json 时,GitHub Actions 的依赖缓存很容易出现“一个锁文件变了,所有缓存一起失效”的现象。cache-dependency-path 决定哪些依赖文件参与缓存主键计算:把多个文件写在同一个列表里得到的是一个组合缓存;想按锁文件真正拆开,就要让每个缓存配置只指向自己的锁文件。
官方地址:https://github.com/actions/cache
下面以 actions/setup-node 为主,先从界面入口确认工作流,再分别给出组合缓存和拆分缓存写法。Python 的 setup-python 也采用同样的 cache-dependency-path 思路。
先确认缓存入口和锁文件范围
打开仓库的 Actions 页面,进入目标 workflow 的最近一次运行,先定位依赖安装步骤。文章中的界面图是原创操作说明图,不是 GitHub 实际页面截图;真正要确认的是 YAML 里是否同时出现了 cache 和 cache-dependency-path。

- 在工作流文件中找到
actions/setup-node或actions/setup-python。 - 确认已经打开缓存,例如 Node 使用
cache: npm,Python 使用cache: pip。 - 列出每个包目录真正提交到仓库的锁文件,不要把
node_modules、虚拟环境目录或临时文件当成依赖文件。
官方地址:https://github.com/actions/setup-node
要点是:cache-dependency-path 只负责指定用于生成缓存主键的依赖文件;它不会改变缓存目录,也不会把 node_modules 直接打包进缓存。setup-node 的内置缓存面向 npm、Yarn 和 pnpm 的全局包数据,setup-python 则面向 pip、pipenv 或 Poetry 的依赖缓存。
多个锁文件写在一起时,得到的是组合缓存
如果前端和后端总是一起安装,组合缓存最简单。用多行 YAML 把两个锁文件交给同一个 setup-node 步骤;两个文件都会参与主键计算。
name: install-monorepo
on:
push:
pull_request:
permissions:
contents: read # 只读取仓库内容,满足 checkout 和依赖安装需要
jobs:
install:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 24 # 示例固定 Node 主版本,避免运行环境漂移
cache: npm # 开启 setup-node 的 npm 依赖缓存
cache-dependency-path: |
frontend/package-lock.json
backend/package-lock.json # 两个锁文件共同参与同一个缓存主键
- run: npm ci --prefix frontend # 按前端锁文件安装,不修改依赖版本
- run: npm ci --prefix backend # 按后端锁文件安装,和前端共享命中结果
这种写法的可见结果是:任意一个锁文件发生变化,下一次运行都会得到新的组合主键。它适合两个包总是一起构建的场景;如果后端只改了自己的依赖,却不希望前端缓存跟着失效,就不要把两个路径放在同一个列表里。
想按锁文件拆开,先拆成独立工作流任务
真正的“按锁文件拆分”要让每个缓存配置只看到一个锁文件。对前端和后端可以使用两个独立 job:它们各自运行 checkout、setup-node 和安装命令,缓存主键也分别由自己的锁文件决定。

jobs:
frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 24 # 前端 job 固定自己的运行时版本
cache: npm
cache-dependency-path: frontend/package-lock.json # 只让前端锁文件影响主键
- run: npm ci --prefix frontend # 安装完成后让 setup-node 保存前端缓存
- run: npm test --prefix frontend # 前端测试失败时不要把结果当成缓存命中
backend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 24 # 后端可以独立升级自己的 Node 版本
cache: npm
cache-dependency-path: backend/package-lock.json # 后端只依赖自己的锁文件
- run: npm ci --prefix backend # 使用后端锁文件安装依赖
- run: npm test --prefix backend # 单独观察后端 job 的命中和失败状态
- 进入 workflow 运行详情,分别展开 frontend 和 backend job。
- 在各自的 setup 步骤中查看缓存命中提示;两个 job 不应因为对方锁文件改变而共同生成新主键。
- 如果两边必须在同一个 job 中运行,改用两个明确的
actions/cache步骤,并分别用hashFiles('frontend/package-lock.json')和hashFiles('backend/package-lock.json')生成 key;不要误以为在一个 setup-node 步骤里写两行路径就完成了拆分。
在运行页区分命中、未命中和路径不生效
配置完成后,重点看每个 job 的 setup 步骤和依赖安装步骤:
- 精确命中时,缓存动作会显示
cache-hit为true,依赖安装仍然会执行,但下载量通常更小。 - 缓存未命中时,setup 步骤会继续完成;只要 job 成功,新的依赖缓存会在运行结束时保存。
- 如果修改了
backend/package-lock.json,只有后端拆分 job 的主键应变化;组合缓存则会整体变化。 - 如果改路径后主键始终不变,先检查 YAML 缩进、文件是否已 checkout,以及路径是否相对于仓库根目录。
不要把“安装命令成功”当成“缓存配置正确”。缓存只改变依赖下载路径,不能替代锁文件,也不会自动修复没有固定版本的依赖声明。
常见问题
把两个锁文件写成多行,为什么还是只有一个缓存?
因为多行列表表达的是多个依赖文件共同参与一次哈希计算,结果是一个组合缓存。要得到独立缓存,需要拆分 job,或改用多个显式 actions/cache 步骤。
cache-dependency-path 能不能写 node_modules?
不建议。它应该指向 package-lock.json、yarn.lock、pnpm-lock.yaml、requirements.txt、pyproject.toml 或其他真正描述依赖版本的文件;缓存目录由对应的 setup action 或显式 cache 步骤决定。
为什么 cache-dependency-path 看起来不生效?
先确认缓存开关已打开。setup-node 只有在设置 cache 或符合其自动缓存条件时才会计算依赖缓存;setup-python 的缓存默认关闭,需要显式指定 cache。再确认锁文件已经被 checkout 且路径没有多余的工作区前缀。
最后确认
把多个锁文件写进同一个 cache-dependency-path 列表,得到的是组合缓存;按锁文件拆分时,应让每个 job 或显式缓存步骤只绑定一个锁文件。最终在 Actions 运行页分别确认命中状态、依赖安装步骤和主键变化,再决定这套配置是否符合仓库的构建边界。
-
Golang · Go教程 | 3个月前 | CI/CD · gitHub actions · Go教程 · 持续集成 · Go 持续集成 CI Go test GitHub Actions self-hosted runner 自托管 runner340 收藏
-
182 收藏
-
250 收藏
-
447 收藏
-
373 收藏
-
219 收藏
-
216 收藏
-
186 收藏
-
315 收藏
-
295 收藏
-
470 收藏
-
文章 · 软件教程 | 1小时前 | Markdown · gitHub actions · 软件教程 · 持续集成 · GitHub Actions GITHUB_STEP_SUMMARY Job Summary workflow commands 构建摘要222 收藏
-
376 收藏
-
301 收藏
-
312 收藏
-
108 收藏
-
432 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习