GitHub Actions CI ビルドマトリックスガイド
.github/workflows/docker-build-matrix.yml ワークフロー(docker-build-matrix.yml)を使用して、
4つの Docker ビルドモード(source/wheel/cython/nuitka)を自動的にビルド・テストします。
目次
ワークフロー概要
このワークフローは以下を実行します:
- マトリックスビルド: 4つのモード(source/wheel/cython/nuitka)を並列にビルド
- ポストビルドテスト: 各モードごとに適切な検証
- 成功通知: すべてのビルドが完了したら報告
Trigger (PR/Push)
↓
├─→ Build mode: source → Test source imports
├─→ Build mode: wheel → Test wheel imports
├─→ Build mode: cython → Test cython imports
└─→ Build mode: nuitka → Test binary existence
All complete → ✅ Success / ❌ Failure
実行時間
- 全モード初回: 60~80 分(各モード 15~50 分)
- キャッシュ有効時: 30~40 分(Docker レイヤーキャッシュ活用)
- 並列実行: マトリックスにより 4 つのジョブが同時実行
リソース使用量
- CPU コア: 4 個並列(GitHub Actions ランナー)
- ディスク容量: 各ジョブ 50GB 必要
- 実行時間制限: 360 分/ジョブ(GitHub Actions デフォルト)
ワークフロー構成
ファイル位置
.github/
├── workflows/
│ └── docker-build-matrix.yml ← このワークフロー
ワークフロー定義(概要)
name: Docker Build Matrix
on:
push:
branches: [main, develop]
paths:
- Dockerfile
- scripts/protect_with_cython.py
- scripts/build_nuitka_api_binary.py
- README.md
- README.ja.md
- pyproject.toml
- .github/workflows/docker-build-matrix.yml
pull_request:
branches: [main]
jobs:
build-matrix:
runs-on: ubuntu-latest
strategy:
matrix:
mode: [source, wheel, cython, nuitka]
fail-fast: false # 1つのモード失敗でも他のモードは継続
steps:
# ... 各ステップは以下で詳述
トリガー条件
アクティベーション条件
このワークフローは以下の場合に実行されます:
| トリガー | 対象 | 実行条件 |
|---|---|---|
| push | main/develop ブランチ | Dockerfile など関連ファイル変更時 |
| pull_request | main ブランチ | PR 作成・更新時 |
| manual | 任意 | GitHub Actions UI から手動実行 |
パス指定(自動フィルタ)
paths:
- Dockerfile # メイン Dockerfile 変更時
- scripts/protect_* # Cython/Nuitka スクリプト変更時
- README.md # README ドキュメント変更時
- pyproject.toml # パッケージ定義変更時
- .github/workflows/* # ワークフロー定義自体の変更時
手動実行
GitHub UI から手動トリガー:
Actions → Docker Build Matrix → Run workflow → Branch: main → Run
マトリックス設定
4つのビルドモード定義
strategy:
matrix:
mode: [source, wheel, cython, nuitka]
include:
- mode: source
target: runtime
tag_suffix: latest
- mode: wheel
target: runtime-wheel
tag_suffix: wheel
- mode: cython
target: runtime-cython
tag_suffix: cython
- mode: nuitka
target: runtime-nuitka
tag_suffix: nuitka
| モード | Docker ターゲット | イメージタグ | 用途 |
|---|---|---|---|
| source | runtime |
latest |
開発・デバッグ |
| wheel | runtime-wheel |
wheel |
ステージング |
| cython | runtime-cython |
cython |
プリプロ |
| nuitka | runtime-nuitka |
nuitka |
本番 |
並列実行と失敗処理
fail-fast: false # 1つのモード失敗でも他のモードは継続(推奨)
fail-fast: trueの場合、1つのモードが失敗するとマトリックス全体が停止fail-fast: falseの場合、すべてのモードが独立して実行(推奨)
ステップ詳細
Step 1: コード取得
- uses: actions/checkout@v4
with:
fetch-depth: 0
目的: リポジトリコード取得、タグ情報も含める
出力:
- ${{ github.workspace }} = /home/runner/work/EvoSpikeNet-Core/EvoSpikeNet-Core
- Dockerfile, scripts/, README.md など全ファイル利用可能
Step 2: Docker Buildx セットアップ
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
目的: マルチプラットフォーム(linux/amd64, linux/arm64)対応ビルダーの設定
機能: - マルチステージビルドサポート(必須) - Docker レイヤーキャッシュ(gha キャッシュ) - イメージ署名サポート(オプション)
Step 3: メタデータ抽出
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}/evospikenet
tags: |
type=ref,event=branch,suffix=-${{ matrix.tag_suffix }}
type=semver,pattern={{version}},suffix=-${{ matrix.tag_suffix }}
type=sha,suffix=-${{ matrix.tag_suffix }}
目的: イメージタグルールを定義
生成されるタグ例:
| トリガー | 生成タグ |
|---|---|
| push to main | ghcr.io/.../evospikenet:main-latest |
| push tag v1.0.0 | ghcr.io/.../evospikenet:1.0.0-latest |
| push to PR | ghcr.io/.../evospikenet:pr-123-latest |
| git sha | ghcr.io/.../evospikenet:abc1234-latest |
Step 4: Docker イメージビルド
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./EvoSpikeNet-Core
target: ${{ matrix.target }}
build-args: |
APP_IMAGE_MODE=${{ matrix.mode }}
BASE_IMAGE=ubuntu:22.04
ENABLE_GPU=false
push: false # PR 時はプッシュなし
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
パラメータ説明:
| パラメータ | 値 | 説明 |
|---|---|---|
context |
./EvoSpikeNet-Core |
ビルドコンテキスト(Dockerfile の場所) |
target |
runtime など |
Dockerfile の FROM ターゲット |
build-args |
APP_IMAGE_MODE=source など |
ビルド引数(--build-arg 相当) |
push |
false (PR) / true (main push) |
レジストリにプッシュするか |
cache-from/to |
type=gha |
GitHub Actions キャッシュを使用 |
ビルド時間(初回):
source: 2-3 分
wheel: 5-8 分
cython: 15-20 分
nuitka: 40-50 分
-------
合計: 60-80 分
Step 5: ポストビルドテスト
5a. source/wheel/cython: Python モジュールテスト
- name: Test module imports
run: |
docker run --rm ${{ steps.build.outputs.imageid }} python -c \
"import evospikenet.api; print('✓ API import OK')"
テスト内容: - evospikenet.api モジュールのインポート - 基本的な関数定義確認
失敗時の対応:
# ステップが失敗するとワークフロー全体が ❌ 状態に
echo "❌ Module import failed"
exit 1
5b. nuitka: バイナリ存在確認
- name: Test Nuitka binary
run: |
docker run --rm ${{ steps.build.outputs.imageid }} \
test -x /tmp/nuitka-dist/evospikenet-api && \
echo "✓ Nuitka binary OK" || exit 1
テスト内容:
- /tmp/nuitka-dist/evospikenet-api ファイルが存在
- 実行可能(-x)
Step 6: 結果レポート
- name: Report build result
if: always() # 成功/失敗に関わらず実行
run: |
echo "Build Status: ${{ job.status }}"
echo "Mode: ${{ matrix.mode }}"
echo "Image: ${{ steps.meta.outputs.tags }}"
ローカル実行
GitHub Actions を手元で実行(act ツール)
# act をインストール(Ubuntu)
curl https://raw.githubusercontent.com/nektos/act/master/install.sh | bash
# ワークフロー実行
cd /path/to/EvoSpikeNet-Core
act --job build-matrix -l
# 特定のモードのみ実行
act --job build-matrix -e events.json # events.json で matrix 指定
マトリックス実行の Docker コマンド例
ワークフロー内の docker build コマンドをローカルで再現:
# source モード
docker build \
--build-arg APP_IMAGE_MODE=source \
--target runtime \
-t evospikenet:test-source \
./EvoSpikeNet-Core
# wheel モード
docker build \
--build-arg APP_IMAGE_MODE=wheel \
--target runtime-wheel \
-t evospikenet:test-wheel \
./EvoSpikeNet-Core
# cython モード
docker build \
--build-arg APP_IMAGE_MODE=cython \
--target runtime-cython \
-t evospikenet:test-cython \
./EvoSpikeNet-Core
# nuitka モード(時間がかかる)
docker build \
--build-arg APP_IMAGE_MODE=nuitka \
--target runtime-nuitka \
-t evospikenet:test-nuitka \
./EvoSpikeNet-Core
テストスクリプト
scripts/test-all-docker-modes.sh:
#!/bin/bash
set -e
echo "Testing all Docker build modes..."
MODES=(source wheel cython nuitka)
TARGETS=(runtime runtime-wheel runtime-cython runtime-nuitka)
for i in "${!MODES[@]}"; do
mode=${MODES[$i]}
target=${TARGETS[$i]}
echo ""
echo "=== Building $mode mode (target: $target) ==="
docker build \
--build-arg APP_IMAGE_MODE=$mode \
--target $target \
-t evospikenet:test-$mode \
./EvoSpikeNet-Core
# テスト実行
echo "Testing $mode mode..."
if [[ "$mode" == "nuitka" ]]; then
docker run --rm evospikenet:test-$mode \
test -x /tmp/nuitka-dist/evospikenet-api && \
echo "✓ $mode mode OK" || (echo "❌ $mode mode FAILED"; exit 1)
else
docker run --rm evospikenet:test-$mode python -c \
"import evospikenet.api; print('✓ $mode mode OK')" || \
(echo "❌ $mode mode FAILED"; exit 1)
fi
done
echo ""
echo "✅ All modes passed!"
実行:
chmod +x scripts/test-all-docker-modes.sh
./scripts/test-all-docker-modes.sh
トラブルシューティング
エラー: "Out of disk space"
GitHub Actions ランナーのディスク容量不足。
# 対策: キャッシュクリーンアップ
- name: Clean up Docker build cache
run: docker builder prune -a --force
エラー: "Nuitka compilation timeout"
Nuitka バイナリ化に時間がかかりすぎた。
# 対策: タイムアウト増加
timeout-minutes: 120 # デフォルト 360 分から明示的に指定
エラー: "Matrix job failed"
特定のモードのビルルが失敗。ワークフロー実行ログを確認:
Actions → [ワークフロー実行] → [失敗したジョブ] → ログを展開
イメージが大きすぎる
# イメージサイズ確認
docker images evospikenet:test-*
docker inspect --format='{{.VirtualSize}}' evospikenet:test-nuitka
キャッシュが効かない
# 対策: キャッシュキーをリセット(すべてのレイヤーを再ビルド)
cache-from: type=gha,scope=${{ github.ref }}
cache-to: type=gha,mode=max,scope=${{ github.ref }}
カスタマイズ
モード追加(例: wheel+GPU)
strategy:
matrix:
mode: [source, wheel, cython, nuitka, wheel-gpu]
include:
# ... 既存のモード ...
- mode: wheel-gpu
target: runtime-wheel
tag_suffix: wheel-gpu
build_args: |
APP_IMAGE_MODE=wheel
BASE_IMAGE=nvidia/cuda:12.4.1
ENABLE_GPU=true
特定のブランチのみビルド
on:
push:
branches:
- main
- develop
- release/* # release/* ブランチも対象
スケジュール実行(定期ビルド)
on:
schedule:
- cron: '0 2 * * 0' # 毎週日曜 2:00 UTC
手動実行パラメータ
on:
workflow_dispatch:
inputs:
build_mode:
description: 'Build mode'
required: true
default: 'all'
type: choice
options:
- all
- source
- wheel
- cython
- nuitka
使用方法:
jobs:
build-matrix:
runs-on: ubuntu-latest
strategy:
matrix:
mode: ${{ github.event.inputs.build_mode == 'all' &&
fromJson('["source","wheel","cython","nuitka"]') ||
fromJson(format('["{0}"]', github.event.inputs.build_mode)) }}
パフォーマンス最適化
1. キャッシュ戦略
cache-from: type=gha,scope=${{ github.workflow }}-${{ github.ref }}
cache-to: type=gha,mode=max,scope=${{ github.workflow }}-${{ github.ref }}
効果: 2 回目以降のビルドが 50% 以上高速化
2. 不要なモードをスキップ
strategy:
matrix:
mode: [source, wheel, cython, nuitka]
exclude:
- mode: nuitka
# PR ではnuitka をスキップ(時間節約)
if: ${{ github.event_name == 'pull_request' }}
3. 並列ジョブ数制限
concurrency:
group: docker-build-${{ github.ref }}
cancel-in-progress: true
効果: 同じブランチで複数実行を防ぐ
関連ドキュメント
- DOCKER_BUILD_MODES.md - ビルドモード詳細
- DOCKER_PUBLISHING_GUIDE.md - パブリッシングワークフロー
- Dockerfile - メイン Dockerfile
- GitHub Actions ドキュメント