【実務・中級編】GitHub Actionsの実行時間を半分に!キャッシュ戦略とセルフホストランナーによるコスト削減術 – バージョン管理・CI/CD活用バイブル

CI/CDを「惰性」で回すな。GitHub Actionsの実行時間を半減させる極限チューニング術

「CIが終わらない」「月末にGitHubの請求額を見て震える」。もしあなたがそう感じているなら、それはCI/CDパイプラインが設計ミスを抱えている証拠だ。

GitHub Actionsは魔法の杖ではない。適切にコントロールしなければ、単なる「コストを吸い上げるブラックホール」と化す。今日は、大規模プロジェクトを牽引するテックリードとして、現場の生産性を劇的に向上させるための「最適化の極意」を伝授する。

—

1. `actions/cache` の真実:ただのキャッシュでは遅すぎる

多くのエンジニアは、とりあえず `actions/cache` を適当なパスで動かしている。これでは不十分だ。キャッシュのヒット率は「戦略」で決まる。

鍵は「不変性」と「粒度」

キャッシュキーを `os-node-${{ hashFiles(‘package-lock.json’) }}` のように大雑把に設定していないか? これでは依存関係が一つ変わるたびに全キャッシュが作り直される。

最適化の鉄則:

  • 階層化: 依存関係だけでなく、OSのバージョンやNode.jsのバージョンをプレフィックスに入れる。
  • リストア専用のジョブ: 巨大な依存関係がある場合、`setup` ジョブを分離し、キャッシュの復元だけを先行させる。

.github/workflows/ci.yml

  • name: Cache node_modules

uses: actions/cache@v3
with:
path: ~/.npm
# 変更頻度の高いものと低いものを分けるのがコツ
key: ${{ runner.os }}-node-${{ hashFiles(‘/package-lock.json’) }}
restore-keys: |
${{ runner.os }}-node-

—

2. セルフホストランナー(Self-hosted Runner)を導入すべき境界線

GitHub公式のランナーは手軽だが、大規模プロジェクトでは「遅い・高い・カスタマイズできない」の三重苦だ。

導入の判断基準

  • ビルド時間: 1ジョブあたり15分を超える(タイムアウトの恐怖から解放される必要がある)。
  • コンパイル負荷: GoやRustの巨大なリポジトリで、CPU/メモリのリソースが足りない。
  • ネットワーク: 社内VPNやプライベートサブネット内のリソースへアクセスする必要がある。

コスト削減のハック:Ephemeral Runners

`actions-runner-controller (ARC)` をKubernetes上に構築し、`ephemeral: true` を設定せよ。ジョブ完了後にランナーを破棄することで、無駄なアイドル時間をゼロにし、セキュリティリスクも最小化できる。

—

3. トリガーの「断捨離」と並列化の魔術

無駄なCI実行は、コストと開発者体験の両方を殺す。

トリガー制御のベストプラクティス

`paths` や `paths-ignore` を駆使し、ドキュメントの修正だけでCIが走るような愚行を止める。

on:
push:
branches: [main]
paths:

  • ‘src/’ # ソースコードの変更時のみ発火させる
  • ‘!docs/’ # ドキュメント変更時は無視

並列実行(Matrix Strategy)の極み

テストスイートを分割し、`strategy.matrix` で並列実行せよ。1時間かかるテストを4並列にすれば、理論上15分に短縮できる。

—

4. プロの隠し味:生産性を底上げするツールとルール

必須級の神ツール・設定

  • GitHub CLI (`gh`): `gh run watch` を使い、ターミナルから離れずにCIのログを監視せよ。ブラウザを開く時間は無駄だ。
  • nektos/act: ローカルでGitHub Actionsをエミュレートする。CIを回してから「あ、ミスった」と気づくフィードバックループを撲滅できる。
  • 設定の共有化ルール: 共通処理は `Composite Actions` として別リポジトリで管理せよ。全リポジトリに同じYAMLをコピペするのは、技術的負債をコピペしているのと同じだ。

現場で役立つYAMLの書き方

`env` コンテキストを使い、ジョブ全体で使い回す値は整理しておく。

env:
NODE_VERSION: ’18.x’
# キャッシュディレクトリの固定化
NPM_CONFIG_CACHE: ${{ github.workspace }}/.npm

—

5. 最後に:テックリードからの提言

CI/CDパイプラインは「動けばいい」ものではない。それはチームの心拍数だ。CIが遅ければ、開発者の思考は停止し、コンテキストスイッチが発生する。

1. 計測せよ: `gh run view –json duration` 等を使って、どのジョブがボトルネックか数値化せよ。
2. 自動化せよ: キャッシュのクリアやRunnerのスケーリングは手動でやるな。
3. 文化にせよ: 遅いパイプラインを「仕方ない」と思わない環境をチームで作れ。

今日からあなたのパイプラインの数値を一つずつ改善してほしい。その小さな積み重ねが、半年後にチーム全体の生産性を2倍、3倍に跳ね上げるはずだ。

さあ、エディタを開いて、まずは `actions/cache` のキー設定を見直すところから始めよう。健闘を祈る。

タイトルとURLをコピーしました