これまでに書いたすべてのGitHub Actionsワークフローはすべてがそれぞれ1つのYAMLファイルです。トリガー、Job、 ステップ、環境変数、Matrix戦略—すべてがYAMLで表現されます。つまりYAMLを深く理解することは 単に学術的なことではありません:これはリリースをデプロイしようとしている金曜日の午後4時に謎めいた障害が発生する 信頼性のないCIと、確実に動作するCIの違いです。
GitHub Actionsには優れた ワークフロー構文ドキュメントがありますが、 Actionsの機能に焦点を当てており、基盤となるYAMLメカニクスには触れていません。この記事では両方— ワークフロー構造と、CI設定を成功または失敗させるYAML固有のパターン(および落とし穴)—をカバーします。
ワークフロー構造:トップレベルのキー
GitHub Actionsのワークフローファイルは.github/workflows/に置かれ、3つの必須トップレベルキーを持ちます。
公式ワークフローの概要では
ファイルがリポジトリ内のどこにあるか、GitHubがどのように検出するかを説明しています:
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 testonに注意: YAML 1.1では、裸の単語onは
ブール値trueとして解釈されます。GitHubのパーサーはこれを正しく処理しますが、汎用YAMLリンターで
ワークフローファイルにフラグが立てられた場合、これが理由です。安全な形式は引用符で囲むことです:
"on": — ただしGitHub Actions自体は引用符を必要としません。トリガー:on:キー
on:キーはワークフローがいつ実行されるかを制御します。
トリガーイベントの完全なリストでは
プルリクエストのレビューからリポジトリのディスパッチまですべてをカバーしています。最も一般的なパターンを紹介します:
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行にコマンドを連結することになり、読みにくくなります:
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のコンテキストおよび式構文を組み合わせて使用します。 どのように組み合わさるかを見てみましょう:
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回ずつ実行します:
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値ではありません:
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:を使用します:
# .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 }}# .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 フォーマッターを使用してください。