これまでに書いたすべてのGitHub Actionsワークフローはすべてがそれぞれ1つのYAMLファイルです。トリガー、Job、 ステップ、環境変数、Matrix戦略—すべてがYAMLで表現されます。つまりYAMLを深く理解することは 単に学術的なことではありません:これはリリースをデプロイしようとしている金曜日の午後4時に謎めいた障害が発生する 信頼性のないCIと、確実に動作するCIの違いです。

GitHub Actionsには優れた ワークフロー構文ドキュメントがありますが、 Actionsの機能に焦点を当てており、基盤となるYAMLメカニクスには触れていません。この記事では両方— ワークフロー構造と、CI設定を成功または失敗させるYAML固有のパターン(および落とし穴)—をカバーします。

ワークフロー構造:トップレベルのキー

GitHub Actionsのワークフローファイルは.github/workflows/に置かれ、3つの必須トップレベルキーを持ちます。 公式ワークフローの概要では ファイルがリポジトリ内のどこにあるか、GitHubがどのように検出するかを説明しています:

yaml
name: CI Pipeline          # optional but shown in the Actions UI

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

jobs:                      # the actual work
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm test
YAMLブール値としてのonに注意: YAML 1.1では、裸の単語onは ブール値trueとして解釈されます。GitHubのパーサーはこれを正しく処理しますが、汎用YAMLリンターで ワークフローファイルにフラグが立てられた場合、これが理由です。安全な形式は引用符で囲むことです: "on": — ただしGitHub Actions自体は引用符を必要としません。

トリガー:on:キー

on:キーはワークフローがいつ実行されるかを制御します。 トリガーイベントの完全なリストでは プルリクエストのレビューからリポジトリのディスパッチまですべてをカバーしています。最も一般的なパターンを紹介します:

yaml
on:
  # Push to specific branches
  push:
    branches:
      - main
      - "release/**"       # glob pattern — quotes needed for /**
    paths-ignore:
      - "docs/**"
      - "*.md"

  # PRs targeting main
  pull_request:
    branches: [main]
    types: [opened, synchronize, reopened]

  # Scheduled (cron syntax)
  schedule:
    - cron: "0 2 * * 1"   # every Monday at 2am UTC

  # Manual trigger with input
  workflow_dispatch:
    inputs:
      environment:
        description: "Target environment"
        required: true
        default: staging
        type: choice
        options: [staging, production]

マルチラインrun:コマンドとYAMLブロックスカラー

run:キーはYAMLのリテラルブロックスカラー(|)が本領を発揮する場所です— ブロックとフォールデッドスカラーのあらゆるバリエーションについてはyaml-multiline.infoリファレンスを参照してください。 これがなければ&&で1行にコマンドを連結することになり、読みにくくなります:

yaml
steps:
  # Single line — works but hard to read
  - name: Build
    run: npm ci && npm run lint && npm run test && npm run build

  # Multi-line with literal block scalar — much better
  - name: Build
    run: |
      npm ci
      npm run lint
      npm run test -- --coverage
      npm run build

  # Folded scalar (>) joins lines with spaces — NOT what you want for shell
  # This would run as a single command with spaces where the newlines are:
  - name: Wrong for shell
    run: >
      npm ci
      npm test
マルチラインのシェルスクリプトには常に|を使い、>は使わないでください。 フォールデッドスカラーは改行をスペースに折りたたみます。つまりシェルコマンドが1つの長い文字列に結合されます。 これにより不可解なエラーが発生します。リテラルブロックスカラー|は改行を正確に保持するため、各行が 個別のシェルコマンドとして実行されます。

環境変数とシークレット

GitHub Actionsの環境変数は、YAMLと Actionsのコンテキストおよび式構文を組み合わせて使用します。 どのように組み合わさるかを見てみましょう:

yaml
env:
  NODE_ENV: production         # workflow-level env var
  API_VERSION: "2.1"          # quoted to force string type

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      DEPLOY_ENV: staging      # job-level env var (overrides workflow-level)

    steps:
      - name: Deploy to staging
        env:
          API_KEY: ${{ secrets.STAGING_API_KEY }}     # step-level, from secret
          DATABASE_URL: ${{ vars.STAGING_DB_URL }}    # step-level, from variable
        run: |
          echo "Deploying to $DEPLOY_ENV"
          ./scripts/deploy.sh

