GitHub Actions の CI コスト最適化: ブログ記事 PR 向け paths filter 設計
ブログ記事を自動生成していて、GitHub Actions(GitHub 上で処理を自動で動かす仕組み)の利用料が気になっている方向けの記事です。自動化が進んでブログ記事の生成頻度が増えると、CI(変更のたびにビルドやテストを自動で走らせる仕組み)の実行時間とコストが急に膨らみます。
特に記事だけを追加する PR(プルリクエスト:変更内容を取り込む前に確認するための依頼)では、コード変更向けの CI をすべて動かす必要はありません。そのため、条件をうまく分ければコストを大きく減らせます。
この記事では、ブログ記事 PR 向けに CI を絞り込む設計と、paths filter(変更されたファイルの場所によって処理を動かすかどうかを決める設定)を使った workflow(GitHub Actions で自動実行する処理のまとまり)の制御方法を、実例とともに解説します。
CI コスト問題の背景
自動生成ブログのコスト試算
analytics-note では、Issue(GitHub 上の課題管理チケット)からブログ記事を自動生成する仕組みを、org(GitHub の組織アカウント)配下の全リポジトリに広げました。その結果、1日10〜20件のペースで記事が生成される見込みとなりました。
1記事あたりの実測 CI 実行時間:
| workflow 種別 | 実行時間 | 用途 |
|---|---|---|
| 記事生成本体 | 3〜4分 | Claude による記事生成 |
| queue 検出・PR 作成 | 30秒 | 自動化パイプライン |
| ビルド検証・自動マージ | 1〜1.5分 | 品質担保 |
| PR 付随 CI | 3〜5分 | 最適化対象 |
| 合計 | 約8〜10分 |
月間コスト試算(GitHub Pro 3000分枠との比較):
- 10件/日 × 30日 = 約3000分(枠ギリギリ)
- 15件/日 × 30日 = 約4500分($12/月の超過)
- 20件/日 × 30日 = 約6000分($24/月の超過)
削減余地の特定
ブログ記事 PR は apps/site/src/content/blog/*.mdx ファイルの追加のみが想定されるため、以下の CI は不要です:
- コード品質チェック(lint:書き方の誤りを自動で検出するツール/test:動作確認の自動テスト)
- インフラ関連の検証
- 依存関係チェック
- セキュリティスキャン(一部を除く)
ただし、記事内容の機密情報漏洩チェックは維持する必要があります。
paths filter による workflow 最適化
基本的な paths filter パターン
GitHub Actions では、paths と paths-ignore で workflow の実行条件を制御できます:
# ブログ記事のみの変更では実行しない
on:
pull_request:
paths-ignore:
- 'apps/site/src/content/blog/**'
- '!apps/site/src/content/config.ts' # schema変更時は除外
条件分岐による細粒度制御
より柔軟に制御したい場合は、job(workflow の中で実行される個々の処理単位)ごとの条件分岐を組み合わせます。
jobs:
check_changes:
runs-on: ubuntu-latest
outputs:
blog_only: ${{ steps.changes.outputs.blog_only }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v2
id: changes
with:
filters: |
blog_only:
- 'apps/site/src/content/blog/**'
config:
- 'apps/site/src/content/config.ts'
lint:
needs: check_changes
if: needs.check_changes.outputs.blog_only != 'true'
runs-on: ubuntu-latest
# ... lint処理
セキュリティチェックの選択的実行
記事内容のセキュリティチェックは、対象ファイルを絞って継続実行します:
secret_scan:
needs: check_changes
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Scan secrets in blog content only
if: needs.check_changes.outputs.blog_only == 'true'
run: |
# MDXファイルのみをスキャン
secret-scan apps/site/src/content/blog/
- name: Full secret scan
if: needs.check_changes.outputs.blog_only != 'true'
run: |
# 全ファイルをスキャン
secret-scan .
実装時の注意点
1. 既存 PR への影響回避
paths filter の追加は既存の通常 PR に影響しないよう設計する必要があります:
- ブログ以外の変更では従来通り全 CI を実行
- 混在 PR(ブログ + コード変更)では安全側に倒して全 CI を実行
- テスト環境での十分な検証
2. 例外ケースの考慮
以下のケースでは通常の CI を実行する必要があります:
- frontmatter(記事冒頭に書くタイトルや日付などの情報)の schema(項目の形式を決めた定義)の変更(
config.tsの修正) - ビルドに影響するコンテンツ構造変更
- 新しい記事カテゴリの追加
3. モニタリングの継続
最適化後も CI の実行状況を継続的に監視します:
# 最近のworkflow実行時間を確認
gh run list --limit 20 --json conclusion,createdAt,durationMs
# ブログPRの平均実行時間を算出
gh pr list --label "feat(blog)" --state merged \
--json number,title,mergedAt --jq '.[].number' | \
xargs -I {} gh pr view {} --json statusCheckRollup
削減効果の測定
Before/After 比較
最適化前後での実行時間比較:
| 項目 | 最適化前 | 最適化後 | 削減率 |
|---|---|---|---|
| ブログ PR 実行時間 | 8〜10分 | 4〜6分 | 40〜50% |
| 月間 Actions 分数 | 4500分 | 2700分 | 40% |
| 超過コスト | $12/月 | $0/月 | 100% |
継続的な改善
CI 最適化は一度で終わりではなく、workflow の追加や変更に合わせて継続的に見直す必要があります:
- 新しい workflow 追加時の paths filter 設定チェック
- ブログ記事の構造変更時の条件見直し
- Actions 実行時間の定期的なレビュー
まとめ
- 記事だけを追加する PR では、コード変更向けの lint やテストを動かす必要がありません。
pathsとpaths-ignoreで実行条件を絞ると、CI の実行時間と料金を減らせます。 - 絞り込むときも、記事の内容に機密情報が混ざっていないかの検査は、対象ファイルを絞って残します。
- ブログとコードの変更が混ざった PR は安全側に倒して全部の CI を動かし、frontmatter の schema を変えたときも通常の CI を通します。
関連記事
- GitHub Project と Workflows の連携による開発自動化 — GitHub Actions の基本的な自動化パターン
- AI ブログ記事生成の品質ゲート設計と CI 検証 — ブログ記事の品質担保における CI の役割
この記事のもとになった記録
この記事は、筆者の作業記録「perf(ci): blog PR 向けに Actions 分数を絞る(paths filter / skip 条件)」をもとに書いています。この記録は非公開のため、リンクは付けていません。
更新履歴
- 2026-11-02: 定期点検で、本文の12か所を直しました。