关于缓存工作流程依赖项
工作流程运行通常在不同运行之间重新使用相同的输出或下载的依赖项。 例如,Maven、Gradle、npm 和 Yarn 等软件包和依赖项管理工具都会对下载的依赖项保留本地缓存。
GitHub 托管的运行器在一个干净的虚拟环境中启动,每次都必须下载依赖项,造成网络利用率提高、运行时间延长和成本增加。 为帮助加快重新创建诸如依赖项的文件,GitHub 可以缓存您在工作流程中经常使用的文件。
要缓存作业的依赖项,可以使用 GitHub 的 cache
操作。 该操作将创建并还原由唯一键标识的缓存。 或者,如果要缓存下面列出的包管理器,则使用其各自的 setup-* 操作时需要的配置最少,并且将为您创建和还原依赖项缓存。
包管理器 | 用于缓存的 setup-* 操作 |
---|---|
npm, Yarn, pnpm | setup-node |
pip, pipenv, Poetry | setup-python |
Gradle, Maven | setup-java |
RubyGems | setup-ruby |
Go go.sum | setup-go |
警告:将缓存与 GitHub Actions 一起使用时,请注意以下事项:
- 我们建议您不要在缓存中存储任何敏感信息。 例如,敏感信息可以包括存储在缓存路径的文件中的访问令牌或登录凭据。 此外,命令行接口 (CLI) 程序,例如
docker login
,可以在配置文件中保存访问凭据。 具有读取访问权限的任何人都可以在仓库上创建拉取请求并访问缓存的内容。 仓库的复刻也可在基本分支上创建拉取请求,并在基本分支上访问缓存。 - 使用自托管运行器时,工作流程运行的缓存存储在 GitHub 拥有的云存储上。 客户拥有的存储解决方案仅适用于 GitHub Enterprise Server。
比较构件和依赖项缓存
构件与缓存类似,因为它们能够在 GitHub 上存储文件,但每项功能都提供不同的用例,不能互换使用。
- Use caching when you want to reuse files that don't change often between jobs or workflow runs, such as build dependencies from a package management system.
- Use artifacts when you want to save files produced by a job to view after a workflow run has ended, such as built binaries or build logs.
有关工作流程运行工件的更多信息,请参阅“使用工件持久化工作流程数据”。
访问缓存的限制
工作流程可以访问和还原当前分支、基础分支(包括复刻的仓库的基本分支)或默认分支(通常是 main
)中创建的缓存 例如,在默认分支上创建的缓存可从任何拉取请求访问。 另外,如果分支 feature-b
具有基础分支 feature-a
,则触发于 feature-b
的工作流程可以访问默认分支 (main
)、feature-a
和 feature-b
中创建的缓存。
访问限制通过在不同分支之间创建逻辑边界来提供缓存隔离和安全。 例如, 为分支 feature-a
(具有基础分支 main
)创建的缓存将无法访问分支 feature-c
(具有基础分支 main
)的拉取请求。
仓库中的多个工作流程共享缓存条目。 可以从同一仓库和分支的另一个工作流程访问和恢复为工作流程中的分支创建的缓存。
使用 cache
操作
cache
操作将尝试恢复基于您提供的 key
的缓存。 当操作找到缓存时,该操作会将缓存的文件还原到您配置的 path
。
如果没有精确匹配,操作在作业成功完成时将自动创建一个新的缓存。 新缓存将使用您提供的 key
并包含 path
中指定的文件。
当 key
与现有缓存不匹配时,您可以选择性提供要使用的 restore-keys
列表。 restore-keys
列表很有用,因为 restore-keys
可以部分匹配缓存密钥。 有关匹配 restore-keys
的更多信息,请参阅“匹配缓存密钥”。
cache
操作的输入参数
-
key
:必要 保存缓存时创建的键,以及用于搜索缓存的键。 它可以是变量、上下文值、静态字符串和函数的任何组合。 密钥最大长度为 512 个字符,密钥长度超过最大长度将导致操作失败。 -
path
:必要 运行器上缓存或还原的文件路径。-
可以指定单个路径,也可以在单独的行上添加多个路径。 例如:
- name: Cache Gradle packages uses: actions/cache@v3 with: path: | ~/.gradle/caches ~/.gradle/wrapper
-
您可以指定目录或单个文件,并且支持 glob 模式。
-
可以指定绝对路径或相对于工作区目录的路径。
-
-
restore-keys
:可选 包含备用恢复键的字符串,每个恢复键都放在新行上。 如果key
未发生缓存命中,则按提供的查找和恢复缓存的顺序使用这些恢复密钥。 例如:restore-keys: | npm-feature-${{ hashFiles('package-lock.json') }} npm-feature- npm-
cache
操作的输出参数
cache-hit
:表示找到了密钥的精确匹配项的布尔值。
cache
操作使用示例
此示例在 package-lock.json
文件中的包更改时,或运行器的操作系统更改时,创建一个新的缓存。 缓存键使用上下文和表达式生成一个键值,其中包括运行器的操作系统和 package-lock.json
文件的 SHA-256 哈希。
name: Caching with npm
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Cache node modules
id: cache-npm
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- if: ${{ steps.cache-npm.outputs.cache-hit == 'false' }}
name: List the state of node modules
continue-on-error: true
run: npm list
- name: Install dependencies
run: npm install
- name: Build
run: npm build
- name: Test
run: npm test
当 key
匹配现有缓存时,被称为缓存命中,并且操作会将缓存的文件还原到 path
目录。
当 key
不匹配现有缓存时,则被称为缓存错过,在作业成功完成时将自动创建一个新缓存。
发生缓存未命中时,该操作还会在指定的 restore-keys
中搜索任何匹配项:
- 如果您提供
restore-keys
,cache
操作将按顺序搜索与restore-keys
列表匹配的任何缓存。- 当精确匹配时,操作会将缓存中的文件恢复至
path
目录。 - 如果没有精确匹配,操作将会搜索恢复键值的部分匹配。 当操作找到部分匹配时,最近的缓存将恢复到
path
目录。
- 当精确匹配时,操作会将缓存中的文件恢复至
cache
操作完成,作业中的下一个步骤运行。- 如果作业成功完成,则操作将自动创建一个包含
path
目录内容的新缓存。
有关缓存匹配过程的更详细说明,请参阅“匹配缓存键”。 创建缓存后,无法更改现有缓存的内容,但可以使用新键创建新缓存。
使用上下文创建缓存键
缓存键可以包括 GitHub Actions 支持的任何上下文、函数、文本和运算符。 更多信息请参阅“上下文”和“表达式”。
使用表达式创建 key
允许您在依赖项更改时自动创建新缓存。
例如,您可以使用计算 npm package-lock.json
文件哈希的表达式创建 key
。 因此,当组成 package-lock.json
文件更改的依赖项时,缓存键会更改,并自动创建新的缓存。
npm-${{ hashFiles('package-lock.json') }}
GitHub 评估表达式 hash "package-lock.json"
以派生最终 key
。
npm-d5ea0750
使用 cache
操作的输出
您可以使用 cache
操作的输出来根据缓存命中或错过是否发生来执行某些操作。 如果存在缓存未命中(找不到指定 key
的缓存的完全匹配项),则 cache-hit
输出将设置为 false
。
在上面的示例工作流程中,有一个步骤列出了发生缓存未命中时 Node 模块的状态:
- if: ${{ steps.cache-npm.outputs.cache-hit == 'false' }}
name: List the state of node modules
continue-on-error: true
run: npm list
匹配缓存键
cache
操作会先在包含工作流程运行的分支中搜索 key
和 restore-key
的缓存命中。 如果当前分支中没有命中,cache
操作将在父分支和上游分支中搜索 key
和 restore-keys
。
restore-keys
允许您指定在 key
上出现缓存错过时要使用的备用还原密钥列表。 您可以创建从最具体到最不具体的多个恢复键。 cache
操作按顺序搜索 restore-keys
。 当键不直接匹配时,操作将搜索以恢复键为前缀的键。 如果恢复键值有多个部分匹配项,操作将返回最近创建的缓存。
使用多个恢复键值的示例
restore-keys: |
npm-feature-${{ hashFiles('package-lock.json') }}
npm-feature-
npm-
运行器将评估表达式,解析为以下 restore-keys
:
restore-keys: |
npm-feature-d5ea0750
npm-feature-
npm-
恢复键 npm-feature-
与任何以字符串 npm-feature-
开头的键值匹配。 例如,键值 npm-feature-fd3052de
和 npm-feature-a9b253ff
都与恢复键值匹配。 将使用创建日期最新的缓存。 此示例中的键值按以下顺序搜索:
npm-feature-d5ea0750
匹配特定的哈希。npm-feature-
匹配前缀为npm-feature-
的缓存键值。npm-
匹配前缀为npm-
的任何键值。
搜索优先级示例
key:
npm-feature-d5ea0750
restore-keys: |
npm-feature-
npm-
例如,如果拉取请求包含 feature
分支并针对默认分支 (main
),操作将按以下顺序搜索 key
和 restore-keys
:
feature
分支中的键值npm-feature-d5ea0750
feature
分支中的键值npm-feature-
feature
分支中的键值npm-
main
分支中的键值npm-feature-d5ea0750
main
分支中的键值npm-feature-
main
分支中的键值npm
使用限制和收回政策
GitHub 将删除 7 天内未被访问的任何缓存条目。 可以存储的缓存数没有限制,但存储库中所有缓存的总大小限制为 10 GB。
If you exceed the limit, GitHub will save the new cache but will begin evicting caches until the total size is less than the repository limit.
管理缓存
您可以使用 GitHub REST API 来管理缓存。 您可以使用 API 列出和删除缓存条目,并查看缓存使用情况。 有关详细信息,请参阅“GitHub Actions 缓存”REST API 文档。