actions-ci-tuning について
GitHub Actionsのワークフローを監査・改善するスキルで、CIを保守する開発チーム向けです。正確性を優先し、キャッシュ、並列テスト、成果物の保護、信頼性やセキュリティ設定を確認して、最小限の変更を提案します。
主な機能
- 01ワークフローと実行時間の棚卸し
- 02依存関係のキャッシュとインストール確認
- 03並列ジョブとテスト分割のレビュー
- 04レポート成果物のマージ保護
- 05同時実行、トリガー、バージョン固定の確認
活用シーン
- 01CIの失敗や遅延の診断
- 02Playwrightのテスト分割とレポートの調整
- 03キャッシュミスやロックファイルのずれの抑制
- 04GitHub Actionsのセキュリティ設定のレビュー
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mizchi/ skills --skill actions-ci-tuningインストール後、Claude Code で/actions-ci-tuningを入力して読み込まれたか確認します。
同梱ファイルREADME.md
詳細
GitHub Actions CI のチューニング
GitHub Actions ワークフローを監査し、改善します。まず正確性(失敗ではなくエラーになるジョブ)、次に速度(キャッシュ、並列処理)、最後に信頼性(不安定な動作、アーティファクトのガード)に重点を置きます。
ワークフロー
- 一覧の作成 — すべての
.github/workflows/*.ymlファイルと、そのトリガーイベント、ジョブ、おおよその実行時間を一覧にします(gh run list --workflow <file> --limit 5)。 - チェックリストに照らして監査 — 以下の各セクションを確認し、すべての不足点にフラグを立てます。
- 優先順位付け — 調査結果を影響度別に分類します:正確性のバグ > キャッシュミス > 並列化による改善 > 見た目の問題。
- 変更の提案 — 最小限の差分を作成します。無関係な部分はリファクタリングしないでください。
- 検証 — 適用後、
gh run listで次の実行が成功し、より速くなったことを確認します。
チェックリスト
パッケージマネージャーのキャッシュ
キャッシュミスが起きると、実行のたびに数百個のパッケージを再ダウンロードすることになります。ほとんどのリポジトリで、これは最も費用対効果の高い改善です。
pnpm
- uses: pnpm/action-setup@v6
with:
version: latest # or pin to a specific version
- uses: actions/setup-node@v7
with:
node-version-file: .nvmrc # or node-version: '24' (current LTS)
cache: 'pnpm' # ← must be present; omitting it silently skips caching
よくある間違い:pnpm/action-setup の代わりに corepack enable を呼び出すことです。corepack enable では pnpm ストアのキャッシュは設定されません。actions/setup-node cache: 'pnpm' を使用するには、先に pnpm/action-setup を実行しておく必要があります。
npm
- uses: actions/setup-node@v7
with:
node-version-file: .nvmrc
cache: 'npm'
yarn(classic / berry)
- uses: actions/setup-node@v7
with:
node-version-file: .nvmrc
cache: 'yarn'
キャッシュの動作確認:setup-node のログで Cache restored successfully を探します。表示されない場合は、cache: キーが指定されていないか、ロックファイルのパスが正しくない可能性があります。
依存関係のインストール
- CI では必ず
--frozen-lockfile(pnpm)/--ci(npm)/--immutable(yarn berry)を使用します。これにより、ロックファイルのずれによってインストールされる依存関係ツリーが暗黙に変わるのを防げます。 - CI では、凍結フラグを付けずに
npm installやpnpm installを使用しないでください。
ジョブとステップの並列実行
- 独立したジョブ(lint、typecheck、test)は、逐次実行ではなく並列実行できるよう、個別のジョブにします。
- 逐次実行するステップは、1 つのジョブ内でのセットアップ(インストール → ビルド → テスト)には適しています。
- lint、typecheck、unit test のすべてが 1 つのジョブに含まれているリポジトリでは、分割してください。
jobs:
lint:
runs-on: ubuntu-latest
steps: [checkout, setup, install, run lint]
typecheck:
runs-on: ubuntu-latest
steps: [checkout, setup, install, run typecheck]
test:
runs-on: ubuntu-latest
steps: [checkout, setup, install, run test]
テストのシャーディング(Playwright / Vitest)
長時間かかるテストスイートを短縮するには、シャーディングを使用します。各シャードはテストの一部を並列に実行します。
Playwright の例 — 4 シャード:
jobs:
e2e:
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4]
steps:
- run: pnpm exec playwright test --shard=${{ matrix.shard }}/4
env:
CI: true
- uses: actions/upload-artifact@v7
if: ${{ !cancelled() }} # ← upload even on test failure
with:
name: blob-report-${{ matrix.shard }}
path: blob-report/
retention-days: 1
注意点:
fail-fast: falseは必須です。設定しないと、1 つのシャードが失敗した時点で残りのシャードがキャンセルされ、blob レポートをアップロードできなくなります。- アップロードステップに
if: ${{ !cancelled() }}を指定すると、テストが失敗しても blob レポートがアップロードされます。指定しない場合、merge-reports ジョブにアーティファクトが渡されません。
merge-reports のアーティファクトガード
シャードが blob レポートをアップロードする前に失敗すると、all-blob-reports ディレクトリが存在しない場合があります。マージコマンドにガードを設定してください。
- name: Merge reports
run: |
if [ -d all-blob-reports ] && [ "$(ls -A all-blob-reports 2>/dev/null)" ]; then
pnpm exec playwright merge-reports --reporter=html ./all-blob-reports
else
echo "No blob reports found, skipping merge"
mkdir -p playwright-report
echo "<html><body><p>No test results available</p></body></html>" > playwright-report/index.html
fi
このガードがないと、ワークフロー全体として「結果なし」と適切に報告すべき場合でも、merge-reports ジョブは Error: Directory does not exist: ./all-blob-reports でエラーになります。
Playwright Docker イメージ
VRT(Visual Regression Testing)では、スナップショットを CI と同じ環境(Linux + 特定のフォント)で生成する必要があります。通常の node:* イメージではなく、公式の Playwright Docker イメージを使用してください。
mcr.microsoft.com/playwright:v1.59.1-noble # pin to the same version as @playwright/test
node:24 を使用しない理由
node:24ではplaywright install --with-deps chromiumが必要です。これによりapt-getが実行され、Docker Desktop の macOS 環境では、QEMU エミュレーション環境での apt に関する既知の問題により、処理が何時間も停止することがあります。mcr.microsoft.com/playwrightイメージには Chromium とすべてのシステム依存関係がプリインストールされているため、apt-get は不要で、数秒で起動します。
バージョンの固定:イメージのバージョンを package.json の @playwright/test と同期させてください。不一致があると、ブラウザーが見つからないエラーが発生します。
同時実行の制御
同じブランチ/PR で進行中の実行をキャンセルし、キューがたまるのを防ぎます。
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
例外:main 上のリリース/デプロイのワークフローはキャンセルしないでください。PR ブランチだけを対象にします。
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
スケジュールされたワークフローの信頼性
- GitHub Actions のスケジュールされたワークフローは、リポジトリに 60 日間アクティビティがないと、通知なく実行されなくなることがあります。
schedule:とあわせてworkflow_dispatch:トリガーを追加すると、コードを変更せずに手動で再実行できます。- 重要なスケジュールジョブ(例:夜間の E2E)には、失敗通知ステップ(GitHub の Issue 作成、Slack など)を追加し、通知なく失敗した場合も把握できるようにします。
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch: # ← always add this
アクションのバージョン固定
- サードパーティ製アクションはタグではなく、完全なコミット SHA に固定します。タグは移動される可能性があります。
- 読みやすさのため、人が判読できるバージョンをコメントに記載します。
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- Dependabot または Renovate を使うと、SHA の固定を自動的に最新の状態に保てます。
.github/dependabot.ymlにgithub-actionsエコシステムが含まれていることを確認してください。
Node.js 20 の非推奨に関する警告:GitHub は 2025/2026 年に「Node.js 20 actions are deprecated」という警告を発し始めました。これはプロジェクトの Node のバージョンではなく、アクション自体のランタイム(runs.using: node20)を指します。node24 を使用する最初のメジャーバージョンにアップグレードして修正します。
| アクション | node24 を使用する最初のメジャーバージョン | 現在のメジャーバージョン(2026-09) |
|---|---|---|
actions/checkout | v6.0.0 | v7 |
actions/setup-node | v6.0.0 | v7 |
actions/cache | v5.0.0 | v6 |
actions/upload-artifact | v7.0.0 | v7 |
actions/download-artifact | v8.0.0 | v8 |
aws-actions/configure-aws-credentials | v6.0.0 | v6 |
最新の固定 SHA(2026-09 に確認):
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c # v6.2.4
注:SHA は変わるため、固定する前に必ず gh release view --repo <owner>/<action> で確認してください。
環境変数
CI: trueは個々の run ステップだけでなく、ジョブまたはワークフローのレベルで設定してください。多くのツール(Playwright、Vite など)は、このフラグに応じて動作を変更します。- シークレットには
${{ secrets.NAME }}を使用し、トークンを直接ハードコードしないでください。 - 制約のあるランナーで大規模なビルドを行う場合、
NODE_OPTIONS: --max-old-space-size=4096が必要になることがあります(7 GB のランナーのデフォルトのヒープは約 1.5 GB です)。
すぐに実行できる監査コマンド
# List recent run durations for a workflow
gh run list --workflow e2e.yml --limit 10 --json databaseId,displayTitle,createdAt,updatedAt,conclusion \
| jq '.[] | {title: .displayTitle, duration: (.updatedAt | fromdate) - (.createdAt | fromdate), conclusion: .conclusion}'
# Find jobs that always time out
gh run list --workflow e2e.yml --status failure --limit 20 --json databaseId \
| jq -r '.[].databaseId' \
| xargs -I{} gh run view {} --json jobs \
| jq '.jobs[] | select(.conclusion == "timed_out") | .name'
# Check cache usage in a run
gh run view <run_id> --log | grep -i "cache"
よくあるアンチパターン
| アンチパターン | 問題 | 修正方法 |
|---|---|---|
corepack enable のみ(pnpm/action-setup なし) | pnpm ストアがキャッシュされません | setup-node の前に pnpm/action-setup@v6 を追加します |
--frozen-lockfile を付けずに pnpm install を実行する | ロックファイルが通知なく変わる可能性があります | CI では常に --frozen-lockfile を使用します |
テストマトリックスで fail-fast: true を設定する | アーティファクトをアップロードする前にシャードがキャンセルされます | fail-fast: false を設定します |
if: ${{ !cancelled() }} なしでアーティファクトをアップロードする | テスト失敗時に Blob レポートが失われます | if 条件を追加します |
ディレクトリの存在確認なしで playwright merge-reports を実行する | シャードからアップロードされたものがない場合、ジョブがエラーになります | [ -d all-blob-reports ] のチェックを追加します |
Playwright VRT に node:* イメージを使用する | macOS の Docker Desktop で apt-get がハングします | mcr.microsoft.com/playwright イメージを使用します |
workflow_dispatch のないスケジュールワークフロー | 手動で再実行できません | 必ず workflow_dispatch: を追加します |
| SHA ではなくタグに固定されたアクション | タグは移動される可能性があります(サプライチェーンリスク) | 完全なコミット SHA に固定します |