说我有一个包含两个步骤的GitHub动作工作流。
我的依赖项很少更改,并且可以安全地缓存已编译的依赖项,直到下次更改指定其版本的锁定文件为止。
是否可以保存第一步的结果,以便将来的工作流可以跳过该步骤?
答案 0 :(得分:20)
现在通过cache action本地支持缓存。它可以跨存储库中的作业和工作流工作。另请参阅:https://help.github.com/en/actions/automating-your-workflow-with-github-actions/caching-dependencies-to-speed-up-workflows。
name: GitHub Actions Workflow with NPM cache
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Use Node.js 8
uses: actions/setup-node@v1
with:
node-version: 8.x
- name: Cache NPM dependencies
uses: actions/cache@v1
with:
path: node_modules
key: ${{ runner.OS }}-npm-cache-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.OS }}-npm-cache-
- name: Install NPM dependencies
run: npm install
path
操作的key
和cache
参数用于标识缓存。
可选的restore-keys
用于可能的回退到部分匹配(即,如果package-lock.json
更改,将使用以前的缓存)。
在使用npm-cache
后备并且存在多个不同的缓存(例如JS程序包和系统程序包)的情况下,使用某些ID(在此示例中为restore-keys
)前缀键非常有用。否则,一个缓存可能会退回到另一个不相关的缓存。同样,使用操作系统前缀在使用矩阵构建时很有用,这样就不会混淆不同系统的缓存。
旧答案:
当前无法进行本地缓存,expected to be implemented by mid-November 2019。
您可以使用工件(1,2)按照GH Community board的建议在作业之间(在1个工作流程中)移动目录。但是,这是doesn't work across workflows。
答案 1 :(得分:5)
在当前GitHub Actions版本(2019年8月23日)上无法使用缓存文件。在circleCi上是可能的。
以下是我的测试:
使用了test file。
1)在GITHUB_WORKSPACE
上写
我的路径:/ home / runner / work / github-actions-test / github-actions-test)
结果:第一份工作可写且可读,但第二份工作为空
Action link
2)写在/github/home
上
我的路径:/ github / home
结果:cannot access '/github/home/
Action link
3)在/home
上写
我的路径:/ home
结果:touch: cannot touch '/home/myFile.txt': Permission denied
Action link
您不能在任何文件夹的作业之间持久保存文件。
答案 2 :(得分:2)
我的依存关系很少更改,可以安全地缓存已编译的依存关系,直到我下次更改指定其版本的锁文件为止。是否可以保存第一步的结果,以便将来的工作流可以跳过该步?
第一步是:
下载并编译我的应用程序的依赖项。
GitHub Actions本身不会为您执行此操作。我能给您的唯一建议是您遵守Docker最佳实践,以确保如果Actions确实利用了docker缓存,图像可以重新使用而不是重新构建。参见:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache
构建映像时,Docker逐步执行Dockerfile中的指令,并按指定的顺序执行每个指令。在检查每条指令时,Docker会在其缓存中寻找一个可以重用的现有映像,而不是创建一个新的(重复的)映像。
这还意味着GitHub Actions的底层系统可以/将利用Docker缓存。
但是,诸如编译之类的事情,Docker将无法使用缓存机制,因此,如果您急需此内容,我建议您考虑得很好。另一种方法是从工件存储(Nexus,NPM,MavenCentral)下载编译/处理的文件,以跳过该步骤。您必须权衡在此基础上增加的收益与复杂性之间的关系。
答案 3 :(得分:2)
actions/cache现在可以进行缓存了。请参见存储库以获取full list of examples。
例如节点-npm
- uses: actions/cache@v1
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
还有关于缓存限制的说明。
单个缓存限制为400MB,存储库最多可以包含2GB缓存。达到2GB限制后,将根据上次访问缓存的时间驱逐较早的缓存。上周未访问的缓存也将被驱逐。
答案 4 :(得分:2)
这是通过使用新的缓存操作:https://github.com/actions/cache
实现的答案 5 :(得分:2)
cache
操作只能缓存文件夹的内容。因此,如果有这样的文件夹,则可以通过缓存它来赢得一些时间。
例如,如果您使用一些虚构的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
答案 6 :(得分:1)
如果您在http://caniuse.com/中使用Docker在WorkFlows中使用,则GitHub现在支持通过@peterevans answered操作进行缓存,但这有其局限性。
因此,您可能会发现有用的cache绕过GitHub的操作限制。 this action中的更多信息。
免责声明:我在GitHub正式创建缓存之前就创建了支持缓存的操作,但由于其简单性和灵活性,我仍然使用它。
答案 7 :(得分:0)
我将总结两个选项:
您可以在工作流程中添加命令以缓存目录。到达该步骤后,它将检查您指定的目录是否先前已保存。如果是这样,它将抓住它。如果没有,它不会。然后在进一步的步骤中,编写检查以查看是否存在缓存的数据。例如,假设您正在编译一些很大的并没有太大变化的依赖项。您可以在工作流程的开始添加一个缓存步骤,然后在目录内容不存在的情况下添加一个步骤。第一次运行时,找不到文件,但随后会找到文件,因此您的工作流程将运行得更快。
在后台,GitHub将目录的zip上传到github自己的AWS存储中。他们会清除超过一周的旧内容,或者清除2GB以上的内容。
此技术的一些缺点是它仅保存目录。因此,如果您安装到/ usr / bin,则必须对其进行缓存!那会很尴尬。相反,您应该安装到$ home / .local中,并使用echo set-env将其添加到您的路径中。
Docker稍微复杂一点,这意味着您必须拥有一个dockerhub帐户并立即管理两件事。但是它功能更强大。您不仅可以保存目录,还可以保存整个计算机!您要做的就是制作一个Dockerfile,其中将包含您的所有依赖项,例如apt-get和python pip行,甚至是长时间编译。然后,您将构建该docker映像并将其发布在dockerhub上。最后,将测试设置为在该新docker映像上运行,而不是在ubuntu-latest上运行。从现在开始,无需安装依赖项,而只需下载映像即可。
您可以通过将该Dockerfile与该项目存储在同一GitHub存储库中进一步自动化操作,然后编写包含以下步骤的作业,该步骤将下载最新的Docker映像,必要时仅重建更改的步骤,然后上载到dockerhub。然后是一项“需要”该工作并使用图像的工作。这样,您的工作流将既可以根据需要更新docker映像,也可以使用它。
缺点是您的部门将放在一个文件,Dockerfile和工作流程中的测试中,因此它们并没有在一起。另外,如果下载映像的时间大于建立依赖项的时间,那么这是一个糟糕的选择。
我认为每个人都有其优点和缺点。缓存仅适用于非常简单的内容,例如编译为.local。如果您需要更广泛的功能,则Docker是最强大的。