GitHub ActionsでCIを高速化する基本

中級 | 13分 で読める | 2026.06.27

公式ドキュメント

今回やること

この記事では、GitHub ActionsのCIを速くする基本を整理します。

CI高速化は、キャッシュ、並列化、不要な実行の削減、重複installの削減から始めると効果が出やすいです。

最初から高度なことをしなくても、設定を少し変えるだけで待ち時間はかなり減ります。

まず時間を測る

高速化の前に、どこで時間がかかっているかを見ます。

見る場所:

  • GitHub Actionsのjob一覧
  • 各stepの実行時間
  • install時間
  • lint/test/buildの時間
  • queue時間
  • 失敗してretryしているstep

「なんとなく遅い」ではなく、どのstepが遅いかを特定します。

setup-nodeのcacheを使う

Node.jsプロジェクトでは、依存関係のインストールが重くなりがちです。

- uses: actions/setup-node@v4
  with:
    node-version: 22
    cache: npm

- run: npm ci

cache: npm を使うと、npmのキャッシュを再利用できます。node_modules を直接キャッシュするより、npm ci とnpmキャッシュを組み合わせる方が安定しやすいです。

pnpmなら次のようにします。

- uses: pnpm/action-setup@v4
  with:
    version: 9

- uses: actions/setup-node@v4
  with:
    node-version: 22
    cache: pnpm

- run: pnpm install --frozen-lockfile

jobを分けて並列化する

1つのjobで全部を直列にすると、合計時間がそのまま待ち時間になります。

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - run: npm run lint
      - run: npm test
      - run: npm run build

独立しているなら、jobを分けます。

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm
      - run: npm ci
      - run: npm run lint

  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm
      - run: npm ci
      - run: npm test

  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm
      - run: npm ci
      - run: npm run build

runnerの起動やinstallが増えるため、必ず速くなるとは限りません。ただし、lint/test/buildが重い場合は並列化の効果が出やすいです。

古いCIをキャンセルする

PRに何度もpushすると、古いcommitのCIが走り続けることがあります。

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

これを入れると、同じブランチで新しいCIが始まったときに古い実行をキャンセルできます。

PR修正が多いプロジェクトでは効果があります。

pathsで不要なCIを止める

ドキュメントだけの変更でフルCIを回す必要がない場合があります。

on:
  pull_request:
    paths:
      - "src/**"
      - "package.json"
      - "package-lock.json"
      - "tsconfig.json"
      - ".github/workflows/ci.yml"

ただし、除外しすぎると必要なCIが動かない危険があります。設定ファイルやビルドに影響するファイルは忘れずに含めます。

installの重複を減らす

jobを分けると、各jobで npm ci が走ります。これは分かりやすい一方、install時間が増えます。

選択肢:

  • cacheを効かせて各jobでinstallする
  • 1つのjob内でstepを直列にする
  • build成果物だけartifactで渡す
  • monorepoなら変更パッケージだけ実行する

小さなプロジェクトでは、1job直列の方が速いこともあります。大きくなったら分割します。

artifactを使う

build成果物を後続jobで使うなら、artifactを使います。

- name: Upload build
  uses: actions/upload-artifact@v4
  with:
    name: dist
    path: dist/

後続job:

- name: Download build
  uses: actions/download-artifact@v4
  with:
    name: dist
    path: dist/

同じbuildを何度もやり直すより、成果物を渡した方が速く安定することがあります。

変更ファイルだけlintする

CI全体では全件lintが必要な場面もありますが、pre-commitや軽いPRチェックでは変更ファイルだけに絞ると速くなります。

例:

npx eslint $(git diff --name-only --diff-filter=ACMR origin/main...HEAD | grep -E '\\.(ts|tsx|js|jsx)$')

ただし、shellで複雑に書きすぎると保守しにくくなります。lint-stagedやLefthookなどのツールを使う方が扱いやすいことが多いです。

高速化のbefore/afterを書く

改善したら、READMEやPRに記録します。

## CI高速化

変更前:
- CI合計: 約8分
- install: 約2分
- lint/test/buildを1jobで直列実行

変更後:
- CI合計: 約4分
- setup-node cacheを追加
- concurrencyで古いCIをキャンセル
- lint/test/buildを分割

転職用ポートフォリオでは、この記録自体がアピールになります。

まとめ

GitHub Actionsの高速化は、まず基本からで十分です。

  • stepごとの時間を測る
  • setup-nodeのcacheを使う
  • 独立した処理を並列化する
  • concurrencyで古いCIをキャンセルする
  • pathsで不要なCIを減らす
  • installの重複を見直す
  • artifactで成果物を渡す
  • before/afterを記録する

CIは毎日使う開発基盤です。少し速くするだけでも、チーム全体には大きく効きます。

参考リソース

次に読む記事

← 一覧に戻る
PR
PR
PR
PR