自动化 CI/CD 管道(如 GitHub Actions)是现代软件质量控制的基石。但是,如果您的工作流程在每个拉取请求上获取外部包、启动容器环境并从头开始重建整个应用程序,则执行时间可能会迅速增加到几分钟。
较长的反馈循环会降低开发人员的工作效率并导致更高的计费成本。
在本文中,我们将演示如何利用 GitHub 的官方缓存机制将您的工作流程从几分钟加快到几秒钟。
1. GitHub Actions 中的缓存如何工作
GitHub Actions 缓存将文件(例如包依赖项和构建输出)保存到 GitHub 管理的安全存储层。在后续运行中,运行程序将恢复这些目录,而不是重新下载或编译它们。
缓存对于以下方面非常有效:
- 包管理器缓存文件夹(例如
.npm或yarn缓存)。 - Web 框架构建目标(例如 Next.js 中的
.next/cache)。 - 编译器中间体(Rust 目标目录、Go 构建缓存)。
2. 使用 setup-* 操作进行本机包缓存
为 Node.js 等运行时环境启用缓存的最简单方法是通过 GitHub 官方设置操作中的集成选项。
使用 npm (.github/workflows/ci.yml) 的 Node.js 项目的示例工作流程:
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
# Enable automatic caching for npm dependencies
cache: 'npm'
# Automatically restores dependency cache mapping package-lock.json hashes
- name: Install dependencies
run: npm ci
- name: Run test
run: npm test
只需设置 cache: 'yarn' 或 cache: 'pnpm' 即可分别处理 Yarn 和 pnpm 设置,无需任何其他配置。
3. actions/cache 的高级配置
如果您需要缓存自定义目录(例如编译文件夹或框架构建输出),请使用独立的 actions/cache 操作。
以下是在 Next.js 项目中缓存 .next/cache 目录的示例设置:
- name: Cache Next.js build
uses: actions/cache@v4
with:
# Define directories to preserve
path: |
${{ github.workspace }}/.next/cache
# Create a cache key using dependency locks and code hashes
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.ts', '**/*.tsx') }}
# Fallback prefixes if an exact key match is not found
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
了解配置参数:
path:要包含在缓存上传/下载中的文件路径。key:标识缓存的唯一字符串。如果在服务器上找到匹配项,运行程序将恢复文件。我们计算锁定文件和代码目录的加密哈希值,以便对依赖项或代码的更改正确地使缓存失效。restore-keys:如果主key丢失,则使用后备前缀的有序列表。 Git 使用它来加载最接近的匹配缓存,从而启用增量构建。
4. 缓存范围和限制
- 存储限制:GitHub 将每个存储库的缓存存储限制为 10GB。如果您的存储库超出此限制,旧的缓存有效负载将被自动驱逐。
- 访问范围:缓存按分支隔离。拉取请求分支可以访问父分支的缓存,但无法对其进行写入或从隔离的同级分支中读取缓存,从而确保构建安全。
结论
优化 CI 反馈循环是一项影响深远的生活质量升级。经过:
- 在设置任务中激活内置配置 (
cache: 'npm'), - 使用
actions/cache作为框架构建目录(如 Next.js),以及 - 设计适当的缓存键和后备,
您可以显着缩短构建时间并降低基础设施成本。