式構文${{ }}はYAMLの上に重ねられたGitHub Actions独自のテンプレート言語です。 一部のコンテキストではYALMの解析前に評価されるため、YAMLの引用符ルールと予期せぬ方法で干渉することがあります。 迷った場合は、${{で始まる値をダブルクォートで囲んでください。

Matrix戦略:複数の設定でビルドする

Matrix戦略は GitHub Actionsの最も強力な機能の1つで、 完全にYAMLで表現されます。Matrix値の各組み合わせについてJobを1回ずつ実行します:

yaml
jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false         # don't cancel other matrix jobs on failure
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node: ["18", "20", "22"]
        exclude:
          - os: windows-latest
            node: "18"         # skip this combination

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm ci && npm test

この1つのJob定義は最大9つの並列実行を生成します(3 OS × 3 Nodeバージョン、除外の1つを引いて)。 YAMLのMatrix値は単純な配列です—唯一注意すべきは、18のようなバージョン番号は 文字列として保持するために"18"のように引用符で囲む必要があるということです。 引用符なしではYAMLは整数として解析し、一部のActionsが不満を述べる場合があります。

if:による条件付きステップ

if:キーを使うと条件に基づいてステップをスキップできます。GitHubの式言語を使用し、 プレーンなYAML値ではありません:

yaml
steps:
  - name: Run tests
    run: npm test

  - name: Upload coverage
    if: success() && github.ref == 'refs/heads/main'
    uses: codecov/codecov-action@v4

  - name: Notify on failure
    if: failure()
    uses: slackapi/slack-github-action@v1
    with:
      slack-message: "Build failed on ${{ github.ref }}"
      channel-id: "C12345ABC"
    env:
      SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}

  - name: Deploy (only on tag push)
    if: startsWith(github.ref, 'refs/tags/v')
    run: ./scripts/deploy.sh production

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

リポジトリをまたいだ重複を排除するために(ファイル内だけでなく)、GitHub Actionsは 再利用可能なワークフローをサポートします。 呼び出されるワークフローはon: workflow_call:を使用し、呼び出し元は ステップレベルではなくJobレベルでuses:を使用します:

yaml
# .github/workflows/reusable-test.yml (the reusable workflow)
on:
  workflow_call:
    inputs:
      node-version:
        required: false
        type: string
        default: "20"
    secrets:
      NPM_TOKEN:
        required: true

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
      - run: npm ci && npm test
        env:
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
yaml
# .github/workflows/ci.yml (the caller)
on: [push, pull_request]

jobs:
  run-tests:
    uses: my-org/shared-workflows/.github/workflows/reusable-test.yml@main
    with:
      node-version: "22"
    secrets:
      NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

GitHub Actionsで最もよくあるYAMLの間違い

  • ステップのインデントが間違っている。 ステップはsteps:の下に一貫したスペースでインデントする必要があります。1つのスペースが多いか少ないかでステップがJobの外に移動してしまいます。
  • バージョン番号を引用符で囲んでいない。 node-version: 20は整数を渡します。一部のActionsは文字列を期待します。安全のためにnode-version: "20"を使用してください。
  • シェルスクリプトに|の代わりに>を使用している。 フォールデッドスカラーは改行を折りたたみます。マルチラインスクリプトが1つの長い文字列になり失敗します。
  • globパターンに引用符がない。 release/**のようなパターンにはYAMLがエイリアスとして解釈する可能性のある*が含まれています。globパターンは常に引用符で囲んでください。
  • if:条件でシークレットを使用している。 GitHubはログでシークレットをマスクしますが、if:式では許可されていません。代わりに環境変数を使用してください。
  • MatrixジョブでのFail-fast: falseを忘れている。 デフォルトでは、1つのMatrixジョブが失敗すると他のすべてがキャンセルされます。デバッグ中は通常これは望ましくありません。

まとめ

GitHub Actionsのワークフローは根本的にYAMLファイルです—YAMLのリテラルブロックスカラー、 引用符ルール、型変換を理解することは、より信頼性の高いCIを書くことに直結します。最も一般的な失敗は インデントミス、間違った型に変換される引用符のない値、シェルスクリプトへの誤ったマルチライン文字列演算子の使用から来ます。 この3点を正しく理解すれば、ほとんどのワークフローのデバッグが簡単になります。 pushする前にYAML バリデータで構文エラーをキャッチし、 ワークフローファイル全体で一貫したインデントを適用するためにYAML フォーマッターを使用してください。