定期的にGitHub Actionsのキャッシュを削除する

目的

GitHub Actionsのキャッシュは上限が10GBです。 キャッシュが上限に達すると、古いキャッシュが都度削除されることになるので、 パフォーマンスが落ちてしまいます。 そこで、三日に一回最新のキャッシュ以外を削除するワークフローを書きました。 トリガーや削除条件は各々の環境によってアレンジした方がいいかもしれません。

GitHub Actionsのキャッシュに関するドキュメント

ソースコード

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がベースになっているので、 ページネーションを使った全件取得も簡単でした。


定期的にGitHub Actionsのキャッシュを削除する

By Katsuya Endoh, 2024-06-18