mcpField
G
github-actions

github-actions

github.com/bobmatnycクラウド・DevOps78764 回インストール15 週間前に更新
リポジトリ

github-actions について

github-actions は、ソフトウェアのワークフローを自動化する開発者向けに、GitHub 標準の CI/CD プラットフォームを解説するスキルです。YAML によるワークフロー設定、テスト、ビルド、デプロイ、リリースの実践を扱います。

主な機能

  1. 01YAML ワークフローとイベントトリガー
  2. 02ジョブ、ステップ、マトリックスの設定
  3. 03テスト、ビルド、デプロイのフロー
  4. 04キャッシュ、アーティファクト、依存関係の管理
  5. 05セキュリティスキャンとリリース自動化

活用シーン

  1. 01プルリクエストでテストを自動実行
  2. 02コードのマージ後にビルドとデプロイ
  3. 03ビルドやバックアップの定期実行
  4. 04コードのスキャンとパッケージ公開

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bobmatnyc/claude-mpm-skills --skill github-actions

インストール後、Claude Code で/github-actionsを入力して読み込まれたか確認します。

同梱ファイルmetadata.json

詳細

GitHub Actions の CI/CD

概要

GitHub Actions は、ソフトウェアのワークフローを自動化する GitHub ネイティブの CI/CD プラットフォームです。YAML ファイルでワークフローを定義すると、イベント駆動型の自動化によって、リポジトリから直接コードをビルド、テスト、デプロイできます。

使用する場面

  • すべてのプルリクエストでテストを自動化する
  • main へのマージ時にアプリケーションをビルドしてデプロイする
  • 定期的なタスクをスケジュールする(夜間ビルド、バックアップなど)
  • レジストリ(npm、PyPI、Docker Hub)にパッケージを公開する
  • セキュリティスキャンとコード品質チェックを実行する
  • リリースプロセスと変更履歴の生成を自動化する

クイックスタート

基本的なテストワークフロー

.github/workflows/test.yml を作成します。

name: Test

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

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm test

GitHub Actions 完全ガイド

基本概念

ワークフロー

自動化パイプラインを定義する、.github/workflows/ 内の YAML ファイルです。

構成:

  • 名前:ワークフローの識別子
  • トリガー:ワークフローを開始するイベント
  • ジョブ:実行する 1 つ以上のジョブ
  • ステップ:各ジョブ内のコマンドやアクション
name: CI Pipeline
on: [push, pull_request]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: echo "Building project"
ジョブ

デフォルトでは並列に実行される、独立した実行単位です。

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - run: npm run lint

  test:
    runs-on: ubuntu-latest
    needs: lint  # Wait for lint to complete
    steps:
      - run: npm test

  deploy:
    runs-on: ubuntu-latest
    needs: [lint, test]  # Wait for both
    steps:
      - run: ./deploy.sh
ステップ

ジョブ内で順番に実行されるコマンドまたはアクションです。

steps:
  # Use pre-built action
  - uses: actions/checkout@v4

  # Run shell command
  - run: npm install

  # Named step with environment
  - name: Run tests
    run: npm test
    env:
      NODE_ENV: test
アクション

再利用可能なコード単位です(マーケットプレイスのもの、またはカスタムのもの)。

# Official action
- uses: actions/checkout@v4

# Third-party action
- uses: docker/build-push-action@v5
  with:
    context: .
    push: true
    tags: user/app:latest

# Local action
- uses: ./.github/actions/custom-action

ワークフローの構文

トリガー(on)
Push イベント
on:
  push:
    branches:
      - main
      - 'releases/**'  # Wildcard pattern
    tags:
      - 'v*'  # All version tags
    paths:
      - 'src/**'
      - '!src/docs/**'  # Exclude docs
プルリクエストイベント
on:
  pull_request:
    types: [opened, synchronize, reopened]
    branches: [main, develop]
    paths-ignore:
      - '**.md'
      - 'docs/**'
スケジュール(Cron)
on:
  schedule:
    # Every day at 2:30 AM UTC
    - cron: '30 2 * * *'
    # Every Monday at 9:00 AM UTC
    - cron: '0 9 * * 1'
手動トリガー
on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Deployment environment'
        required: true
        type: choice
        options:
          - staging
          - production
      version:
        description: 'Version to deploy'
        required: false
        default: 'latest'
複数のトリガー
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 0 * * 0'  # Weekly
  workflow_dispatch:  # Manual
