GitHub Actions の「Artifact storage quota has been hit」の対処:古い Artifact の削除と continue-on-error・retention-days

GitHub Actions の「Artifact storage quota has been hit」の対処:古い Artifact の削除と continue-on-error・retention-days

GitHub Actions で、外部のサービスに記事を下書きとして投稿するワークフローを動かしています。drafts/ に置いた記事を定期実行で投稿し、終わったら posted/ に移してコミットする作りです。

ある日、投稿はできていたのに、そのあとでデバッグ用のスクリーンショットを Artifact に保存するステップが失敗していました。ログにはこう出ていました。

Failed to CreateArtifact: Artifact storage quota has been hit. Unable to upload any new artifacts. Usage is recalculated every 6-12 hours.

Artifact の保存が失敗したせいで、後に続くステップが動かず、不具合が起きていました。 古い Artifact を消し、保存のステップに continue-on-error: true と retention-days を付けて直しました。

目次

解決方法

1. 古い Artifact を消す

まず、リポジトリにどれだけ Artifact が残っているかを見ます。

gh api repos/<owner>/<repo>/actions/artifacts --paginate \
  --jq '.artifacts[] | [.id, .name, (.size_in_bytes/1048576*100|round/100|tostring)+" MB", .created_at, (.expired|tostring)] | @tsv' \
  | sort -t$'\t' -k4 -r

ID・名前・サイズ・作成日時・期限切れかどうかが、新しい順に並びます。今回は、デバッグ用のスクリーンショットと HTML が 103件、約590MB たまっていて、どれも期限切れになっていませんでした。

消しても困らないものだったので、全部消しました。

gh api repos/<owner>/<repo>/actions/artifacts --paginate --jq '.artifacts[].id' | while read id; do gh api -X DELETE repos/<owner>/<repo>/actions/artifacts/$id; done

このコマンドはリポジトリの Artifact をすべて消します。調査に使いたいものが残っているときは、一覧を見てから ID を選んで消すほうが安全です。

消しても、すぐには保存できるようになりません。 エラー文のとおり、使用量の再計算には時間がかかります。GitHub のドキュメントにもこう書かれています。

GitHub updates your artifact storage usage within 6 to 12 hours. (GitHub は Artifact のストレージ使用量を6〜12時間以内に更新します)

実際に、消してから約6時間半後の実行では、まだ同じエラーが出ていました。次に Artifact を保存した約1日後の実行では、保存できていました。

2. 保存のステップに continue-on-error と retention-days を付ける

デバッグ用の保存のステップに、2行を足しました(差分の抜粋)。

       - name: Upload debug artifacts
         if: always() && steps.select.outputs.found == 'true'
         uses: actions/upload-artifact@v4
+        continue-on-error: true
         with:
           ...
           if-no-files-found: ignore
+          retention-days: 7
  • continue-on-error: true:このステップが失敗しても、ジョブを失敗にせず、後のステップに進みます。デバッグ用の保存は、失敗しても投稿の結果には関係ないので、ジョブを止めないようにしました
  • retention-days: 7:Artifact の保存期間です。指定しないと、リポジトリの設定の期間(既定は90日)になります。調査には直近の数日分があれば足りるので、7日にしました

同じ保存のステップを持つほかのワークフローにも、同じ2行を足しました。

起きたこと

失敗した実行の、ステップごとの結果はこうでした。

ステップ 結果
記事を選ぶ success
記事を投稿する success
デバッグ用の Artifact を保存する failure
posted/ へ移してコミットする skipped

投稿は成功しているのに、後に続く posted/ へ移すステップは、失敗ではなくスキップされていました。

原因

後片付けのステップが飛ばされた理由

2つのステップの if: は、こうなっていました。

# デバッグ用の Artifact を保存する
if: always() && steps.select.outputs.found == 'true'

# posted/ へ移してコミットする
if: steps.select.outputs.found == 'true'

保存のステップには always() が付いているので、前のステップが失敗しても動きます。一方、posted/ へ移すステップには、always() や failure() のような状態を見る関数がありません。GitHub のドキュメントには、こう書かれています。

A default status check of success() is applied unless you include one of these functions. (これらの関数を含めない限り、既定で success() の状態チェックが適用されます)

つまり、移すステップの条件は、実際には「success() かつ対象の記事がある」になります。その前のどこかのステップが1つでも失敗すると、if: に書いた条件を満たしていてもスキップされます。 今回は、保存のステップの失敗がこれに当たりました。

容量を超えた理由

Artifact のストレージには上限があります。無料プラン(GitHub Free)の個人アカウントでは 500MB で、GitHub Packages と同じ枠を、アカウントのすべてのリポジトリで分け合います。

Actions artifacts and GitHub Packages storage share the same pooled allowance (Actions の Artifact と GitHub Packages のストレージは、同じ枠を共有します)

このワークフローは、投稿のたびにスクリーンショットと HTML を保存していました。保存期間を指定していなかったので、既定の90日が過ぎるまで1件も消えず、2か月分で約590MB になっていました。このリポジトリだけで 500MB を超えていたことになります。同じ作りのほかのリポジトリにも、合わせて100MBほど残っていました。

continue-on-error の注意点

直したあとの最初の実行では、上に書いたとおり、まだ容量超過のエラーが出ていました。それでも、保存のステップの結果は success になり、posted/ へ移すステップも動いて、ジョブは成功で終わりました。直したかった動きのとおりです。

その代わり、保存が失敗しても、ログを開かない限り気づけなくなります。 デバッグ用の保存なら、これで困らないと思います。結果を後で使うステップに付けると失敗が見えなくなるので、付けるのは「失敗しても本来の処理に関係ないステップ」だけにしています。

後片付けのステップの if: に always() を付けて直すこともできます。ただ、それだと投稿そのものが失敗したときにも posted/ へ移してしまうので、この作りには向いていないと思います。

確かめた環境

  • GitHub Actions(ubuntu-latest)
  • actions/upload-artifact@v4
  • 無料プラン(GitHub Free)の個人アカウント

まとめ

  • Artifact storage quota has been hit は、アカウント全体の Artifact(と Packages)のストレージが上限に達したときのエラー
  • 古い Artifact を消しても、使用量の再計算には6〜12時間かかる。今回は約6時間半後でもまだ保存できなかった
  • if: に状態を見る関数がないステップには success() が付くので、前のステップが1つ失敗するとスキップされる
  • デバッグ用の保存には continue-on-error: true を付けて、失敗してもジョブを止めないようにした
  • retention-days を指定しないと90日残るので、毎回保存するものは短くした

定期実行で Artifact を毎回保存しているワークフローがあれば、一度 retention-days と、後片付けのステップの if: を見ておくと安心かなと思います。

参考

GitHub Actions の「Artifact storage quota has been hit」の対処:古い Artifact の削除と continue-on-error・retention-days

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

エンジニア。Claude Code / Codex / MCP / BigQuery / 自動化 / ガジェット / 3Dプリンター / スマートホーム。楽して生きたい。ゲーム / イヤホン / キーボード / プログラミング / AI

目次