GitHub ActionsでCI/CDパイプラインを構築する


GitHub Actionsとは

GitHub Actionsは、GitHubが提供するCI/CDプラットフォームです。リポジトリで発生するイベント(プッシュ、プルリクエストなど)をトリガーに、自動的にワークフローを実行できます。

基本的なワークフロー

シンプルなテストワークフロー

.github/workflows/test.ymlを作成:

name: Test

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

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: '20'
        cache: 'npm'

    - name: Install dependencies
      run: npm ci

    - name: Run tests
      run: npm test

    - name: Run linter
      run: npm run lint

複数のNode.jsバージョンでテスト

name: Test Multiple Versions

on: [push, pull_request]

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [18.x, 20.x, 22.x]

    steps:
    - uses: actions/checkout@v4

    - name: Setup Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v4
      with:
        node-version: ${{ matrix.node-version }}

    - name: Install dependencies
      run: npm ci

    - name: Run tests
      run: npm test

ビルドとデプロイ

Cloudflare Pagesへのデプロイ

name: Deploy to Cloudflare Pages

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      deployments: write

    steps:
    - uses: actions/checkout@v4

    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: '20'
        cache: 'npm'

    - name: Install dependencies
      run: npm ci

    - name: Build
      run: npm run build

    - name: Deploy to Cloudflare Pages
      uses: cloudflare/pages-action@v1
      with:
        apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
        accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
        projectName: my-project
        directory: dist
        gitHubToken: ${{ secrets.GITHUB_TOKEN }}

Vercelへのデプロイ

name: Deploy to Vercel

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Deploy to Vercel
      uses: amondnet/vercel-action@v25
      with:
        vercel-token: ${{ secrets.VERCEL_TOKEN }}
        vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
        vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
        vercel-args: '--prod'

環境変数とシークレット

シークレットの設定

  1. GitHubリポジトリの Settings > Secrets and variables > Actions
  2. 「New repository secret」をクリック
  3. 名前と値を入力

ワークフローでの使用

steps:
  - name: Use secrets
    env:
      API_KEY: ${{ secrets.API_KEY }}
      DATABASE_URL: ${{ secrets.DATABASE_URL }}
    run: |
      echo "API Keyは環境変数として利用可能"
      npm run deploy

キャッシュの活用

依存関係のキャッシュ

steps:
  - uses: actions/checkout@v4

  - name: Cache node modules
    uses: actions/cache@v3
    with:
      path: ~/.npm
      key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
      restore-keys: |
        ${{ runner.os }}-node-

  - name: Install dependencies
    run: npm ci

ビルド成果物のキャッシュ

steps:
  - name: Build
    run: npm run build

  - name: Cache build
    uses: actions/cache@v3
    with:
      path: dist
      key: build-${{ github.sha }}

条件付き実行

特定のファイルが変更された時のみ実行

name: Frontend Tests

on:
  pull_request:
    paths:
      - 'src/**'
      - 'package.json'
      - 'package-lock.json'

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - run: npm test

ブランチに応じた処理

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4

    - name: Deploy to Production
      if: github.ref == 'refs/heads/main'
      run: npm run deploy:prod

    - name: Deploy to Staging
      if: github.ref == 'refs/heads/develop'
      run: npm run deploy:staging

再利用可能なワークフロー

呼び出される側のワークフロー

.github/workflows/reusable-deploy.yml:

name: Reusable Deploy

on:
  workflow_call:
    inputs:
      environment:
        required: true
        type: string
    secrets:
      deploy-token:
        required: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4

    - name: Deploy to ${{ inputs.environment }}
      env:
        DEPLOY_TOKEN: ${{ secrets.deploy-token }}
      run: |
        echo "Deploying to ${{ inputs.environment }}"
        npm run deploy

呼び出す側のワークフロー

name: Deploy All Environments

on:
  push:
    branches: [ main ]

jobs:
  deploy-staging:
    uses: ./.github/workflows/reusable-deploy.yml
    with:
      environment: staging
    secrets:
      deploy-token: ${{ secrets.STAGING_TOKEN }}

  deploy-production:
    needs: deploy-staging
    uses: ./.github/workflows/reusable-deploy.yml
    with:
      environment: production
    secrets:
      deploy-token: ${{ secrets.PRODUCTION_TOKEN }}

セキュリティのベストプラクティス

1. 最小権限の原則

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read  # リポジトリの読み取りのみ
      packages: write # パッケージへの書き込み

2. サードパーティアクションのバージョン固定

# ❌ 悪い例(常に最新版を使用)
- uses: actions/checkout@v4

# ✅ 良い例(特定のコミットハッシュを指定)
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11

3. シークレットの保護

steps:
  - name: Use secret
    env:
      SECRET_KEY: ${{ secrets.SECRET_KEY }}
    run: |
      # シークレットをログに出力しない
      echo "::add-mask::$SECRET_KEY"

デバッグとトラブルシューティング

デバッグログの有効化

steps:
  - name: Debug info
    run: |
      echo "Event name: ${{ github.event_name }}"
      echo "Ref: ${{ github.ref }}"
      echo "SHA: ${{ github.sha }}"
      echo "Actor: ${{ github.actor }}"

SSH経由でのデバッグ

steps:
  - name: Setup tmate session
    if: failure()
    uses: mxschmitt/action-tmate@v3

まとめ

GitHub Actionsを活用することで、開発ワークフローを大幅に自動化できます。テスト、ビルド、デプロイを自動化することで、より素早く確実にコードをリリースできるようになります。

最初はシンプルなワークフローから始めて、徐々に複雑な処理を追加していくのがおすすめです。ぜひプロジェクトにCI/CDを導入してみてください!