環境変数
ワークフローレベル
env:
  NODE_ENV: production
  API_URL: https://api.example.com

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - run: echo $NODE_ENV
ジョブレベル
jobs:
  test:
    runs-on: ubuntu-latest
    env:
      TEST_DATABASE: test_db
    steps:
      - run: pytest
ステップレベル
steps:
  - name: Build
    run: npm run build
    env:
      BUILD_TARGET: production
シークレット

機密データはリポジトリの設定に保存します。

steps:
  - name: Deploy
    run: ./deploy.sh
    env:
      API_KEY: ${{ secrets.API_KEY }}
      DATABASE_URL: ${{ secrets.DATABASE_URL }}

ベストプラクティス:

  • シークレットをコードにコミットしない
  • GitHub の暗号化されたシークレットを使用する
  • シークレットへのアクセスを特定の環境に制限する
  • シークレットを定期的にローテーションする

コンテキスト

github コンテキスト

リポジトリとワークフローの情報です。

steps:
  - name: Print context
    run: |
      echo "Repository: ${{ github.repository }}"
      echo "Ref: ${{ github.ref }}"
      echo "SHA: ${{ github.sha }}"
      echo "Actor: ${{ github.actor }}"
      echo "Event: ${{ github.event_name }}"
      echo "Branch: ${{ github.ref_name }}"
env コンテキスト

環境変数にアクセスします。

env:
  BUILD_ID: 12345

steps:
  - run: echo "Build ${{ env.BUILD_ID }}"
secrets コンテキスト

リポジトリのシークレットにアクセスします。

- run: echo "Token exists"
  env:
    TOKEN: ${{ secrets.GITHUB_TOKEN }}
matrix コンテキスト

マトリックスの値にアクセスします。

strategy:
  matrix:
    node: [18, 20, 22]
steps:
  - run: echo "Testing Node ${{ matrix.node }}"
needs コンテキスト

依存するジョブの出力にアクセスします。

jobs:
  build:
    outputs:
      version: ${{ steps.get_version.outputs.version }}
    steps:
      - id: get_version
        run: echo "version=1.2.3" >> $GITHUB_OUTPUT

  deploy:
    needs: build
    steps:
      - run: echo "Deploying ${{ needs.build.outputs.version }}"

ランナー

GitHub ホステッドランナー
jobs:
  ubuntu:
    runs-on: ubuntu-latest  # ubuntu-22.04

  macos:
    runs-on: macos-latest  # macOS 14

  windows:
    runs-on: windows-latest  # Windows 2022

  specific:
    runs-on: ubuntu-20.04  # Specific version

利用可能なランナー:

  • ubuntu-latest、ubuntu-22.04、ubuntu-20.04
  • macos-latest、macos-14、macos-13
  • windows-latest、windows-2022、windows-2019
セルフホステッドランナー
runs-on: self-hosted

# With labels
runs-on: [self-hosted, linux, x64, gpu]

セットアップ:

  1. Settings → Actions → Runners に移動します
  2. "New self-hosted runner" をクリックします
  3. プラットフォーム固有の手順に従います
  4. 対象を指定するためのカスタムラベルを追加します

マトリックス戦略

基本的なマトリックス

複数のバージョンでテストします。

strategy:
  matrix:
    node: [18, 20, 22]
    os: [ubuntu-latest, macos-latest, windows-latest]

runs-on: ${{ matrix.os }}
steps:
  - uses: actions/setup-node@v4
    with:
      node-version: ${{ matrix.node }}
Include/Exclude
strategy:
  matrix:
    node: [18, 20, 22]
    os: [ubuntu-latest, windows-latest]
    include:
      # Add specific combination
      - node: 22
        os: macos-latest
        experimental: true
    exclude:
      # Remove specific combination
      - node: 18
        os: windows-latest
Fail-fast
strategy:
  fail-fast: false  # Continue other jobs if one fails
  matrix:
    node: [18, 20, 22]
最大並列数
strategy:
  max-parallel: 2  # Run only 2 jobs concurrently
  matrix:
    node: [18, 20, 22]

よく使われるアクション

コードのチェックアウト
- uses: actions/checkout@v4
  with:
    fetch-depth: 0  # Full history for changelog
    submodules: true  # Include submodules
Node.js のセットアップ
- uses: actions/setup-node@v4
  with:
    node-version: '20'
    cache: 'npm'  # or 'yarn', 'pnpm'
    registry-url: 'https://registry.npmjs.org'
