清除 GitHub 操作中的缓存

我正在开发一个 R 包,并使用 GitHub Action (GHA)作为持续集成(CI)提供者。我使用 actions/cache缓存 R 包(依赖项)。现在我要清空所有缓存。我该怎么做?


我使用的 GHA 工作流程的一部分:
on: push


name: R-CMD-check


jobs:
R-CMD-check:
runs-on: ${{ matrix.config.os }}


name: ${{ matrix.config.os }} (${{ matrix.config.r }})


strategy:
fail-fast: false
matrix:
config:
# - {os: windows-latest, r: 'devel'}
- {os: macOS-latest,   r: 'release'}


env:
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
RSPM: ${{ matrix.config.rspm }}
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}


steps:
- uses: actions/checkout@v2


- uses: r-lib/actions/setup-r@master


- name: Query dependencies
run: |
repos <- c("https://r-hyperspec.github.io/hySpc.pkgs/", getOption("repos"))
saveRDS("remotes::dev_package_deps(dependencies = TRUE)", ".github/depends.Rds", version = 2)
writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version")
shell: Rscript {0}


- name: Cache R packages
if: runner.os != 'Windows'
uses: actions/cache@v1
with:
path: ${{ env.R_LIBS_USER }}
key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }}
restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-


- name: Install dependencies
run:   remotes::install_deps(dependencies = TRUE)
shell: Rscript {0}


- name: Session info
run: |
options(width = 100)
pkgs <- installed.packages()[, "Package"]
sessioninfo::session_info(pkgs, include_base = TRUE)
shell: Rscript {0}
45299 次浏览

您当前无法强制清除缓存,而且似乎在 https://github.com/actions/cache/issues/2时有一个开放的特性请求。如果我是你,我也会在那里发布请求,这样他们就知道更多的人希望实现这个特性。

关于这次行动,有几点需要注意:

操作中没有参数,甚至在构建此操作的工具包包中也没有参数。

在深入研究工具箱代码时,他们使用一个缓存 api URL 来完成所有有用的工作。这意味着我们甚至不知道 api 是否支持它,假设我们试图测试它,并通过直接命中它来查看它还提供了什么。下面是从 env ACTION _ CACHE _ URL 获取基本 URL 的 api 调用的行

Https://github.com/actions/toolkit/blob/c2bc747506bf562195a02bd4fdb1ff2a95d8b7ed/packages/cache/src/internal/cachehttpclient.ts#l44

Npm 包作为参考 https://www.npmjs.com/package/@actions/cache

既然我们已经深入研究了 action/cache 代码以及它是如何工作的,如果我们退一步回到 github 文档,

根据 github 文档 https://docs.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows

有两件事要注意,

Once you create a cache, you cannot change the contents of an existing
cache but you can create a new cache with a new key.
GitHub will remove any cache entries that have not been accessed in over 7 days.

@ GegznaV 你可以使用类似 好的的东西,然后通过 sshing 进入运行器手动清除缓存。

更新(二○二二年十月二十日)

你现在可以:

https://github.com/<OWNER>/<REPO>/actions/caches

更新(二○二二年六月二十七日)

你现在可以:

  • 存储库缓存的 GET列表:

    $ curl \
    -H "Accept: application/vnd.github.v3+json" \
    -H "Authorization: token <TOKEN>" \
    https://api.github.com/repos/OWNER/REPO/actions/caches
    
  • 使用缓存 ID 的存储库的 DELETE缓存:

    $ curl \
    -X DELETE \
    -H "Accept: application/vnd.github.v3+json" \
    -H "Authorization: token <TOKEN>" \
    https://api.github.com/repos/OWNER/REPO/actions/caches/CACHE_ID
    

或者,您也可以使用 GitHub CLI与 API 交互,使用 Gh-actions-cache 扩展

原文(2020年11月13日)

正如在 相应的问题中指出的,可以使用两种实用的解决方案来强制使用新的缓存。这与清除当前缓存(关于 缓存使用限制)不完全相同,但它完成了这项工作。

为此,您必须更改缓存 key(以及任何 restore-keys)。因为如果键是/不同的,这将被认为是缓存丢失,您将从一个新的开始。

您可以通过直接修改工作流文件来更改缓存键,例如,通过添加版本号:

key: $\{\{ runner.os }}-mycache-v1-$\{\{ hashFiles(...) }}

如果您现在想要使用一个新的缓存,您所需要做的就是提交一个不同的版本号:

key: $\{\{ runner.os }}-mycache-v2-$\{\{ hashFiles(...) }}

如果你不想修改工作流文件而更喜欢使用 UI,你可以滥用 秘密:

key: $\{\{ runner.os }}-mycache-$\{\{ secrets.CACHE_VERSION }}-$\{\{ hashFiles(...) }}

每当秘密更改时,都将使用新的缓存。

Something 警告:用于缓存键的密钥是 “显示”在用户界面中

