假设我有一个包含2个步骤的 GitHub actions 工作流程。
- 下载并编译我的应用程序依赖项。
- 编译和测试我的应用程序。
我的依赖关系很少更改,已编译的依赖关系可以安全地缓存,直到下次更改锁定文件以指定它们的版本。
有没有一种方法可以保存第一步的结果,以便将来的工作流程可以跳过该步骤?
假设我有一个包含2个步骤的 GitHub actions 工作流程。
我的依赖关系很少更改,已编译的依赖关系可以安全地缓存,直到下次更改锁定文件以指定它们的版本。
有没有一种方法可以保存第一步的结果,以便将来的工作流程可以跳过该步骤?
大多数用例都可以使用现有的操作来完成,例如:
actions/setup-node
用于 JSdocker/build-push-action
用于 Docker可以通过 缓存操作 来支持自定义缓存。它适用于存储库中的作业和工作流。另请参阅:GitHub文档 和 示例。
考虑 以下示例:
name: GitHub Actions Workflow with NPM cache
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Cache NPM dependencies
uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.OS }}-npm-cache-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.OS }}-npm-cache-
- name: Install NPM dependencies
run: npm install
缓存是如何逐步实现的:
Cache NPM dependencies
步骤中,操作将检查当前key
是否存在现有缓存restore-keys
检查空间匹配项。在这种情况下,如果package-lock.json
更改,则会返回以前的缓存。将键和恢复键与缓存的 OS 和名称前缀一起使用很有用,因为它不应该为不同类型的缓存或操作系统加载文件。path
npm install
将使用~/.npm
中的文件来节省网络下载(请注意,对于NPM,直接缓存node_modules
不是推荐的方法)。key
发生更改。这在工作流程中没有明确定义,而是内置到缓存操作中,以同时处理缓存的加载和保存。您还可以使用@actions/cache构建自己的可重用缓存逻辑,例如:
旧答案:
目前不支持本地缓存,预计在2019年11月中旬实施。
您可以使用构件(1,2)按照 GH社区版 上的建议在作业之间移动目录(在一个工作流内)。然而,这种方法不能在工作流之间运行。
旧答案:
目前不支持本地缓存,预计在2019年11月中旬实施。
您可以使用构件(1,2)按照 GH社区版 上的建议在作业之间移动目录(在一个工作流内)。然而,这种方法不能在工作流之间运行。
if: steps.cache-deps.outputs.cache-hit != 'true'
和 id: cache-deps
这样的条件语句和缓存步骤,这个例子是否仍然会在每次推送时运行 npm install
步骤? - Janoshnpm install
步骤,从缓存中加载依赖项的好处是什么? - DannyFeliz@action/cache
的全部意义。它只是重复了GitHub无意义的文档,而这份文档也没有解释如何消耗缓存。 - Stevecache
操作仅能缓存文件夹的内容。如果有这样的文件夹,您可以通过缓存它来节省一些时间。
例如,如果您使用某个虚构的package-installer
(例如Python的pip
或virtualenv
,或NodeJS的npm
,或其他将其文件放入文件夹中的任何工具),您可以通过以下方式来节省一些时间:
- uses: actions/cache@v2
id: cache-packages # give it a name for checking the cache hit-or-not
with:
path: ./packages/ # what we cache: the folder
key: ${{ runner.os }}-packages-${{ hashFiles('**/packages*.txt') }}
restore-keys: |
${{ runner.os }}-packages-
- run: package-installer packages.txt
if: steps.cache-packages.outputs.cache-hit != 'true'
那么这里的重点是:
cache-packages
if
,steps.cache-packages.outputs.cache-hit != 'true'
./packages/
packages.txt
文件更改,则会重新构建缓存。对于virtualenv
用户:如果您需要激活某些shell环境,则必须在每个步骤中执行此操作。像这样:
- run: . ./environment/activate && command
现在可以使用以下方式本地支持:
https://help.github.com/en/actions/automating-your-workflow-with-github-actions/caching-dependencies-to-speed-up-workflows这是通过使用新的缓存操作(cache action)实现的:https://github.com/actions/cache
免责声明: 我在GitHub正式支持缓存之前创建了该操作,并且由于其简单和灵活性,我仍在使用它。
您可以在工作流程中添加一个命令来缓存目录。当到达该步骤时,它会检查您指定的目录是否已保存。如果是,则会获取它。如果没有,就不会获取。然后,在进一步的步骤中,您编写检查以查看缓存数据是否存在。例如,假设您正在编译某个相对较大且不经常更改的依赖项。您可以在工作流程的开头添加一个缓存步骤,然后添加一个构建目录内容的步骤(如果它们不存在)。第一次运行时,它不会找到文件,但随后它会找到并且您的工作流程将运行得更快。
在幕后,GitHub正在将您的目录的 zip 上传到 GitHub 自己的 AWS 存储。他们清除任何早于一周或达到 2GB 限制的内容。
使用此技术的一些缺点是它只保存目录。因此,如果您安装到 /usr/bin 中,则必须缓存该目录!那会很尴尬。您应该安装到 $home/.local 中,并使用 echo set-env 将其添加到路径中。
我认为每个工具都有其优点和缺点。缓存只适用于非常简单的内容,例如编译成 .local 文件。如果需要更复杂的内容,Docker 是最强大的工具。