【入門編】CI環境を爆速化!GitHub Actionsの「キャッシュ」を最大限に活用してビルド時間を50%短縮する – バージョン管理・CI/CD活用バイブル

こんにちは。現場の最前線でコードを書き、パイプラインの待ち時間にコーヒーを淹れる暇も惜しんでいる皆さん。

CI/CDのパイプラインが「遅い」というのは、エンジニアにとって最大のストレスですよね。ビルドが完了するのを眺めている時間は、生産性がゼロになるだけでなく、開発者の集中力を削ぐ最大の要因です。

今回は、GitHub Actionsの標準機能である`actions/cache`を使い倒し、「ビルド時間を物理的に半分以下にする」ための極限のキャッシュ戦略を伝授します。単なるマニュアルの焼き直しではありません。現場で明日からすぐに使える、実践的な最適化の技術です。

—

1. なぜ「キャッシュ」がビルドを劇的に速くするのか?

GitHub Actionsは、ジョブが走るたびに「クリーンな仮想環境」を一から構築します。つまり、`npm install`や`pip install`で毎回インターネットの海から数千個のライブラリをダウンロードしているのです。

キャッシュの役割は、「過去の遺産を再利用すること」です。
特定のディレクトリ(`node_modules`や`~/.cache/pip`など)を保存し、次回以降の実行時に「ダウンロード済み」の状態からスタートさせる。これだけで、ネットワーク通信のオーバーヘッドをほぼゼロにできます。

—

2. まずはここから!キャッシュ設定の「黄金律」

`actions/cache`を使う際の最も重要なポイントは、「何をキーにするか(Cache Key)」です。

  • name: Cache dependencies

uses: actions/cache@v3
with:
# キャッシュ対象のディレクトリ
path: ~/.npm
# キーが同じならキャッシュがヒットする
key: ${{ runner.os }}-node-${{ hashFiles(‘/package-lock.json’) }}
# キーが不一致の際、過去のキャッシュから部分一致で復元する(重要!)
restore-keys: |
${{ runner.os }}-node-

なぜこの設定が「最強」なのか?

  • `hashFiles`の魔法: `package-lock.json`(または`yarn.lock`)の中身が変わった時だけ、キャッシュを無効化します。これにより、ライブラリの追加・更新時だけ再インストールを行い、それ以外は爆速でパスします。
  • `restore-keys`の活用: 仮にロックファイルが変更されても、直前のキャッシュをベースにすれば差分更新だけで済みます。ゼロからやり直す必要はありません。

—

3. 言語別・現場で愛用される最適化テンプレート

それぞれの言語環境で、「どこをキャッシュすべきか」を迷う必要はありません。以下の設定が、最もヒット率が高く安定する「定番」です。

Node.js (npm/yarn)

  • name: Cache node_modules

uses: actions/cache@v3
with:
path: ~/.npm # npmのキャッシュディレクトリを指定
key: ${{ runner.os }}-node-${{ hashFiles(‘/package-lock.json’) }}

Python (pip)

  • name: Cache pip

uses: actions/cache@v3
with:
path: ~/.cache/pip # pipのデフォルトキャッシュ場所
key: ${{ runner.os }}-pip-${{ hashFiles(‘/requirements.txt’) }}

—

4. キャッシュヒット率を上げるための「極意」

キャッシュを導入しても、「なぜかヒットしない」という事態に陥ることがあります。以下の3点を守るだけで、ヒット率は劇的に向上します。

1. ディレクトリを絞り込む: 大量にゴミが含まれるプロジェクトルート全体をキャッシュしてはいけません。必ずパッケージマネージャが利用する「専用のキャッシュディレクトリ」をピンポイントで指定してください。
2. キーをシンプルに保つ: OS名、パッケージマネージャの種類、ロックファイルのハッシュ値。この3つで十分です。キーに複雑な情報を詰め込むと、わずかな環境差でヒットしなくなります。
3. CIの実行フローを統一する: プロジェクト内で複数のWorkflowがある場合、`path`や`key`の形式を揃えておくと、プロジェクト全体でのキャッシュの再利用性が高まります。

—

5. HelloWorld的実装:まずはここから試そう

まずは、あなたのリポジトリの `.github/workflows/main.yml` に以下のステップを追加してみてください。

jobs:
build:
runs-on: ubuntu-latest
steps:

  • uses: actions/checkout@v3
  • name: Setup Node.js

uses: actions/setup-node@v3
with:
node-version: ’18’
# ※実は setup-node はキャッシュ機能を内蔵しています!
cache: ‘npm’

  • name: Install dependencies

run: npm ci # –frozen-lockfile と同義。CIでは必ずciコマンドを!

先輩エンジニアからのアドバイス:
実は、`actions/setup-node`や`actions/setup-python`などの公式ツールには、すでに`cache: ‘npm’`のようなオプションが用意されています。まずはこれを利用し、より複雑なキャッシュ制御が必要になった段階で`actions/cache`を直接触るのが、最も効率的かつ安全な道です。

—

最後に

CIの待ち時間は、あなたの「思考のコンテキスト」を破壊します。キャッシュを最適化し、ビルドを爆速にすることは、単なる効率化ではなく、あなた自身の集中力を守り、最高のプロダクトを作るための環境投資です。

今日からこの設定を取り入れて、ビルド完了の通知が来る前に「お茶を淹れる時間」を削り、その分、少しだけコードの品質を高めることに時間を使ってみてください。

何か詰まったら、いつでも聞いてくださいね。一緒に最強のパイプラインを作り上げましょう!

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