下面是另一个类似于@beatngu13的缓存密钥失效方法的自动化解决方案。这个文件使用生成的时间戳文件,该文件被提交,然后以 hashFiles(...)前缀用于缓存键。

其中包括一组 GNU Makefile目标,使得使用这种方法非常容易: make clear-github-cache

注意: 确保每个 Makefile“菜谱”部分都缩进了1个制表符!StackOverflow 将制表符转换为代码块中的空格。

.github/clear_github_actions_cache:
date  +%s > .github/clear_github_actions_cache


.PHONY: clean-github-cache-file clear-github-cache
clear-github-cache: clean-github-cache-file .github/clear_github_actions_cache ## Force GitHub Actions Cache key to change for fresh CI run
git add .github/clear_github_actions_cache
git commit -m "Clear GitHub Actions Cache @ $$(cat .github/clear_github_actions_cache)"


clean-github-cache-file: ## Remove GitHub Actions Cache timestamp invalidator file.
[ -f '.github/clear_github_actions_cache' ] && rm -f '.github/clear_github_actions_cache' || true

然后,在 GitHub Actions 工作流 YAML 中,添加一个缓存密钥前缀,该前缀使用该文件的哈希值:

      - name: Cache R packages
if: runner.os != 'Windows'
uses: actions/cache@v2
with:
path: $\{\{ env.R_LIBS_USER }}
key: $\{\{ runner.os }}-$\{\{ runner.arch }}-$\{\{ hashFiles('.github/clear_github_actions_cache') }}-$\{\{ hashFiles('.github/R-version') }}-$\{\{ hashFiles('.github/depends.Rds') }}
restore-keys: |
$\{\{ runner.os }}-$\{\{ runner.arch }}-$\{\{ hashFiles('.github/clear_github_actions_cache') }}-$\{\{ hashFiles('.github/R-version') }}-$\{\{ hashFiles('.github/depends.Rds') }}
$\{\{ runner.os }}-$\{\{ runner.arch }}-$\{\{ hashFiles('.github/clear_github_actions_cache') }}-$\{\{ hashFiles('.github/R-version') }}-
$\{\{ runner.os }}-$\{\{ runner.arch }}-$\{\{ hashFiles('.github/clear_github_actions_cache') }}-

现在快跑:

make clear-github-cache

这将生成并提交一个文件 .github/clear_github_actions_cache,其内容为 Unix 时间戳。hashFiles(...)缓存键前缀使用这个前缀,并将生成这个文件的唯一散列,作为缓存/restore-key其余部分的前缀。

下一次使用 git push时,缓存键将失效... ... 有效地使用空缓存运行 GitHub Actions。

基于@beatngu13 回答我已经创建了 Makefile 目标,可以从 Github Actions 中删除所有缓存:

GH_REPO ?= ALLATRA-IT/ephyr  # replace with your `org/repo`


# Clear Github Acions usage cache.
#
# Need to install github cli first [https://cli.github.com/] and authorize
#
# Usage:
#   make gh.clear


gh.clear:
gh api -H "Accept: application/vnd.github+json" \
/repos/$(GH_REPO)/actions/caches \
| for ID in `jq '.actions_caches[].id'`; \
do echo "Deleting $$ID"; \
gh api --method DELETE /repos/$(GH_REPO)/actions/caches/$$ID | echo; done

需要先安装 Github CLIJq 工具工具。安装 Github CLI 后,需要授权:

gh auth login

这也可以通过 GH 操作来完成。

name: Clear cache


on:
workflow_dispatch:


permissions:
actions: write


jobs:
clear-cache:
runs-on: ubuntu-latest
steps:
- name: Clear cache
uses: actions/github-script@v6
with:
script: |
console.log("About to clear")
const caches = await github.rest.actions.getActionsCacheList({
owner: context.repo.owner,
repo: context.repo.repo,
})
for (const cache of caches.data.actions_caches) {
console.log(cache)
github.rest.actions.deleteActionsCacheById({
owner: context.repo.owner,
repo: context.repo.repo,
cache_id: cache.id,
})
}
console.log("Clear completed")

确保它被合并到 HEAD 分支,并从 Actions 手动触发它。

对于任何寻找简单命令行解决方案的人来说,下面的 shell 命令也可以做到这一点。它需要 Github CLI + JQ:

gh api -H 'Accept: application/vnd.github+json' /repos/realm/realm-kotlin/actions/caches --paginate | jq -r '.actions_caches | .[].key' | sed -e 's/|/%7c/g' -e 's/\[/%5b/g' -e 's/\]/%5d/g' | xargs -I {} sh -c 'gh api --method DELETE -H "Accept: application/vnd.github+json" /repos/<OWNER>/<REPO>/actions/caches?key={} --silent'

在本例中,我使用 sed 来 URL 编码密钥中的特殊字符。我只是需要处理一下。其他可以根据需要添加。例如 https://gist.github.com/jaytaylor/5a90c49e0976aadfe0726a847ce58736#file-url_encode-sh-L11