-- Views
September 30, 26
スライド概要
Zennで書いた記事のダイジェスト版です。
▼E2EをCIで回してGitHub Actionsの無料枠を月初の3日で使い切った話
https://zenn.dev/unsoluble_sugar/articles/github-actions-e2e-free-tier
フルオタクエンジニア
T E C H TA L K E2EをCIで回して GitHub Actionsの無料枠を 月初3日で使い切った話 〜「並列で速い」は「安い」ではなかった〜 2026/09/30 @unsoluble_sugar
今日話すこと 1 何が起きたか 2 料金がどう決まるか 3 使った時間を計測する 4 対策と、その後の考え方 2
注目ポイント3つ CI: コードを直すたびに、自動でテストを走らせてくれる仕組み E2Eテスト: 実際にブラウザを動かして、画面の操作が壊れていないか確かめるテスト ジョブ: CIの中で動く作業のひとかたまり。料金はこのジョブごとに数えられる 今日の話を一言で: このジョブの数え方を知らずにCIを組んだら、無料枠が3日で消えた 3
CHAPTER 01 何が起きたか
月初3日間の実績 139 回 2,777 分 93 % CIが動いた回数 料金として数えられた時間 無料枠3,000分に対する割合 個人で作っているブラウザゲーム集。3日間で514個のジョブが動いた 金額に直すと$16.66ぶん。上限を設定していたので実際の請求は$0だった 5
気づいたきっかけは90%アラートメール 9月4日、GitHubから「無料枠の90%を 使った」という通知が届く 使用量を見ると 2,703 / 3,000分 設定ファイルを眺めても、どこで使って いるのか分からない 使用量が90%に達したBilling画面 6
使用量の詳細はアカウント設定から確認できる Settings → Billing and licensing → Overview → Metered usage → Actions リポジトリごとの使用量も出てくる リポジトリごとの内訳まで確認できる 7
日ごとの減り方 日 使った分数 金額換算 9/2 471 $2.83 9/3 1,299 $7.79 9/4 1,007 $6.04 合計 2,777 $16.66 このペースが続くと: 月およそ27,800分。 上限を外していたら月 約$149 の請求 8
CHAPTER 02 作っていたものと CIの組み方
作っていたアプリ ブラウザで遊ぶミニゲーム集。作ったも のを置くだけの素朴な作り Firebase Hostingで公開。スマホにアプ リとして入れることもできる(PWA) 音や保存など共通の仕組みを1つにまと め、ゲームのルールは切り離してある 開発中のゲームたち 10
用意していたテスト 種類 中身 かかる時間 ユニットテスト 小さな単位で動作を確認 392件 数十秒 E2Eテスト 実際にブラウザを操作して確認 433件(PC+スマホ) 約3分 コードのルール確認 書き方が決めたルールに沿っているか 数秒 11
問題が起きたときのCIの組み方 変更を提出するたび、本番に取り込むたびに、毎回すべてのテストを実行 E2Eは待ち時間を縮めるため、6つに分けて同時に走らせていた 取り込み時には、さらにSafari系とFirefoxでの確認も追加 目標は「待ち時間5分前後」。速さだけを見て組んだ構成だった 12
CHAPTER 03 料金がどう決まるか
料金は「ジョブごとに1分単位」で数える 公開リポジトリは無料。非公開は月3,000分の無料枠から減っていく 動かすOSで倍率が変わる。Linuxは1分=1分、Windowsは2倍、macOSは10倍 1つのジョブが1分10秒で終わっても2分として数え、それを全ジョブぶん足す 分けて同時に走らせるほど、切り上げのムダと毎回の準備時間がジョブの数だけ増える ここが罠: 「待ち時間が短いこと」と「料金が安いこと」はまったく別の話 14
CHAPTER 04 使った時間を 計測する
実際の実行時間をAPIで集計する
月以降の実行を列挙
# 9
gh api --paginate "repos/<owner>/<repo>/actions/runs?created=>=2026-09-01" \
-q '.workflow_runs[] | "\(.id)\t\(.event)"'
#
実行ごとのジョブ時間(秒)
gh api "repos/<owner>/<repo>/actions/runs/<id>/jobs" \
-q '.jobs[] | "\(.name)\t\((.completed_at|fromdateiso8601) - (.started_at|fromdateiso8601))"'
ポイント: 設定ファイルを読むだけでは分からない。実際に何分動いたかを1件ずつ計測す
る
16
何にいちばん使っていたか ジョブの種類 使った分数 割合 E2Eテスト(6分割 × PC・スマホ) 1,467 58% 事前チェック(コードのルール確認・ユニットテスト) 858 34% Safari系・Firefoxでの確認 174 7% 17
変更1回あたりの内訳(実測) ジョブ 時間 中身 事前チェック 3.0分 コード取得 → 準備 → コードのルール確認 → ユニットテスト E2E 1〜6 4.9〜10.3分 6つとも、コード取得とブラウザ準備(約1.5分)からやり直す 合計 約45分 画面で見える待ち時間は10分ほど 本番に取り込むときはさらにSafari系・Firefoxの確認が加わり、1回55〜65分 18
原因は5つの掛け算だった 倍率 中身 ×2 提出時と取り込み時の2回実行(手元も含めると実質3回) ×6 6つに分割。準備1.5分と切り上げのムダがジョブの数だけ増える ×2 PC版とスマホ版で2回。半分は同じ内容の確認 ×139回 AIエージェントが自動で進めるので1日46回。人の手なら数回 +174分 月に数回で足りるSafari系・Firefoxの確認を毎回実行 19
「並列で速い」は 「安い」ではない 待ち時間を16分→5分に縮めた代わりに、料金は10分→45分に増えていた 20
CHAPTER 05 対策
手をつける順番 効果:大 動かす場面を減らす → 効果:中 分け方を数え方に合わせる → 効果:小〜中 速くするのは最後 順番が大事: 高速化から手をつけても、料金が膨らむ構造はそのまま残る 22
1 そもそも動かす場面を減らす E2EをCIから外して手元に移した。CIはコードのルール確認とユニットテストだけ E2Eは1つのコマンドにまとめ、手元から送る直前に自動で走るようにした 急いでいるときは環境変数を付けて飛ばせる逃げ道も用意 Gitの標準機能だけで実現しているので、追加のパッケージはいらない 23
設定ファイルで起動条件を絞る
1
on:
pull_request:
paths-ignore: ["**/*.md", "docs/**", ".claude/**"]
push:
branches: [main]
paths-ignore: ["**/*.md", "docs/**", ".claude/**"]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
効果: 文章だけの変更ではCIを動かさない。続けて送ったときは前の実行を自動で打ち切る
24
2 分け方を料金の数え方に合わせる E2Eは、必要なときだけ手動で動かす形に変更 6分割をやめ、分けるのは本当に必要な場面だけに限定 Safari系・Firefoxの確認も手動実行にまとめた 準備1.5分×6と、切り上げのムダ×6がまるごと消える 25
3 速くするのは最後 変更内容を見て、E2Eの対象を絞り込むスクリプトを用意した ゲーム1本だけ直したとき → そのゲームのテストだけ(1〜2分) 文章やユニットテストだけ直したとき → E2Eは0分 共通部分やデザインを直したとき → 全部実行(約3分) 判断がつかないときは、安全側に倒して全部実行 26
対策前と対策後 場面 変更前 変更後 変更を提出・更新 事前チェック+E2E6分割 = 34〜51分 事前チェックのみ = 2〜6分 本番に取り込む +Safari系・Firefox = 55〜65分 事前チェックのみ = 2〜6分 文章だけの変更 同上 CIを動かさない = 0分 E2E CIで毎回すべて 手元で変更部分だけ(0〜2分) 1回の取り込みが約100分 → 4〜12分。残り223分でこなせる回数は約2回→18〜55回 27
対策後のCI実行結果 28
見送った案と理由 分割を6個から2個に減らす 自前のマシンで動かす → それでも1回60分ほど残り、足りない → 無料だが、管理の手間が個人開発には重い リポジトリを公開する 翌月のリセットを待つ → 効果は最大だが、非公開の方針を優先 → 26日間もCIなしで進めるのは無理がある 29
同じことを繰り返さないために 実行ごとの分数を、いつでも集計できる状態にしておく 設定ファイルの冒頭に方針をコメントで残す(料金はジョブの合計、E2Eは手元で) AIエージェント向けのルールにも、同じ方針を書いておく 1回の取り込みは4〜12分が目安。10分を超えたら構成を疑う 30
つまずきポイント 「並列で速い」=「安い」ではない 自分の集計と請求がズレる → 待ち時間と料金は別の指標として見る → ジョブごとの切り上げで2,518分が2,777分に CIでだけ失敗する 途中で止めても料金はかかる → 環境の違いで「CIで確認」の往復が増える → 走った分は課金される。まとめて送るのが先 31
まとめ 料金はジョブごとに切り上げて合計。分 1 けて同時に走らせるほど増える 2 原因は倍率の掛け算。実行時間を計測し て初めて見えた AIエージェント時代は「1日何回動くか」 3 でCIを設計する 4 動かす場面を減らすのが最優先。結果、1 回約100分が4〜12分に 32
参考 元記事: E2EをCIで回してGitHub Actionsの無料枠を月初の3日 で使い切った話 zenn.dev/unsoluble_sugar/articles/github-actions-e2e-free-tier GitHub Actions の課金について(GitHub Docs) docs.github.com/ja/billing/.../about-billing-for-github-actions 33