GitHub Actionsを使いこなせているか
GitHub Actionsでyamlを書いてテストとデプロイを自動化しているチームは多い。しかし、ビルド時間が20分を超えている、似たようなワークフロー定義がリポジトリ間で重複している、GPUが必要なMLパイプラインを回せない—こうした課題を抱えているなら、GitHub Actionsの高度な機能を活用しきれていない可能性が高い。
KGAでは全プロジェクト(20以上のリポジトリ)でGitHub Actionsを運用しており、年間のCI/CD実行回数は約15万回。この規模で培ったノウハウを共有する。
マトリックスビルドの最適化
マトリックス戦略は複数の環境・バージョンの組み合わせを並列テストする機能だ。Node.js 18/20/22 × OS (ubuntu/macos/windows) × DB (postgres 15/16/17) のような組み合わせを自動展開できる。
しかし素朴にマトリックスを展開すると、3×3×3=27ジョブが生成される。すべてが必要とは限らない。KGAではinclude/excludeを活用し、本当に必要な組み合わせのみをテストする。例えばWindowsではPostgres 15のテストのみ、macOSではNode.js 22のテストのみ、といった絞り込みで27ジョブを12ジョブに削減した。
fail-fastをfalseに設定するのも重要だ。デフォルトでは1つのジョブが失敗すると他のマトリックスジョブもキャンセルされるが、全組み合わせの結果を知りたい場合はfalse設定が適切。逆にPRのチェックでは早期失敗の方が開発者体験が良い場合もある。
再利用可能ワークフロー(Reusable Workflows)
KGAの20以上のリポジトリで共通のCI/CDパターンを再利用するため、.github/workflowsの共通ワークフローを専用リポジトリ(kga-org/ci-workflows)に集約している。
各リポジトリからはworkflow_callで呼び出す。パラメータとしてNode.jsバージョン、デプロイ先環境、テストコマンド等をinputsで渡す。共通ワークフローのバージョニングはgit tagで管理し、安定版のタグ(v2等)を参照する。
この集約により、セキュリティパッチの適用(例: actions/checkoutの脆弱性対応)が1箇所の変更で全リポジトリに反映される。以前は20リポジトリを個別に更新する作業が発生していた。
キャッシュ戦略で実行時間を半減
GitHub Actionsのactions/cacheは強力だが、キャッシュキーの設計が甘いと効果が半減する。KGAのキャッシュ設計原則を共有する。
node_modulesのキャッシュ: キーにpackage-lock.jsonのハッシュを含める。OS名も含めること(ネイティブモジュールのバイナリが異なるため)。restore-keysでプレフィックスマッチのフォールバックを設定し、lockファイルの微小変更でもキャッシュを部分的に再利用する。
Dockerレイヤーキャッシュ: docker/build-push-actionのcache-fromとcache-toオプションでGitHub Container Registryをキャッシュバックエンドに使う。マルチステージビルドの各ステージがキャッシュされ、変更のないステージはスキップされる。KGAの大きなDockerイメージ(2GB超)のビルドが15分から3分に短縮された。
Terraformプロバイダのキャッシュ: .terraform/providers/ディレクトリをキャッシュし、terraform initの実行時間を60秒から5秒に短縮。
Self-hosted Runnersの構築
GPU付きのMLパイプラインやarm64ビルドなど、GitHub-hostedランナーでは対応できないワークロードにはSelf-hosted Runnersが必要だ。KGAではAWS EC2上にSelf-hosted Runners群を構築し、actions-runner-controllerでKubernetes上にオートスケーリングするランナーを運用している。
ランナーの構成として、ML学習ジョブ用にg5.xlarge(A10G GPU)、一般ビルド用にm7i.xlarge、arm64ビルド用にm7g.xlargeの3種類を用意。runsOnラベルで使い分ける。
セキュリティの観点では、Self-hosted Runnersはephemeral mode(ジョブ終了後にランナーを破棄)で運用することを強く推奨する。永続ランナーでは前のジョブの痕跡が残り、secret漏洩やビルド汚染のリスクがある。KGAではジョブごとに新しいPodを起動し、完了後に削除するパターンを採用している。
セキュリティのベストプラクティス
GitHub Actionsのセキュリティ脆弱性は攻撃者にとって魅力的なターゲットだ。KGAで徹底しているルールを共有する。
サードパーティActionsはコミットSHA指定で固定する(@v4ではなく@abc123def...のフルSHA)。タグは後から変更可能で、サプライチェーン攻撃のリスクがある。
GITHUB_TOKENの権限はpermissionsで最小限に設定する。デフォルトのwrite-allは危険だ。contents: read、pull-requests: writeなど必要な権限のみを明示。
PRからのワークフロー実行ではpull_request_targetの使用に注意。外部PRからのコード実行がリポジトリのsecretにアクセスできてしまう。KGAでは外部コントリビューターからのPRは手動承認を必須としている。
実行時間の計測と最適化
KGAではワークフローの実行時間をDatadogにメトリクスとして送信し、ダッシュボードで可視化している。P50/P90/P99の実行時間、キャッシュヒット率、失敗率をモニタリングし、劣化を早期に検知する。
この可視化により、あるリポジトリのCIが3日前から50%遅くなっていることを発見し、原因がnpmパッケージの追加によるキャッシュミスだったことを特定した例がある。キャッシュキーの調整で即座に改善できた。CIの速度は開発者体験に直結するため、パフォーマンスの計測と最適化は継続的に行うべきだ。