Python のセットアップ
- uses: actions/setup-python@v5
  with:
    python-version: '3.11'
    cache: 'pip'
Java のセットアップ
- uses: actions/setup-java@v4
  with:
    distribution: 'temurin'
    java-version: '17'
    cache: 'maven'
Go のセットアップ
- uses: actions/setup-go@v5
  with:
    go-version: '1.21'
    cache: true
依存関係のキャッシュ
- uses: actions/cache@v4
  with:
    path: |
      ~/.npm
      node_modules
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-
アーティファクトのアップロード
- uses: actions/upload-artifact@v4
  with:
    name: build-output
    path: dist/
    retention-days: 7
アーティファクトのダウンロード
- uses: actions/download-artifact@v4
  with:
    name: build-output
    path: dist/

条件付き実行

if 条件
steps:
  - name: Deploy to production
    if: github.ref == 'refs/heads/main'
    run: ./deploy.sh

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

  - name: Only on PR
    if: github.event_name == 'pull_request'
    run: echo "This is a PR"

  - name: On success
    if: success()
    run: echo "Previous steps succeeded"

  - name: On failure
    if: failure()
    run: echo "A step failed"

  - name: Always run
    if: always()
    run: echo "Cleanup tasks"
ジョブの条件
jobs:
  deploy:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - run: ./deploy.sh

フレームワーク別のワークフロー

Node.js/TypeScript
name: Node.js CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18, 20, 22]
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - run: npm ci

      - run: npm run lint

      - run: npm run type-check

      - run: npm test
        env:
          CI: true

      - run: npm run build

      - uses: codecov/codecov-action@v4
        if: matrix.node-version == 20
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
Python
name: Python CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.10', '3.11', '3.12']
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
          cache: 'pip'

      - run: pip install -r requirements.txt

      - run: pip install pytest pytest-cov mypy ruff

      - run: ruff check .

      - run: mypy .

      - run: pytest --cov=. --cov-report=xml

      - uses: codecov/codecov-action@v4
        if: matrix.python-version == '3.11'
Docker
name: Docker Build

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

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

      - uses: docker/setup-buildx-action@v3

      - uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - uses: docker/metadata-action@v5
        id: meta
        with:
          images: user/app
          tags: |
            type=ref,event=branch
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}

      - uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
Vercel を使用した Next.js
name: Next.js CI

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

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

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci

      - run: npm run lint

      - run: npm run build

      - run: npm test

  deploy-preview:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    needs: build
    steps:
      - uses: actions/checkout@v4

      - 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 }}

  deploy-production:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    needs: build
    steps:
      - uses: actions/checkout@v4

      - 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'

デプロイパターン

Vercel へのデプロイ
name: Deploy to Vercel

on:
  push:
    branches: [main]

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

      - 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'
Netlify へのデプロイ
name: Deploy to Netlify

on:
  push:
    branches: [main]

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

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - run: npm ci
      - run: npm run build

      - uses: netlify/actions/cli@master
        with:
          args: deploy --prod --dir=dist
        env:
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
AWS S3 + CloudFront
name: Deploy to AWS

on:
  push:
    branches: [main]

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

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - run: npm ci
      - run: npm run build

      - uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1

      - run: aws s3 sync dist/ s3://${{ secrets.S3_BUCKET }} --delete

      - run: |
          aws cloudfront create-invalidation \
            --distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} \
            --paths "/*"
Docker レジストリへのプッシュ
name: Publish Docker Image

on:
  release:
    types: [published]

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

      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: |
            ghcr.io/${{ github.repository }}:latest
            ghcr.io/${{ github.repository }}:${{ github.event.release.tag_name }}

テストワークフロー

カバレッジ付きユニットテスト
name: Test Coverage

on: [push, pull_request]

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

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci

      - run: npm test -- --coverage

      - uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          files: ./coverage/coverage-final.json
          fail_ci_if_error: true
統合テスト
name: Integration Tests

on: [push, pull_request]

jobs:
  integration:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_PASSWORD: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432

      redis:
        image: redis:7
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 6379:6379

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - run: npm ci

      - run: npm run test:integration
        env:
          DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test
          REDIS_URL: redis://localhost:6379
Playwright による E2E テスト
name: E2E Tests

on: [push, pull_request]

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

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci

      - run: npx playwright install --with-deps

      - run: npm run build

      - run: npm run test:e2e

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 30

