Github Actionsのcacheをデータの永続化(?)に使う
Github Actionsでワークフローを作るとき、「どこかにデータを保存して次の実行時に参照したいな」「別のワークフローとデータを共有したいな」と思ったことはないでしょうか。
実は、普段キャッシュ用途に使っている actions/cache を使うと、制限付きでこの辺りが実現できます。
actions/cache
actions/cache は任意の文字列(key)を使って、指定ディレクトリや指定ファイルを保存し、任意の文字列(restore-keys)を使って復元できる仕組みです。
主に依存インストールのキャッシュやビルドのキャッシュに使われていますが、この仕組みをもっと汎用的に考えればデータの永続化(?)にも使えます。
制限
actions/cache には以下の制限があります:
- レポジトリ全体で10GBまで(2022/6/4現在)
- 保持期間は7日間
この条件を満たさないものは、古いものから順に削除されていきます。
なのでこの記事が適用できるのは、例えば決まった曜日にscheduleで実行されるWorkflowで7日以上間隔が空かないものや、一定期間過ぎたらリセットされても問題ないものになります。
(私は、月曜と木曜にメンバーを輪番で指名するWorkflowのために使用しています)
Starカウンター
簡単な例としてレポジトリにスターが付くたびにインクリメントするWorkflowを考えてみましょう。
on句にwatchを指定することでスターが付くたびにWorkflowが実行されます。あとは、cacheを使って現在のスター数をインクリメントしていけば、なんとなくカウントできそうです。
(Github API叩けばスター数取れるじゃんというのは一旦置いておきましょう)
name: Star Counter on: watch: types: [started] env: STATE_FILE: './state' jobs: increment: runs-on: ubuntu-20.04 steps: - name: IDの生成 id: build-id run: echo "::set-output name=id::$(date +%s)" - uses: actions/cache@v3 id: state with: path: ${{ env.STATE_FILE }} key: counter-${{ steps.build-id.outputs.id }} # 毎回、最新のキャッシュを保存するためにIDを指定する restore-keys: counter- # 復元時は最新のキャッシュを指定する - name: 初回ならカウンターを初期化 run: | if [ ! -f ${{ env.STATE_FILE }} ]; then echo '0' > ${{ env.STATE_FILE }} fi - name: カウンターをインクリメントする run: | VALUE=$(cat ${{ env.STATE_FILE }}) echo "CURRENT: $VALUE" echo "$((VALUE + 1))" >| ${{ env.STATE_FILE }}
これを実行すると、以下のように実行されるたびに前回の状態を復元し、インクリメントするWorkflowが実現できます。
その他の可能性
まだ試していませんが、Workflowが同時に走らないという前提があれば、このキャッシュを通じて他のWorkflowとも値を共有できます。
このキャッシュは「ブランチ」と「key」のスコープで共有されるため、同じ「key」を指定すれば同じデータが見れるはずです。
Workflowが同時に走りうる場合は不整合が起きるので、トリガーがscheduleで1日おきに動かすWorkflowなどだったら安全に扱えるのではと思っています。
https://github.com/actions/cache#cache-scopes
まとめ
制限はあるが、actions/cache を使ってデータの永続化(?)ができる。 簡単なWorkflowなら、Workflow間の状態を持たせることができる。