目的
GitHub Actionsのキャッシュは上限が10GBです。 キャッシュが上限に達すると、古いキャッシュが都度削除されることになるので、 パフォーマンスが落ちてしまいます。 そこで、三日に一回最新のキャッシュ以外を削除するワークフローを書きました。 トリガーや削除条件は各々の環境によってアレンジした方がいいかもしれません。
GitHub Actionsのキャッシュに関するドキュメント
- https://docs.github.com/ja/actions/using-workflows/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy
- https://docs.github.com/ja/actions/using-workflows/caching-dependencies-to-speed-up-workflows#managing-caches
ソースコード
actions/github-scriptで書いています。
actions/gh-actions-cache で出力した結果をshellでゴニョゴニョして実装したり色々と遠回りしてしまいました。
on:
workflow_dispatch:
schedule:
- cron: '0 0 */3 * *'
env:
GH_TOKEN: ${{ github.token }}
jobs:
setup:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
id: delete-dependency-cache
with:
result-encoding: string
script: |
const owner = context.repo.owner
const repo = context.repo.repo
const key = 'YOUR_CACHE_KEY'
// キャッシュを全件取得する
const opts = await github.rest.actions.getActionsCacheList.endpoint.merge({
owner, repo, key,
sort: 'last_accessed_at',
})
const actionsCaches = await github.paginate(opts)
// 一件以下ならスキップする
if (actionsCaches.length <= 1) {
console.log('*** Skipped ***')
console.log(`Number of caches: ${actionsCaches.length}`)
console.log(actionsCaches)
return
}
// 最初の一件を除いて削除する
const deleteTargets = actionsCaches.slice(1)
await Promise.all(deleteTargets.map(deleteTarget => {
return github.rest.actions.deleteActionsCacheById({
owner, repo,
cache_id: deleteTarget.id,
})
}))
console.log('*** Deleted ***')
console.log(`Number of caches: ${deleteTargets.length}`)
console.log(deleteTargets)
一応、シンタックスハイライト付きの script
も載せておきます。
const owner = context.repo.owner
const repo = context.repo.repo
const key = 'YOUR_CACHE_KEY'
// キャッシュを全件取得する
const opts = await github.rest.actions.getActionsCacheList.endpoint.merge({
owner, repo, key,
sort: 'last_accessed_at',
})
const actionsCaches = await github.paginate(opts)
// 一件以下ならスキップする
if (actionsCaches.length <= 1) {
console.log('*** Skipped ***')
console.log(`Number of caches: ${actionsCaches.length}`)
console.log(actionsCaches)
return
}
// 最初の一件を除いて削除する
const deleteTargets = actionsCaches.slice(1)
await Promise.all(deleteTargets.map(deleteTarget => {
return github.rest.actions.deleteActionsCacheById({
owner, repo,
cache_id: deleteTarget.id,
})
}))
console.log('*** Deleted ***')
console.log(`Number of caches: ${deleteTargets.length}`)
console.log(deleteTargets)
感想
actions/github-script 便利ですね。 octokit/rest.jsがベースになっているので、 ページネーションを使った全件取得も簡単でした。