コンテンツにスキップ

GitHub Actions CI ビルドマトリックスガイド

.github/workflows/docker-build-matrix.yml ワークフロー(docker-build-matrix.yml)を使用して、 4つの Docker ビルドモード(source/wheel/cython/nuitka)を自動的にビルド・テストします。

目次

  1. ワークフロー概要
  2. ワークフロー構成
  3. トリガー条件
  4. マトリックス設定
  5. ステップ詳細
  6. ローカル実行
  7. トラブルシューティング
  8. カスタマイズ

ワークフロー概要

このワークフローは以下を実行します:

  1. マトリックスビルド: 4つのモード(source/wheel/cython/nuitka)を並列にビルド
  2. ポストビルドテスト: 各モードごとに適切な検証
  3. 成功通知: すべてのビルドが完了したら報告
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

効果: 同じブランチで複数実行を防ぐ


関連ドキュメント