GitHub Actionsで自動テストをCI/CDパイプラインに組み込む

GitHub Actionsを使えば、コード変更時に自動的にテストやビルドを実行し、品質を保ちながら開発スピードを加速できます。この記事では、実際のプロジェクトに即座に導入できるワークフローの設定方法を解説します。

GitHub Actionsとは何か

GitHub Actionsは、GitHubが提供するCI/CD(継続的インテグレーション・継続的デリバリー)ツールです。リポジトリ内に.github/workflowsディレクトリを作成し、YAMLファイルでワークフローを定義することで、プッシュやプルリクエストなどのイベント発生時に自動的にタスクを実行します。

Jenkins や GitLab CI といった外部ツールと異なり、GitHub のネイティブ機能であるため、セットアップが簡単で、GitHub との統合が緊密です。パブリックリポジトリなら無制限に無料で使用できます。

基本的なワークフローの設定

最小限のYAMLファイルから始める

まず、最もシンプルなワークフローを作成してみましょう。リポジトリのルートディレクトリに.github/workflows/ディレクトリを作成し、test.ymlというファイルを以下の内容で作成してください。

name: Node.js テスト

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    
    strategy:
      matrix:
        node-version: [18.x, 20.x]
    
    steps:
      - name: コードをチェックアウト
        uses: actions/checkout@v4
      
      - name: Node.js ${{ matrix.node-version }} をセットアップ
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      
      - name: 依存関係をインストール
        run: npm ci
      
      - name: テストを実行
        run: npm test
      
      - name: ビルドを実行
        run: npm run build

このワークフローの各要素を説明します:

  • name: ワークフローの表示名
  • on: ワークフローをトリガーするイベント
  • jobs: 実行するジョブの定義
  • runs-on: 実行環境(ubuntu-latestwindows-latestmacos-latest等)
  • strategy.matrix: 複数バージョンでの並列実行
  • steps: 順序立てて実行するステップ

環境変数とシークレット情報の管理

APIキーやデータベースのパスワードなどの機密情報は、GitHubのシークレット機能で安全に管理します。リポジトリの Settings → Secrets and variables → Actions から、シークレット変数を登録してください。

name: 本番環境へのデプロイ

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      - name: 環境変数をセット
        run: |
          echo "API_KEY=${{ secrets.API_KEY }}" >> $GITHUB_ENV
          echo "DATABASE_URL=${{ secrets.DATABASE_URL }}" >> $GITHUB_ENV
      
      - name: デプロイスクリプトを実行
        run: ./scripts/deploy.sh

${{ secrets.シークレット名 }}という記法でシークレット情報にアクセスできます。ログには出力されないため、安全に機密情報を利用できます。

実践的なワークフロー例

Pythonプロジェクトの自動テストと品質チェック

Python開発の場合、pytest でテストを実行し、flake8 で構文チェック、coverage でテストカバレッジを測定するワークフローが一般的です。以下の例を試してみてください。

name: Python CI

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    
    strategy:
      matrix:
        python-version: ['3.9', '3.11', '3.12']
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Python ${{ matrix.python-version }} をセットアップ
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      
      - name: 依存関係をインストール
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements-dev.txt
      
      - name: flake8 で構文をチェック
        run: flake8 src/ tests/
      
      - name: pytest でテストを実行
        run: pytest --cov=src/ --cov-report=xml
      
      - name: Codecov にカバレッジをアップロード
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage.xml

Docker イメージのビルドとプッシュ

コンテナ化されたアプリケーションの場合、GitHub Actions から Docker イメージをビルドし、Docker Hub や GitHub Container Registry にプッシュするワークフローが有用です。

name: Docker イメージをビルド・プッシュ

on:
  push:
    branches: [ main ]
    tags: [ 'v*' ]

jobs:
  build:
    runs-on: ubuntu-latest
    
    permissions:
      contents: read
      packages: write
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Docker メタデータを取得
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: |
            ghcr.io/${{ github.repository }}
          tags: |
            type=ref,event=branch
            type=semver,pattern={{version}}
            type=sha
      
      - name: Docker Buildx をセットアップ
        uses: docker/setup-buildx-action@v3
      
      - name: GitHub Container Registry にログイン
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      
      - name: イメージをビルド・プッシュ
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

よくあるハマりポイントと解決策

タイムアウトエラーが発生する

大規模なテストスイートやビルドプロセスが実行時間の上限(デフォルト360分)に達することがあります。ジョブレベルでtimeout-minutesを設定して明示的にタイムアウト時間を指定してください。

jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 30  # 30分でタイムアウト
    
    steps:
      - uses: actions/checkout@v4
      # ... その他のステップ

権限エラーで実行に失敗する

デプロイやクラウドリソースへのアクセスが必要な場合、permissionsを正しく設定する必要があります。最小限の権限を付与するが原則です。

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: read        # リポジトリの読み取り
      id-token: write       # OIDC トークンの生成
      packages: write       # パッケージのプッシュ
    
    steps:
      # ... デプロイ処理

キャッシュが効かない

依存関係のインストール時間を短縮するため、actions/cacheを使用してください。npm の場合、package-lock.jsonが変更されるまでキャッシュが再利用されます。

- name: npm キャッシュをセットアップ
  uses: actions/setup-node@v4
  with:
    node-version: '20.x'
    cache: 'npm'

- name: 依存関係をインストール
  run: npm ci

GitHub Actions vs 代替ツール

GitLab CI や Jenkins との比較では、GitHub Actions はセットアップの簡単さと GitHub との統合の密接さが強み。一方、オンプレミス環境が必須なら Jenkins、既に GitLab を使用しているなら GitLab CI の方が適しています。ほとんどのクラウドネイティブプロジェクトでは GitHub Actions で十分です。

使うべき場面と使うべきでない場面

使うべき場面: Web アプリケーションの自動テスト、ビルド、デプロイ。コード品質チェック(linting、型チェック)。定期的なメンテナンスタスク。GitHub のドキュメント自動生成。

使うべきでない場面: 極めて複雑なビルドパイプライン(専門的な CI/CD ツールの方が適切)。長時間の計算処理(実行時間制限あり)。オンプレミス環境専用のシステム連携。

よくある質問

on.workflow_dispatchを追加すると、GitHub UI から手動実行可能になります。

pathsフィルターを使用してください。

if条件を使用します。

まとめ

  • GitHub Actions は .github/workflows/ ディレクトリの YAML ファイルで定義され、イベントに応じて自動実行される
  • 基本的な Node.js や Python プロジェクトなら数分で導入可能。公式の actions を組み合わせるだけで十分
  • 機密情報は secrets で管理し、matrix を使って複数バージョンでの並列テストを効率化できる
  • Docker イメージのビルド・プッシュやコード品質測定など、実践的なユースケースが豊富
  • タイムアウトやキャッシュの設定、権限管理に注意し、シンプルから始めて徐々に複雑化させるのがコツ

GitHub Actions の公式ドキュメントはこちらで参照できます。テンプレートとなるワークフローも豊富に提供されているため、自分のプロジェクトに合わせてカスタマイズしてみてください。

動作確認環境: Ubuntu 22.04 / Node.js 20.x / GitHub Actions 2025年1月版で動作確認済み

K
AWS・Python・生成AIを専門とするソフトウェアエンジニア。AI・クラウド・開発ワークフローの実践ガイドを執筆しています。詳しく見る →