リリースの自動化

Semantic Release
name: Release

on:
  push:
    branches: [main]

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Full history for changelog

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - run: npm ci

      - run: npx semantic-release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
変更履歴付きリリースの作成
name: Create Release

on:
  push:
    tags:
      - 'v*'

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Generate changelog
        id: changelog
        run: |
          # Generate changelog from commits
          CHANGELOG=$(git log $(git describe --tags --abbrev=0 HEAD^)..HEAD --pretty=format:"- %s (%h)" --no-merges)
          echo "changelog<<EOF" >> $GITHUB_OUTPUT
          echo "$CHANGELOG" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref_name }}
          release_name: Release ${{ github.ref_name }}
          body: |
            ## Changes
            ${{ steps.changelog.outputs.changelog }}
          draft: false
          prerelease: false
npm パッケージの公開
name: Publish to npm

on:
  release:
    types: [published]

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

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          registry-url: 'https://registry.npmjs.org'

      - run: npm ci

      - run: npm test

      - run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

セキュリティスキャン

CodeQL 分析
name: CodeQL

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 0 * * 1'  # Weekly

jobs:
  analyze:
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: ['javascript', 'python']

    steps:
      - uses: actions/checkout@v4

      - uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}

      - uses: github/codeql-action/autobuild@v3

      - uses: github/codeql-action/analyze@v3
依存関係のスキャン
name: Dependency Check

on:
  push:
    branches: [main]
  schedule:
    - cron: '0 0 * * 1'

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

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - run: npm audit --audit-level=moderate

      - run: npx snyk test
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        continue-on-error: true
Trivy コンテナスキャン
name: Container Security Scan

on:
  push:
    branches: [main]

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

      - run: docker build -t myapp:${{ github.sha }} .

      - uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'myapp:${{ github.sha }}'
          format: 'sarif'
          output: 'trivy-results.sarif'

      - uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: 'trivy-results.sarif'

コンポジットアクション

.github/actions/ に再利用可能なアクションを作成します。

シンプルなコンポジットアクション

.github/actions/setup-project/action.yml:

name: 'Setup Project'
description: 'Install dependencies and cache'

inputs:
  node-version:
    description: 'Node.js version'
    required: false
    default: '20'

runs:
  using: 'composite'
  steps:
    - uses: actions/setup-node@v4
      with:
        node-version: ${{ inputs.node-version }}
        cache: 'npm'

    - run: npm ci
      shell: bash

使用方法:

steps:
  - uses: actions/checkout@v4
  - uses: ./.github/actions/setup-project
    with:
      node-version: '20'
再利用可能なワークフロー

.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
    environment: ${{ inputs.environment }}
    steps:
      - uses: actions/checkout@v4

      - run: ./deploy.sh
        env:
          DEPLOY_TOKEN: ${{ secrets.deploy-token }}
          ENVIRONMENT: ${{ inputs.environment }}

使用方法:

name: Deploy Production

on:
  push:
    branches: [main]

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

パフォーマンスの最適化

依存関係のキャッシュ
- uses: actions/cache@v4
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-
Docker レイヤーのキャッシュ
- uses: docker/build-push-action@v5
  with:
    context: .
    cache-from: type=gha
    cache-to: type=gha,mode=max
並列化
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - run: npm run lint

  test-unit:
    runs-on: ubuntu-latest
    steps:
      - run: npm run test:unit

  test-integration:
    runs-on: ubuntu-latest
    steps:
      - run: npm run test:integration

  # All run in parallel
条件付きジョブ実行
jobs:
  deploy:
    # Skip deploy on draft PRs
    if: github.event.pull_request.draft == false
    runs-on: ubuntu-latest
    steps:
      - run: ./deploy.sh

ワークフローのデバッグ

デバッグログを有効にする

リポジトリのシークレットを設定します:

  • ACTIONS_RUNNER_DEBUG:true
  • ACTIONS_STEP_DEBUG:true
デバッグステップ
- name: Debug Info
  run: |
    echo "Event: ${{ github.event_name }}"
    echo "Ref: ${{ github.ref }}"
    echo "SHA: ${{ github.sha }}"
    echo "Actor: ${{ github.actor }}"
    env
tmate を使った対話型デバッグ
- name: Setup tmate session
  if: failure()
  uses: mxschmitt/action-tmate@v3
  timeout-minutes: 15

