kachick / times_kachick

`#times_kachick channel in chat` as a public repository. Personal Note and TODOs
https://github.com/kachick/times_kachick/issues?q=is%3Aissue+is%3Aclosed
6 stars 0 forks source link

2024-10-25 - GitHub Actions のキャッシュから merge された PR で使われていたものをファイルサイズが大きい順に消す #311

Closed kachick closed 1 month ago

kachick commented 1 month ago

TL; DR

gh pr list --state merged --json number --jq '.[].number' --limit 1000 | \
  xargs --no-run-if-empty -I '{}' gh cache list --sort size_in_bytes --order desc --json id --jq '.[].id' --limit 100 --ref 'refs/pull/{}/merge' | \
  xargs --no-run-if-empty --max-lines=1 gh cache delete

https://github.com/kachick/dotfiles/blob/e1e11f55f0b270f2f72db6196d91d7bf352e3265/.github/workflows/cleanup-caches.yml#L20-L25

N+1 どころではないが、まぁリクエスト先がGitHubだしええやろ(?)

ごちゃごちゃ

GitHub Actions の Cache は freeplan だと?10Gを超えると古いのが消されだす。そして https://github.com/DeterminateSystems/magic-nix-cache-action を使っていると大量のキャッシュで埋まる しかも scope がブランチ単位ということで、マージされたPRのキャッシュなんてどうでもいいものも default ブランチも多分一緒くたに日付ベースで消される ほしい要件としては マージされたブランチのキャッシュは消す、デフォルトブランチのキャッシュは残す、マージされてないブランチのキャッシュは残す、キャッシュを消すときは日付ベースでも悪くないけどそれよりまずサイズのでかいの消すのを優先してほしい(ページングが常に働くから雑に全部みたいな指定は難しい) このあたりのドキュメントで https://docs.github.com/ja/actions/writing-workflows/choosing-what-your-workflow-does/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy に誘導されるが、紹介されている https://github.com/actions/gh-actions-cache はそもそもつい先日 deprecated になっている。今は gh cli がこの機能をオフィシャルに提供しているらしい ( issue は https://github.com/github/docs/issues/35030 に上がってた ) で、この gh cache list/delete を組み合わせるわけだけれど、main だけリストするとか特定PRだけリストするみたいなのは簡単ながら、 main 以外をリストして消すみたいなのをストレートに実現できるようなオプションが見つからない。実際docsで紹介されていたのもPRマージ時だけに走らせる前提になっていたので、それ以前分とかは考慮されていない APIから調べたほうが綺麗にできそうな気もするけれど、とりあえず gh cli の他機能でマージされたPR一覧が出せるので、あとはxargs x 2で一応動く。--limit をあちこちに差し込む必要があるし大規模リポジトリには向かなそうなのと、一回動かせばあとは都度削除の方が良い気はする

kachick commented 3 weeks ago

main ブランチも古いものは消すみたいなのはこんな感じ

https://github.com/kachick/dotfiles/blob/436ec1401fd9f73edfb9773e4e4a513b75e7a8b5/.github/workflows/cleanup-caches.yml#L45-L51

threshold="$(date --rfc-3339='date' --date='-4 days')"
gh cache list --limit 2000 --ref 'refs/heads/main' --sort last_accessed_at --order asc --json 'id,lastAccessedAt,sizeInBytes' --jq ".[] | select(.lastAccessedAt < \"$threshold\") | .id" | \
  xargs --no-run-if-empty --max-lines=1 gh cache delete

timestamp は iso8601 的な形だから辞書順にソート出来る

ただ、これやってるときに GITHUB_TOKEN 使ってるにも関わらず rate limit にひっかかった

N+1 どころではないが、まぁリクエスト先がGitHubだしええやろ(?)

良くなかった。 しかしこれAPIを直接叩いても多分同じで、REST の DELETE endpoint 的に1つずつしか指定できない

https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28

GraphQL 側にはそもそも cache 系操作が無いと思うんよな・・・