GitHub Actions コンテキスト&式の早見表:fromJson/toJson/hashFiles まで
GitHub Actions でワークフローを書いていると、${{ }} の中で使える便利な機能がたくさんあることに気づきますよね。でも、いざ使おうとすると「あれ、この関数って何だっけ?」「コンテキストってどうアクセスするんだっけ?」と迷ってしまうことも多いのではないでしょうか。
本記事では、GitHub Actions のコンテキストと**式(Expression)**について、実務でよく使う機能を早見表形式でまとめました。fromJson、toJson、hashFiles といった便利な関数の使い方を、具体例とともにわかりやすく解説します。これを読めば、GitHub Actions の表現力がグッと広がり、より柔軟なワークフローが書けるようになるでしょう。
早見表:主要なコンテキスト一覧
GitHub Actions で利用できる主要なコンテキストを以下の表にまとめました。
| # | コンテキスト名 | 概要 | よく使うプロパティ例 | 利用シーン |
|---|---|---|---|---|
| 1 | github | イベント、リポジトリ、コミット情報 | github.event_name, github.sha, github.ref | ブランチ名取得、コミット SHA 参照 |
| 2 | env | 環境変数(グローバル・ジョブ・ステップ) | env.NODE_ENV, env.API_KEY | 環境変数の参照 |
| 3 | job | 現在のジョブ情報 | job.status, job.container.id | ジョブステータス確認 |
| 4 | steps | 前ステップの出力・結果 | steps.<step_id>.outputs, steps.<step_id>.outcome | ステップ間のデータ受け渡し |
| 5 | runner | ランナー環境情報 | runner.os, runner.temp, runner.tool_cache | OS 判定、一時ディレクトリ利用 |
| 6 | secrets | リポジトリ・Organization のシークレット | secrets.GITHUB_TOKEN, secrets.DEPLOY_KEY | 認証情報の安全な参照 |
| 7 | inputs | ワークフロー呼び出し時の入力 | inputs.environment, inputs.version | 再利用可能ワークフローのパラメータ |
| 8 | matrix | マトリックス戦略の現在値 | matrix.os, matrix.node-version | 複数環境での並列実行 |
早見表:主要な式関数一覧
GitHub Actions で利用できる便利な式関数を以下の表にまとめました。
| # | 関数名 | 構文例 | 戻り値 | 用途 |
|---|---|---|---|---|
| 1 | fromJson | fromJson('{"key":"value"}') | オブジェクト | JSON 文字列をオブジェクトに変換 |
| 2 | toJson | toJson(github.event) | 文字列 | オブジェクトを JSON 文字列に変換 |
| 3 | hashFiles | hashFiles('**/package-lock.json') | 文字列 | ファイルのハッシュ値を計算(キャッシュキーに使用) |
| 4 | format | format('Hello {0}', 'World') | 文字列 | フォーマット文字列の生成 |
| 5 | contains | contains(github.ref, 'main') | 真偽値 | 文字列・配列に値が含まれるか判定 |
| 6 | startsWith | startsWith(github.ref, 'refs/tags/') | 真偽値 | 文字列が特定の値で始まるか判定 |
| 7 | endsWith | endsWith(github.ref, '/main') | 真偽値 | 文字列が特定の値で終わるか判定 |
| 8 | join | join(matrix.os, '-') | 文字列 | 配列を区切り文字で結合 |
| 9 | success() | if: success() | 真偽値 | 前のステップが成功したか判定 |
| 10 | failure() | if: failure() | 真偽値 | 前のステップが失敗したか判定 |
| 11 | always() | if: always() | 真偽値 | 常に実行(ステップ結果に関わらず) |
| 12 | cancelled() | if: cancelled() | 真偽値 | ワークフローがキャンセルされたか判定 |
背景
GitHub Actions の式とコンテキストの役割
GitHub Actions でワークフローを記述する際、静的な設定だけでは柔軟な処理を実現できません。たとえば、以下のようなニーズがあります。
- プルリクエストのブランチ名に応じて、デプロイ先の環境を切り替えたい
- 前のステップで生成されたビルド成果物のパスを、次のステップで使いたい
- 複数の OS やバージョンでテストを並列実行し、結果を統合したい
- キャッシュキーをファイルの内容に基づいて動的に生成したい
これらを実現するために、GitHub Actions では**式(Expression)とコンテキスト(Context)**という仕組みが用意されています。
mermaidflowchart TB
workflow["ワークフロー実行"]
context["コンテキスト<br/>(実行環境の情報)"]
expression["式<br/>(動的な値の計算)"]
action["アクション実行"]
workflow --> context
context --> expression
expression --> action
context -.-> |"github, env, steps など"| expression
expression -.-> |"fromJson, contains, hashFiles など"| action
上図のように、コンテキストは実行時の情報(イベント、環境変数、前ステップの結果など)を保持し、式はそれらを組み合わせて動的に値を計算します。この 2 つを組み合わせることで、GitHub Actions の表現力が飛躍的に高まるのです。
式の基本構文
式は ${{ }} で囲んで記述します。この中では、JavaScript に似た構文で条件分岐、関数呼び出し、プロパティアクセスなどが可能です。
typescript// 基本的な式の構文
${{ expression }}
yaml# 実際の使用例
steps:
- name: Conditional step
if: ${{ github.ref == 'refs/heads/main' }}
run: echo "This is main branch"
ここでは github.ref というコンテキストプロパティにアクセスし、== 演算子で比較しています。if 条件での利用が最も一般的ですが、run、with、env などあらゆる場所で式を活用できます。
課題
GitHub Actions の式・コンテキストで直面する課題
GitHub Actions を使い始めると、以下のような課題に直面することが多いでしょう。
課題 1:どのコンテキストを使えばよいか分からない
GitHub Actions には github、env、job、steps、runner、secrets、inputs、matrix など、多数のコンテキストが存在します。初めて使うときは、「イベント情報はどこから取得するの?」「前のステップの出力はどうやって参照するの?」と迷ってしまいがちです。
課題 2:JSON データの扱い方が分からない
GitHub Actions では、イベントペイロードやステップの出力が JSON 形式で提供されることがあります。しかし、そのままでは文字列として扱われるため、オブジェクトとして操作するには fromJson 関数が必要です。逆に、オブジェクトを JSON 文字列に変換する toJson も必要になる場面があります。
課題 3:キャッシュキーの生成が難しい
依存関係のキャッシュを効率的に使うには、ファイルの内容に基づいたハッシュ値をキャッシュキーに含める必要があります。hashFiles 関数を使えば簡単に実現できますが、使い方を知らないと手動でハッシュを計算しようとして複雑になってしまいます。
課題 4:条件分岐の書き方が複雑
複数の条件を組み合わせたり、文字列の一部を判定したりする際、どの関数を使えばよいか分からないことがあります。contains、startsWith、endsWith などの関数を知っていれば簡潔に書けますが、知らないと冗長なスクリプトを書いてしまいがちです。
mermaidflowchart LR
start["ワークフロー記述"]
problem1["どのコンテキスト?"]
problem2["JSON の扱い方?"]
problem3["ハッシュ計算?"]
problem4["条件分岐が複雑"]
start --> problem1
start --> problem2
start --> problem3
start --> problem4
これらの課題を解決するには、GitHub Actions の式とコンテキストの体系的な理解が必要です。
解決策
コンテキストの活用方法
GitHub Actions のコンテキストは、実行環境のさまざまな情報にアクセスするための仕組みです。ここでは、主要なコンテキストの使い方を具体的に見ていきましょう。
github コンテキスト
github コンテキストは、イベント、リポジトリ、コミットに関する情報を提供します。最も頻繁に使うコンテキストと言えるでしょう。
yaml# github コンテキストの基本的な使い方
name: GitHub Context Example
on: [push, pull_request]
jobs:
context_example:
runs-on: ubuntu-latest
steps:
- name: Display event information
run: |
echo "Event name: ${{ github.event_name }}"
echo "Repository: ${{ github.repository }}"
echo "Branch: ${{ github.ref }}"
echo "Commit SHA: ${{ github.sha }}"
このステップでは、トリガーされたイベント名、リポジトリ名、ブランチ名、コミット SHA を表示しています。これらの情報は、条件分岐やタグ付けなどに活用できます。
yaml# ブランチ名に応じた条件分岐
- name: Deploy to production
if: ${{ github.ref == 'refs/heads/main' }}
run: echo "Deploying to production"
- name: Deploy to staging
if: ${{ startsWith(github.ref, 'refs/heads/develop') }}
run: echo "Deploying to staging"
github.ref は完全なリファレンス名(refs/heads/main など)を返すため、比較時には注意が必要です。startsWith 関数を使うと、プレフィックスマッチングが簡単に行えます。
steps コンテキスト
steps コンテキストは、前のステップの出力や結果を参照するために使います。ステップ間でデータを受け渡す際に非常に便利です。
yaml# steps コンテキストの使い方
- name: Generate version
id: version
run: echo "version=1.2.3" >> $GITHUB_OUTPUT
- name: Use version
run: echo "Version is ${{ steps.version.outputs.version }}"
ここでは、id: version で識別されたステップが version という出力を生成し、次のステップで steps.version.outputs.version として参照しています。
yaml# ステップの実行結果を判定
- name: Run tests
id: test
continue-on-error: true
run: npm test
- name: Handle test failure
if: ${{ steps.test.outcome == 'failure' }}
run: echo "Tests failed, but continuing"
outcome プロパティは、ステップが成功したか失敗したかを success または failure として返します。continue-on-error: true と組み合わせることで、失敗後の処理を柔軟に制御できます。
env コンテキスト
env コンテキストは、環境変数にアクセスするために使います。ワークフロー、ジョブ、ステップの各レベルで定義できます。
yaml# env コンテキストの使い方
env:
GLOBAL_VAR: global
jobs:
env_example:
runs-on: ubuntu-latest
env:
JOB_VAR: job_level
steps:
- name: Display environment variables
env:
STEP_VAR: step_level
run: |
echo "Global: ${{ env.GLOBAL_VAR }}"
echo "Job: ${{ env.JOB_VAR }}"
echo "Step: ${{ env.STEP_VAR }}"
このように、スコープの異なる環境変数を階層的に定義できます。同名の変数がある場合、より狭いスコープが優先されます。
runner コンテキスト
runner コンテキストは、ジョブを実行しているランナーの情報を提供します。OS に応じた処理の分岐などに使えます。
yaml# runner コンテキストの使い方
- name: OS-specific command
run: |
echo "OS: ${{ runner.os }}"
echo "Temp directory: ${{ runner.temp }}"
echo "Tool cache: ${{ runner.tool_cache }}"
- name: Install dependencies (Ubuntu)
if: ${{ runner.os == 'Linux' }}
run: sudo apt-get install -y some-package
- name: Install dependencies (macOS)
if: ${{ runner.os == 'macOS' }}
run: brew install some-package
runner.os は Linux、macOS、Windows のいずれかを返すため、OS 固有の処理を簡単に分岐できます。
JSON 操作関数:fromJson と toJson
GitHub Actions では、JSON データの変換が頻繁に必要になります。fromJson と toJson は、その変換を担う重要な関数です。
fromJson 関数
fromJson は、JSON 文字列をオブジェクトに変換します。主に、外部から取得した JSON データや、ステップの出力を構造化データとして扱う際に使います。
yaml# fromJson の基本的な使い方
jobs:
json_example:
runs-on: ubuntu-latest
steps:
- name: Parse JSON string
id: parse
run: |
json='{"name":"MyApp","version":"1.0.0","tags":["stable","latest"]}'
echo "data=$json" >> $GITHUB_OUTPUT
- name: Access parsed data
run: |
echo "Name: ${{ fromJson(steps.parse.outputs.data).name }}"
echo "Version: ${{ fromJson(steps.parse.outputs.data).version }}"
ここでは、JSON 文字列を fromJson で変換し、ドット記法でプロパティにアクセスしています。
yaml# マトリックス戦略での活用
jobs:
matrix_from_json:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Set matrix
id: set-matrix
run: |
matrix='{"os":["ubuntu-latest","macos-latest"],"node":["16","18","20"]}'
echo "matrix=$matrix" >> $GITHUB_OUTPUT
test:
needs: matrix_from_json
runs-on: ${{ matrix.os }}
strategy:
matrix: ${{ fromJson(needs.matrix_from_json.outputs.matrix) }}
steps:
- name: Test
run: echo "Testing on ${{ matrix.os }} with Node ${{ matrix.node }}"
動的にマトリックス戦略を生成できるため、外部ファイルや API から設定を読み込む際に非常に便利です。
toJson 関数
toJson は、オブジェクトを JSON 文字列に変換します。デバッグやログ出力、外部サービスへのデータ送信などに使います。
yaml# toJson の基本的な使い方
- name: Display GitHub event
run: echo '${{ toJson(github.event) }}'
- name: Display matrix values
run: echo '${{ toJson(matrix) }}'
toJson を使うと、構造化データを見やすく出力できます。特に、github.event の内容を確認する際に重宝します。
yaml# 条件分岐での活用
- name: Check pull request labels
if: ${{ contains(toJson(github.event.pull_request.labels.*.name), 'deploy') }}
run: echo "Deploy label found"
ここでは、プルリクエストのラベル配列を JSON 文字列に変換し、contains 関数で特定のラベルが含まれているか判定しています。
ハッシュ計算:hashFiles 関数
hashFiles 関数は、指定したパターンに一致するファイルの内容から SHA-256 ハッシュを計算します。キャッシュキーの生成に最適です。
yaml# hashFiles の基本的な使い方
- name: Cache dependencies
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
このように、package-lock.json の内容が変わるとハッシュ値が変わり、新しいキャッシュが作成されます。内容が同じであれば同じハッシュ値が返されるため、効率的なキャッシュ管理が可能です。
yaml# 複数ファイルのハッシュ計算
- name: Cache with multiple files
uses: actions/cache@v3
with:
path: |
~/.cargo
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock', '**/Cargo.toml') }}
複数のファイルパターンをカンマ区切りで指定することもできます。この場合、すべてのファイルの内容を組み合わせてハッシュが計算されます。
yaml# グロブパターンの活用
- name: Cache Python dependencies
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('requirements/**/*.txt') }}
**/ を使うことで、ディレクトリ階層を再帰的に検索できます。requirements ディレクトリ配下のすべての .txt ファイルが対象になります。
文字列判定関数:contains、startsWith、endsWith
文字列や配列の判定には、専用の関数を使うと簡潔に書けます。
yaml# contains の使い方
- name: Check branch
if: ${{ contains(github.ref, 'feature') }}
run: echo "This is a feature branch"
- name: Check commit message
if: ${{ contains(github.event.head_commit.message, '[skip ci]') }}
run: echo "CI skip requested"
contains は、第 1 引数が第 2 引数を含むかどうかを判定します。文字列だけでなく、配列に対しても使えます。
yaml# startsWith と endsWith の使い方
- name: Deploy on tag
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
run: echo "Deploying version tag"
- name: Check file extension
if: ${{ endsWith(github.event.head_commit.modified[0], '.md') }}
run: echo "Markdown file modified"
startsWith は先頭一致、endsWith は末尾一致を判定します。バージョンタグの判定やファイル拡張子のチェックに便利です。
フォーマット関数:format と join
文字列の生成には、format と join が役立ちます。
yaml# format の使い方
- name: Format message
run: |
message="${{ format('Deploying {0} to {1} environment', github.sha, 'production') }}"
echo "$message"
- name: Format with multiple placeholders
run: |
echo "${{ format('Build {0} on {1} completed at {2}', github.run_number, runner.os, github.event.head_commit.timestamp) }}"
format は、プレースホルダー {0}、{1}、{2} などに引数を埋め込みます。可読性の高いメッセージ生成に便利です。
yaml# join の使い方
- name: Join array
run: |
tags="${{ join(fromJson('["v1.0.0","latest","stable"]'), ', ') }}"
echo "Tags: $tags"
- name: Join matrix values
run: |
echo "Testing: ${{ join(matrix.*, '-') }}"
join は、配列の要素を指定した区切り文字で結合します。タグのリストやマトリックス値の表示に活用できます。
ステップ制御関数:success、failure、always、cancelled
ステップの実行条件を制御する関数も重要です。
yaml# ステップ制御関数の使い方
- name: Run tests
id: test
run: npm test
- name: On success
if: ${{ success() }}
run: echo "All previous steps succeeded"
- name: On failure
if: ${{ failure() }}
run: echo "Some step failed"
- name: Cleanup
if: ${{ always() }}
run: echo "This always runs"
- name: On cancelled
if: ${{ cancelled() }}
run: echo "Workflow was cancelled"
これらの関数を使うことで、エラーハンドリングやクリーンアップ処理を柔軟に制御できます。
具体例
具体例 1:動的マトリックス戦略の構築
外部ファイルから設定を読み込み、動的にマトリックス戦略を構築する例を見てみましょう。
json// .github/test-config.json
{
"os": ["ubuntu-latest", "macos-latest", "windows-latest"],
"node": ["16", "18", "20"],
"exclude": [{ "os": "windows-latest", "node": "16" }]
}
この設定ファイルを読み込んで、マトリックステストを実行するワークフローを作成します。
yaml# 動的マトリックス戦略のワークフロー
name: Dynamic Matrix Test
on: [push, pull_request]
jobs:
setup:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Read test configuration
id: set-matrix
run: |
config=$(cat .github/test-config.json)
echo "matrix=$config" >> $GITHUB_OUTPUT
最初のジョブでは、設定ファイルを読み込み、出力として保存しています。cat コマンドでファイル内容を取得し、$GITHUB_OUTPUT に書き込むことで、次のジョブで利用できるようにしています。
yamltest:
needs: setup
runs-on: ${{ matrix.os }}
strategy:
matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- name: Display test environment
run: |
echo "OS: ${{ matrix.os }}"
echo "Node: ${{ matrix.node }}"
echo "Runner: ${{ runner.os }}"
fromJson で設定を変換し、マトリックス戦略として展開しています。これにより、設定ファイルを編集するだけでテスト環境を柔軟に変更できます。
yaml- name: Cache dependencies
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-node-${{ matrix.node }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-${{ matrix.node }}-
${{ runner.os }}-node-
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Run tests
run: yarn test
キャッシュキーには、OS、Node バージョン、package-lock.json のハッシュを組み合わせています。これにより、環境ごとに適切なキャッシュが使われます。
具体例 2:プルリクエストのラベルに基づいた自動デプロイ
プルリクエストに特定のラベルが付いている場合のみデプロイを実行する例です。
yaml# ラベルベースの自動デプロイワークフロー
name: Auto Deploy
on:
pull_request:
types: [labeled, synchronize]
jobs:
check-label:
runs-on: ubuntu-latest
outputs:
should-deploy: ${{ steps.check.outputs.deploy }}
environment: ${{ steps.check.outputs.env }}
steps:
- name: Check labels
id: check
run: |
labels='${{ toJson(github.event.pull_request.labels.*.name) }}'
echo "Labels: $labels"
if echo "$labels" | grep -q "deploy:production"; then
echo "deploy=true" >> $GITHUB_OUTPUT
echo "env=production" >> $GITHUB_OUTPUT
elif echo "$labels" | grep -q "deploy:staging"; then
echo "deploy=true" >> $GITHUB_OUTPUT
echo "env=staging" >> $GITHUB_OUTPUT
else
echo "deploy=false" >> $GITHUB_OUTPUT
echo "env=none" >> $GITHUB_OUTPUT
fi
ラベル情報を toJson で JSON 文字列に変換し、grep で特定のラベルを検索しています。結果を出力として保存し、次のジョブで利用します。
yamldeploy:
needs: check-label
if: ${{ needs.check-label.outputs.should-deploy == 'true' }}
runs-on: ubuntu-latest
environment:
name: ${{ needs.check-label.outputs.environment }}
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Display deployment info
run: |
echo "Deploying to: ${{ needs.check-label.outputs.environment }}"
echo "Branch: ${{ github.head_ref }}"
echo "Commit: ${{ github.event.pull_request.head.sha }}"
- name: Deploy to environment
run: |
echo "Deploying application..."
# デプロイコマンドを実行
前のジョブの出力を参照し、デプロイの実行可否と環境を判定しています。if 条件により、ラベルが付いている場合のみジョブが実行されます。
具体例 3:複数ファイルのハッシュを使ったキャッシュ戦略
モノレポ構成で、複数のプロジェクトが異なる依存関係を持つ場合のキャッシュ戦略です。
yaml# モノレポのキャッシュ戦略
name: Monorepo Build
on: [push]
jobs:
build-frontend:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Cache frontend dependencies
uses: actions/cache@v3
with:
path: frontend/node_modules
key: frontend-${{ runner.os }}-${{ hashFiles('frontend/package-lock.json', 'frontend/yarn.lock') }}
restore-keys: |
frontend-${{ runner.os }}-
- name: Install frontend dependencies
working-directory: frontend
run: yarn install --frozen-lockfile
- name: Build frontend
working-directory: frontend
run: yarn build
frontend ディレクトリの依存関係ファイルのみをハッシュ計算の対象にすることで、無駄なキャッシュ再生成を防いでいます。
yamlbuild-backend:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Cache backend dependencies
uses: actions/cache@v3
with:
path: |
backend/node_modules
backend/.yarn/cache
key: backend-${{ runner.os }}-${{ hashFiles('backend/package-lock.json', 'backend/.yarnrc.yml') }}
restore-keys: |
backend-${{ runner.os }}-
- name: Install backend dependencies
working-directory: backend
run: yarn install --immutable
- name: Build backend
working-directory: backend
run: yarn build
バックエンドも同様に、独自の依存関係ファイルでキャッシュキーを生成しています。複数のパスをキャッシュ対象に含めることもできます。
yamlintegration-test:
needs: [build-frontend, build-backend]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Cache all dependencies
uses: actions/cache@v3
with:
path: |
frontend/node_modules
backend/node_modules
key: all-deps-${{ runner.os }}-${{ hashFiles('**/package-lock.json', '**/.yarnrc.yml') }}
- name: Run integration tests
run: yarn test:integration
統合テストでは、すべてのプロジェクトの依存関係をまとめてキャッシュしています。**/ パターンで、すべてのディレクトリから該当ファイルを検索できます。
具体例 4:条件付きステップ実行とエラーハンドリング
複雑な条件分岐とエラーハンドリングを組み合わせた例です。
yaml# 条件付きステップとエラーハンドリング
name: Advanced Workflow
on: [push, pull_request]
jobs:
test-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Check if tests should run
id: should-test
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]] || [[ "${{ contains(github.event.head_commit.message, '[test]') }}" == "true" ]]; then
echo "run=true" >> $GITHUB_OUTPUT
else
echo "run=false" >> $GITHUB_OUTPUT
fi
プルリクエストの場合、またはコミットメッセージに [test] が含まれる場合にテストを実行する判定をしています。
yaml- name: Run unit tests
id: unit-test
if: ${{ steps.should-test.outputs.run == 'true' }}
continue-on-error: true
run: yarn test:unit
- name: Run integration tests
id: integration-test
if: ${{ steps.should-test.outputs.run == 'true' && steps.unit-test.outcome == 'success' }}
continue-on-error: true
run: yarn test:integration
ユニットテストが成功した場合のみ、統合テストを実行しています。continue-on-error により、失敗してもワークフローは継続します。
yaml- name: Report test results
if: ${{ always() && steps.should-test.outputs.run == 'true' }}
run: |
unit_result="${{ steps.unit-test.outcome }}"
integration_result="${{ steps.integration-test.outcome }}"
echo "Unit tests: $unit_result"
echo "Integration tests: $integration_result"
if [[ "$unit_result" == "failure" ]] || [[ "$integration_result" == "failure" ]]; then
echo "::error::Some tests failed"
exit 1
fi
テスト結果をまとめて報告し、いずれかが失敗していればワークフロー全体を失敗させています。always() により、前のステップが失敗しても必ず実行されます。
yaml- name: Deploy on success
if: ${{ success() && github.ref == 'refs/heads/main' }}
run: |
echo "All tests passed, deploying..."
# デプロイコマンドを実行
- name: Cleanup on failure
if: ${{ failure() }}
run: |
echo "Workflow failed, cleaning up..."
# クリーンアップコマンドを実行
- name: Always cleanup
if: ${{ always() }}
run: |
echo "Performing final cleanup..."
# 最終クリーンアップコマンドを実行
成功時のデプロイ、失敗時のクリーンアップ、常に実行される最終処理を、それぞれの条件関数で制御しています。
具体例 5:イベントペイロードの活用
github.event から詳細な情報を取得し、柔軟な処理を実現する例です。
yaml# イベントペイロードの活用
name: Event Payload Example
on:
pull_request:
types: [opened, synchronize, reopened]
issue_comment:
types: [created]
jobs:
handle-event:
runs-on: ubuntu-latest
steps:
- name: Display full event payload
run: echo '${{ toJson(github.event) }}'
- name: Handle pull request event
if: ${{ github.event_name == 'pull_request' }}
run: |
echo "PR Number: ${{ github.event.pull_request.number }}"
echo "PR Title: ${{ github.event.pull_request.title }}"
echo "PR Author: ${{ github.event.pull_request.user.login }}"
echo "Base Branch: ${{ github.event.pull_request.base.ref }}"
echo "Head Branch: ${{ github.event.pull_request.head.ref }}"
プルリクエストイベントでは、番号、タイトル、作成者、ブランチ名などの詳細情報にアクセスできます。
yaml- name: Check changed files
if: ${{ github.event_name == 'pull_request' }}
run: |
files='${{ toJson(github.event.pull_request.changed_files) }}'
echo "Changed files count: $files"
# ファイルの差分を取得してチェック
git fetch origin ${{ github.event.pull_request.base.ref }}
changed_files=$(git diff --name-only origin/${{ github.event.pull_request.base.ref }}...HEAD)
if echo "$changed_files" | grep -q "^src/"; then
echo "Source files changed, running tests"
fi
変更されたファイルの情報を元に、必要なテストやビルドを判断できます。
yaml- name: Handle issue comment event
if: ${{ github.event_name == 'issue_comment' }}
run: |
echo "Comment Author: ${{ github.event.comment.user.login }}"
echo "Comment Body: ${{ github.event.comment.body }}"
echo "Issue Number: ${{ github.event.issue.number }}"
# コメント内容に基づいた処理
comment="${{ github.event.comment.body }}"
if [[ "$comment" == "/deploy"* ]]; then
echo "Deploy command detected"
# デプロイ処理を実行
fi
コメントイベントでは、コメント内容や Issue 番号にアクセスし、チャットオプス的な操作が可能です。
yaml- name: Check user permissions
if: ${{ github.event_name == 'issue_comment' }}
run: |
author="${{ github.event.comment.user.login }}"
author_association="${{ github.event.comment.author_association }}"
echo "Author: $author"
echo "Association: $author_association"
if [[ "$author_association" == "OWNER" ]] || [[ "$author_association" == "MEMBER" ]]; then
echo "User has required permissions"
else
echo "User does not have required permissions"
exit 1
fi
コメント作成者の権限を確認し、適切な権限を持つユーザーのみが操作できるように制御しています。
まとめ
GitHub Actions のコンテキストと式は、ワークフローの表現力を大きく高める強力な機能です。本記事では、以下の内容を解説しました。
- 主要なコンテキスト:
github、env、job、steps、runner、secrets、inputs、matrixの使い方と活用シーン - JSON 操作関数:
fromJsonでオブジェクトに変換、toJsonで JSON 文字列に変換する方法 - ハッシュ計算:
hashFilesでファイルの内容からハッシュを生成し、効率的なキャッシュ管理を実現 - 文字列判定関数:
contains、startsWith、endsWithで柔軟な条件分岐を記述 - フォーマット関数:
formatとjoinで読みやすいメッセージを生成 - ステップ制御関数:
success()、failure()、always()、cancelled()でエラーハンドリングとクリーンアップを制御
これらの機能を組み合わせることで、動的なマトリックス戦略、条件付きデプロイ、複雑なエラーハンドリングなど、高度なワークフローを実現できます。
早見表を手元に置きながら、ぜひ実際のプロジェクトで活用してみてください。GitHub Actions の柔軟性を最大限に引き出し、より効率的な CI/CD パイプラインを構築できるでしょう。
関連リンク
articleGitHub Actions コンテキスト&式の早見表:fromJson/toJson/hashFiles まで
articleGitHub Actions で PostgreSQL/Redis を services で立ち上げるテスト基盤レシピ
articleGitHub Actions 署名戦略を比べる:SHA ピン留め vs タグ参照 vs バージョン範囲
articleGitHub Actions のキャッシュがヒットしない原因 10 と対処レシピ
articleGitHub Actions コンテキスト辞典:github/env/runner/secrets の使い分け最速理解
articleGitHub Actions 実行コストを見える化:Usage API でジョブ別分析ダッシュボード
articleLangChain 再ランキング手法の実測:Cohere/OpenAI ReRank/Cross-Encoder の効果
articleJotai 非同期で Suspense が発火しない問題の切り分けガイド
articleJest moduleNameMapper 早見表:パスエイリアス/静的アセット/CSS を一網打尽
articleComfyUI ワークフロー設計 101:入力 → 前処理 → 生成 → 後処理 → 出力の責務分離
articleGitHub Copilot でリファクタ促進プロンプト集:命名・抽象化・分割・削除の誘導文
articleCodex で既存コードを読み解く:要約・設計意図抽出・依存関係マップ化
blogiPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
blogGoogleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
blog【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
blogGoogleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
blogPixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
blogフロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
review今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
reviewついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
review愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
review週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
review新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
review科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来