ベストプラクティス

セキュリティ
  • 機密データにはシークレットを使用します
  • アクションのバージョンを SHA に固定します:uses: actions/checkout@8e5e7e5a...
  • トークンの権限を最小限にします
  • 環境保護ルールを使用します
  • 必須チェックを設定してブランチ保護を有効にします
パフォーマンス
  • 依存関係を積極的にキャッシュします
  • 並列テストにはマトリックス戦略を使用します
  • 可能な場合はチェックアウトの深さを最小限にします
  • ジョブ間のデータ転送にはアーティファクトを使用します
  • マルチステージビルドで Docker ビルドを最適化します
保守性
  • 共通パターンには再利用可能なワークフローを使用します
  • 繰り返し使用するステップには複合アクションを作成します
  • ワークフローの目的とトリガーを文書化します
  • 意味の分かるジョブ名とステップ名を使用します
  • ワークフローの対象を絞ります(単一責任)
信頼性
  • 適切なタイムアウトを設定します
  • continue-on-error を適切に使用します
  • 不安定なテストには再試行ロジックを実装します
  • ワークフローの実行時間を監視します
  • 古いアーティファクトとキャッシュをクリーンアップします

よく使われるパターン

失敗時に PR へコメントする
- name: Comment on PR
  if: failure() && github.event_name == 'pull_request'
  uses: actions/github-script@v7
  with:
    script: |
      github.rest.issues.createComment({
        issue_number: context.issue.number,
        owner: context.repo.owner,
        repo: context.repo.repo,
        body: '❌ Tests failed. Please check the workflow logs.'
      })
Dependabot の PR を自動マージする
name: Auto-merge Dependabot

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  auto-merge:
    if: github.actor == 'dependabot[bot]'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - run: npm ci
      - run: npm test

      - uses: gh enable-auto-merge --merge
        if: success()
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
デプロイ時に通知する
- name: Slack Notification
  if: always()
  uses: 8398a7/action-slack@v3
  with:
    status: ${{ job.status }}
    text: 'Deploy to ${{ inputs.environment }}: ${{ job.status }}'
    webhook_url: ${{ secrets.SLACK_WEBHOOK }}

トラブルシューティング

よくある問題

ワークフローがトリガーされない:

  • ブランチフィルターが実際のブランチ名と一致しているか確認します
  • ワークフローファイルが .github/workflows/ にあることを確認します
  • YAML の構文が有効であることを確認します

ジョブがスキップされる:

  • if 条件を確認します
  • needs の依存関係が成功していることを確認します
  • ブランチ保護ルールを確認します

タイムアウト:

  • デフォルトのタイムアウトは 360 分です
  • 明示的にタイムアウトを設定します:timeout-minutes: 30
  • 実行時間の長いステップを最適化します

権限が拒否される:

  • ワークフローの権限を更新します:
    permissions:
      contents: write
      pull-requests: write
    

シークレットを利用できない:

  • シークレット名が完全に一致していることを確認します(大文字と小文字を区別します)
  • シークレットのスコープ(リポジトリ、組織、環境)を確認します
  • ワークフローが環境シークレットにアクセスできることを確認します

ローカルのワークフローパターン(使用中のリポジトリ)

Python + uv CI(mcp-vector-search)
  • uv をインストールします:astral-sh/setup-uv@v3 と uv python install 3.11。
  • uv sync --dev を使用し、uv run ruff、uv run mypy、uv run pytest を実行します。
  • OS と Python バージョンのマトリックスを使用し、linux でカバレッジを Codecov にアップロードします。
Node + pnpm CI(ai-code-review)
  • pnpm キャッシュを使用して pnpm/action-setup@v4 と actions/setup-node@v4 を使用します。
  • pnpm install --frozen-lockfile でインストールし、続いて pnpm run lint、pnpm run build:types、pnpm test を実行します。
タグによるリリース
  • push の v* タグをトリガーにします。
  • ビルドし、GitHub Release のノートを作成して、npm または PyPI に公開します。
  • pypa/gh-action-pypi-publish@release/v1 または npm 公開用の NODE_AUTH_TOKEN を使用します。
Homebrew 更新パイプライン
  • CI 成功後の workflow_run をトリガーにします。
  • HOMEBREW_TAP_TOKEN を使って scripts/update_homebrew_formula.py を実行します。
  • 失敗した場合は、手動更新手順を記載した issue を作成します。

リソース

コメント