GitHub Actions ワークフロー構文 Tips&チートシート
안녕하신게라!パナソニック コネクト株式会社クラウドソリューション部の加賀です。
GitHub Actions のワークフローを書くとき、「この設定は jobs の直下だっけ? steps の中だっけ?」「複数行のスクリプトはどう書くんだっけ?」と毎回ドキュメントを探しに行く手間を省くためのチートシートです。
GitHub Actions のワークフロー構文 をベースに、よく使うものを階層別にまとめました。
GitHub Actions ワークフローの全体構造
階層構造のイメージです。大きく分けて ルート(name, on, env)、ジョブ(jobs)、ステップ(steps) の3つのレベルがあります。
name: Workflow Name # 1.ルートレベル
run-name: ${{ github.actor }} runs workflow # ルートレベル(Actionsタブの実行一覧に表示される実行名)
on: [push] # ルートレベル(トリガー設定)
env: # ルートレベル(全体共通環境変数)
GLOBAL_ENV: "value"
permissions: # ルートレベル(GITHUB_TOKENの権限設定)
contents: read
id-token: write # OIDC認証(AWS連携など)に必須
defaults: # ルートレベル(デフォルト設定)
run:
shell: bash
jobs:
job_name: # 2.ジョブレベル
runs-on: ubuntu-latest # ジョブレベル(実行環境)
env: # ジョブレベル(ジョブ内環境変数)
JOB_ENV: "value"
steps: # 3.ステップレベル
- name: Step 1 # ステップレベル(タスク名)
uses: actions/checkout@v6
- name: Step 2 (Multi-line)
run: | # 複数行の処理は `|` を使う
echo "Hello"
echo "World"
YAMLファイルを /.github/workflows/ に配置します。
1. ルートレベル (name / on / env 等)
ワークフロー全体に関わる設定を記述します。
| キー | 説明 |
|---|---|
name |
ワークフローの名前(省略時はファイル名) |
run-name |
Actionsタブの実行一覧で個別の実行に対して表示される名前(変数を含められる) |
on |
(必須) ワークフローをトリガーするイベント |
env |
ワークフロー全体で使える環境変数 |
permissions |
ワークフロー内で提供される GITHUB_TOKEN の権限を設定する(read/writeなど) |
defaults.run |
全ての run ステップのデフォルト設定(シェルや作業ディレクトリなど) |
concurrency |
同時実行の制御。グループを指定して古い実行を自動キャンセルするなど |
Tips
-
permissions
リポジトリ設定によっては、デフォルトの権限が広すぎる場合があります。セキュリティ向上のため、ルートレベルでpermissionsを明示(例 制限付きのcontents: read)し、必要に応じて各ジョブで権限を追加・上書きするのがベストプラクティスです。 -
defaults.run
shell: bashを指定しておくと、Windows ランナーでも Bash 挙動で統一できるだけでなく、GitHub Actions の Bash はset -eo pipefailで実行されるため、パイプ途中のコマンドの失敗も明確に検知できるようになり、非常にオススメです。
on のよくある設定パターン
以下は on に使える設定のバリエーションです。実際にはこれらを組み合わせて必要なものだけ記述します。
(types などのリストは一例として網羅的に記載しています)
on:
# ① 単純なイベントトリガー(ブランチ指定などなし)
push:
# ② プルリクエスト(アクティビティタイプの全量に近いリスト)
pull_request:
types:
- opened # 作成された
- synchronize # 新しいコミットがプッシュされた
- reopened # 再オープンされた
- closed # クローズされた(マージ含む)
- labeled # ラベルが付与された
- unlabeled # ラベルが削除された
- edited # タイトルや本文が編集された
- ready_for_review # ドラフトからレビュー可能状態になった
- review_requested # レビューがリクエストされた
branches:
- main
paths-ignore:
- 'docs/**' # トリガーから除外
# ※ paths と paths-ignore は同一イベント内で併用できません。
# 併用したい場合は paths: の中で '!docs/**' のように否定パターンを記述してください。
# ③ Pushイベントの詳細指定
push:
branches: # ブランチでフィルタ
- main
- 'feature/*'
tags: # タグでフィルタ
- 'v*'
paths: # 変更されたファイルパスでフィルタ
- 'src/**'
- '!src/docs/**' # 除外
# ④ 手動実行(入力パラメータを定義可能)
workflow_dispatch:
inputs:
log_level:
description: 'ログレベル'
required: true # 実行時に入力必須(UIに*が表示される)
default: 'warning'
type: choice # セレクトボックス
options:
- info
- warning
- debug
environment:
description: '環境名'
required: true
type: string # 自由入力テキスト
is_force:
description: '強制実行するか'
type: boolean # チェックボックス (チェックあり=true, なし=false)
# ※ boolean型はチェック状態によらず値が担保されるため、required の指定は不要です。
# ただし式の中で評価する際、文字列型の 'true' や 'false' として扱われることがあるため、
# if: ${{ inputs.is_force == true || inputs.is_force == 'true' }} のように比較演算子を丁寧に扱うと安全です。
# ⑤ 定期実行(Cron構文 ※UTC時間)
schedule:
- cron: '0 0 * * *' # 日本時間 朝9時
# ⑥ 再利用可能ワークフローとしての呼び出し定義
workflow_call:
inputs:
env_name:
required: true
type: string
secrets:
token:
required: true
concurrency による同時実行制御
# PR単位で同時実行を1つに絞り、新しいコミットが積まれたら古い実行をキャンセルする
# PR単位(head_ref)とブランチ単位(ref)の両方に対応するベストプラクティス
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
2. ジョブレベル (jobs.<job_id>)
各ジョブの実行環境や、ジョブ間の依存関係などを設定します。
| キー | 説明 |
|---|---|
runs-on |
(必須) 実行するランナー(ubuntu-latest, windows-latest など) |
uses |
再利用可能ワークフロー (Reusable Workflows) を呼び出す場合に指定。 ※ジョブレベルで uses を指定した場合、steps や run など他の多くのキーと共存できません(needs, if, permissions, secrets, with 等のみ許可)。ステップレベルの uses と混同しやすい初心者によくある落とし穴です |
needs |
依存する先行ジョブのID。配列 [job1, job2] で指定。※いずれかが失敗(キャンセル含む)すると後続もスキップされるため、失敗しても続行したい場合は後続ジョブに if: always() 等が別途必要 |
if |
ジョブを実行するかどうかの条件式 |
environment |
デプロイ前の手動承認(Reviewers)を設けたり、特定環境下だけの限定シークレット・変数を保護して使用するための機能(実運用で必須級) |
permissions |
このジョブ内での GITHUB_TOKEN の権限指定 |
defaults.run |
このジョブ内の run に適用されるデフォルト設定 |
env |
このジョブ内でのみ使える環境変数 ※優先順位は「ステップ > ジョブ > ルート(全体)」の順で上書きされます |
strategy.matrix |
複数バージョンの並列テストなどに使うマトリクス変数の定義 ※特定の組み合わせを除外する exclude や、追加する include も指定可能です |
services |
データベース(Redis, MySQLなど)のサービスコンテナを立ち上げる設定 |
container |
ジョブ全体を指定した Docker コンテナ内で実行する設定(言語やツールのバージョン固定に便利) |
outputs |
他のジョブに渡すための出力 (outputs) の定義 |
continue-on-error |
失敗してもエラーとして扱わず、後続処理を続行するかどうか(true/false)※特定の実験的なテスト環境だけ許容する場合はこちらを使います。マトリクス実行全体で「進行中の他のマトリクスジョブをキャンセルしない」場合は strategy.fail-fast: false を使います(デフォルトは true で即時全キャンセル) |
timeout-minutes |
ジョブのタイムアウト時間。(重要) デフォルト360分。事故防止のため内容に応じて短め(10-30分)の設定を推奨 |
permissions の上書き挙動に注意
ルートレベルで permissions を定義している場合、ジョブレベルで permissions を定義すると そのジョブではルートレベルの設定がすべて無効になり、ジョブレベルの設定のみが適用されます(追加・マージではなく、完全な置き換え)。継承して一部だけ変更することはできません。
permissions:
contents: read
issues: read
jobs:
build:
permissions:
contents: write # これだけ書くと issues: read は消え、contents: write のみになる
steps: ...
特定の権限だけを上げたい場合でも、そのジョブで必要な権限をすべて記述する必要があります。
Tips
-
timeout-minutes を必ず設定しよう
デフォルトのタイムアウト時間は 360分(6時間) です。
異常終了などでジョブがスタックしてしまうと、気づくまで課金を消費し続けてしまいます。
timeout-minutes: 10など、内容に応じた現実的な時間を必ず設定する癖をつけましょう。
ジョブレベルの記述例
jobs:
# ① マトリクスを使った並列実行
test-matrix:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20]
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
# ② 出力 (outputs) の定義
build:
runs-on: ubuntu-latest
outputs: # 別のジョブで値を使うために出力 (outputs) を定義
result: ${{ steps.step1.outputs.build_result }}
steps:
- id: step1
run: echo "build_result=success" >> "$GITHUB_OUTPUT"
# ③ 再利用可能ワークフローの呼び出し(他のYAMLを呼ぶ)
call-workflow:
uses: ./.github/workflows/another-workflow.yml
with:
env_name: staging
secrets: inherit # 呼び出し元のシークレットを継承
# ④ 依存関係と環境の指定、出力 (outputs) の参照
deploy:
needs: [test-matrix, build, call-workflow] # 配列で複数指定可能
# buildジョブの出力 (outputs) が success の場合のみ実行
if: github.ref == 'refs/heads/main' && needs.build.outputs.result == 'success'
runs-on: ubuntu-latest
environment: production # Production環境として扱い保護ルールの対象にする
steps:
...
3. ステップレベル (jobs.<job_id>.steps)
ジョブの中で順番に実行される実際のアクションやコマンドを記述します。
| キー | 説明 |
|---|---|
name |
ステップの名前(ログなどで表示される)。省略可能 |
uses |
実行するアクションを指定 (例 actions/checkout@v4) |
run |
実行するコマンド | を使って複数行を記述できる |
shell |
コマンドを実行するシェルを指定 ( bash, pwsh, python など) |
with |
uses で指定したアクションに渡す入力パラメータ |
env |
このステップ内でのみ使える環境変数 |
if |
このステップを実行するかどうかの条件式 |
id |
ステップの一意の識別子。 後続の処理でこのステップの出力を参照する際に使う |
working-directory |
コマンドを実行する作業ディレクトリ |
continue-on-error |
失敗してもエラーとして扱わず、 後続処理を続行するかどうか( true/false) |
timeout-minutes |
そのステップ単体のタイムアウト時間 |
ステップレベルの記述例
steps:
# 既存のアクションを使用する場合
- name: リポジトリのチェックアウト
uses: actions/checkout@v4
# 環境変数(シークレットなど)を使ってコマンドを実行する場合
- name: 依存関係のインストール
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npm install
# 後続のステップで環境変数として読むために特別な環境変数ファイルに書き込む場合
- name: 環境変数のセット
run: echo "MY_ENV_VAR=hello" >> "$GITHUB_ENV"
# 他のジョブに値を渡すための出力 (outputs) のセット
- name: 出力のセット
id: set_output
run: echo "build_result=hello" >> "$GITHUB_OUTPUT"
# 複数行のスクリプトを実行する場合
- name: 複数行の処理
run: |
echo "Step 1"
echo "Step 2"
echo "Step 3"
# 前のステップの成否などで条件分岐
- name: 失敗時のみ実行
if: failure()
run: echo "前のステップが失敗しました"
4. よく使うコンテキスト・記法
変数を参照する際は ${{ ... }} の構文を使います(run のシェル変数 $VAR とは別物なので注意)。
github コンテキスト(ワークフロー実行情報)
| プロパティ | 説明 | 例 |
|---|---|---|
github.repository |
リポジトリ名 (所有者/リポジトリ) |
octocat/Hello-World |
github.ref |
ブランチやタグの 完全な参照パス |
refs/heads/main※PR時は refs/pull/123/merge などになる点に注意 |
github.ref_name |
短縮形のブランチ名やタグ名 |
main, v1.0
|
github.sha |
コミットの完全なSHAハッシュ | ffac537e... |
github.event_name |
イベント名 |
push, pull_request
|
github.actor |
実行したユーザー | octocat |
github.workflow |
ワークフロー名 | Build & Deploy |
github.run_id |
実行固有のID (ログURLなどの生成に利用) |
1658821493 |
github.run_number |
実行回数 (1から増加) |
3 |
github.workspace |
ステップが実行されるデフォルトの作業ディレクトリの絶対パス (checkoutアクションでクローンされる場所) |
/home/runner/work/repo/repo |
github.server_url |
GitHubサーバーのURL | https://github.com |
その他の重要コンテキスト
※ YAML内に直接記述する env (ワークフロー定義変数)、GitHubのGUIで管理する vars (非機密の構成変数)、secrets (暗号化される機密変数) はそれぞれ用途が異なります。
| コンテキスト | 説明 | 利用例 |
|---|---|---|
secrets |
設定された機密情報(※1 自動マスク) | ${{ secrets.AWS_ACCESS_KEY_ID }} |
vars |
Org, Repo, Env レベルで設定された非機密の構成変数 | ${{ vars.ENVIRONMENT_NAME }} |
env |
ワークフロー内で定義した変数 | ${{ env.MY_ENV_VAR }} |
inputs |
workflow_dispatch / workflow_call 時の入力値 |
${{ inputs.target_env }} |
steps |
ステップの情報 (出力や結果) |
${{ steps.step_id.outputs.output_name }}${{ steps.step_id.conclusion }}
|
needs |
依存ジョブの出力情報 | ${{ needs.job_id.outputs.output_name }} |
runner |
ランナーの情報 |
${{ runner.os }} (Linux/Windows/macOS)${{ runner.arch }} (X64, ARM64)${{ runner.temp }} (一時ディレクトリ) |
matrix |
マトリクス実行時の現在の値 | ${{ matrix.node-version }} |
特殊な環境変数(ファイルパス)
コンテキスト(${{ }})ではなく、ランナーのシェル上で利用できる特殊な環境変数です。これらは特殊なファイルへのパスとなっており、ファイルに追記することでGitHub Actionsに値を渡します。
| 環境変数 | 説明 | 利用例 |
|---|---|---|
GITHUB_ENV |
環境変数を設定する特殊ファイル | echo "VAR=val" >> "$GITHUB_ENV" |
GITHUB_OUTPUT |
ステップの出力(outputs)を設定する特殊ファイル |
echo "VAR=val" >> "$GITHUB_OUTPUT" |
GITHUB_STEP_SUMMARY |
実行サマリ(Markdown)出力先 | echo "### Result" >> "$GITHUB_STEP_SUMMARY" |
※1 シークレットの自動マスクの限界
${{ secrets.XXX }} の値はログ出力時に *** と自動でマスクされますが、スクリプト内で Base64 エンコードしたり、1文字ずつ加工したりするとマスク処理をすり抜けて漏洩する恐れがあるため注意してください。
前のステップの出力を参照する使い方
ステップに id を付けることで、後のステップで変数を参照できます。
steps:
- id: generate_value
run: echo "build_result=HelloWorld" >> "$GITHUB_OUTPUT"
- name: 値を利用する
run: echo "生成された値は ${{ steps.generate_value.outputs.build_result }} です"
よく使う関数 (Functions)
条件式や値の生成で使える組み込み関数です。
| 関数 | 説明 | 例 |
|---|---|---|
format |
文字列の埋め込み置換 | format('Hello {0} {1}', 'World', '!') |
join |
配列を文字列に結合 | join(fromJSON('["A", "B"]'), ', ') |
toJSON |
オブジェクトをJSON文字列に変換 (デバッグ出力に便利) |
toJSON(github.event) |
fromJSON |
JSON文字列をオブジェクトに戻す (マトリクスの動的生成などで利用) |
fromJSON(needs.job.outputs.matrix) |
contains |
文字列が含まれるか判定 (配列に対しても使用可能) |
contains(fromJSON('["ubuntu", "windows"]'), runner.os) |
startsWith |
指定文字列で始まるか判定 | startsWith(github.ref, 'refs/tags/v') |
hashFiles |
ファイル群のハッシュ値を計算 (キャッシュキー生成などで利用) |
hashFiles('**/package-lock.json') |
状態チェック関数
if 条件式でよく使う、ジョブやステップのステータス判定関数です。
| 関数 | 説明 | 例 |
|---|---|---|
success() |
前のステップまで全て成功した場合に true (デフォルト) | if: success() |
failure() |
前のステップのいずれかが失敗した場合に true | if: failure() |
cancelled() |
ワークフローがキャンセルされた場合に true | if: cancelled() |
always() |
成功・失敗・キャンセルに関わらず常に実行する場合に true | if: always() |
5. よくある落とし穴とベストプラクティス
利用する上で知っておくとハマりにくいポイントです。
if 条件式での ${{ }} の省略
if キーの右側はデフォルトで式として評価されるため、${{ }} は**基本的に不要(書かなくてよい)**です。format() などの関数を使う場合でも if: format('...') と記述できます。
注意点として、式の先頭が ! で始まる場合はYAMLのタグ指定処理と衝突して構文エラーになります。この場合は ${{ !... }} の形にするか、あるいは if: "!..." や if: '!...' のようにクォーテーションで囲むことで回避できます。
# スッキリした例(推奨)
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
# 冗長な例(文法エラーにはならないが非推奨)
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
$GITHUB_ENV や $GITHUB_OUTPUT のスコープと遅延
echo "MY_ENV_VAR=hello" >> "$GITHUB_ENV"(または $GITHUB_OUTPUT)で設定した変数は、設定したのと同じステップ内では参照できません。次のステップ以降で初めて利用可能になります。同一ステップ内で変数を使い回したい場合は、通常のシェルの変数(MY_ENV_VAR="hello" など)を利用してください。
複数行の環境変数を書き込む際の特殊構文(EOF)とインジェクション対策
$GITHUB_ENV や $GITHUB_OUTPUT に対して、改行を含むテキスト(APIのJSONレスポンスや複数行のログなど)を書き込む場合は、単純な echo ではエラーになり書き込めません。ヒアドキュメント(デリミタ EOF など)を用いた特殊な構文が必要です。
その際、固定の文字列(EOF等)をデリミタにすると、**出力する文字列内に全く同じ EOF が含まれていた場合にそこで代入が終端とみなされ、それ以降の文字列が予期せぬシェルコマンドとして実行されてしまう重大な脆弱性(コマンドインジェクション)**に繋がります。
公式でも推奨されている通り、ランダムなデリミタを生成して使用するのが安全なベストプラクティスです。
- run: |
# ランダムなデリミタを生成
DELIMITER=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
{
echo "MULTI_LINE_VAR<<$DELIMITER"
echo "1行目"
echo "2行目"
echo "$DELIMITER"
} >> "$GITHUB_ENV"
スクリプト内での変数の扱い(インジェクション対策)
${{ }}(コンテキスト式)とシェル変数 $VAR は評価されるタイミングが異なります。${{ }} は GitHub Actions がジョブをランナーに送る前(YAMLのパース時)に単なる文字列の置換として評価されますが、$VAR はランナー上でスクリプトが実行される際にシェルによって評価されます。
そのため、run コマンドの中で ${{ }} を直接埋め込むと、置換後の値に引用符や改行コード、セミコロンなどが含まれていた場合にスクリプトの構文が破損したり、意図しないコマンドが実行される(シェルスクリプトインジェクション)リスクがあります。ユーザー入力や動的な値は、必ず環境変数 (env) 経由で渡すのが安全です。
# 悪い例(インジェクションのリスクあり)
- run: echo "Title is ${{ github.event.issue.title }}"
# 良い例(環境変数経由)
- env:
TITLE: ${{ github.event.issue.title }}
run: echo "Title is $TITLE"
パスフィルタのワイルドカード (Globパターン)
paths や paths-ignore などで使われるファイルパス指定のパターン記法です。
| パターン | 説明 | 例 |
|---|---|---|
* |
パス区切り(/)を含まない任意の文字列にマッチ |
src/*.js (src直下のjsのみ、サブディレクトリは含まない) |
** |
パス区切りを含む任意の文字列にマッチ(再帰的) |
src/**/*.js (src以下の全階層のjs) |
? |
任意の1文字にマッチ | file?.txt |
! |
直前のパターンを除外(否定) | !src/temp/** |
無限ループ防止(GITHUB_TOKENの仕様)と回避策
ワークフロー内で提供される GITHUB_TOKEN を使って、リポジトリに新しくコミットを Push したり、タグを打ったり、PRを作成した場合、その操作によっては新たなワークフローはトリガーされないという仕様があります。これはワークフローが意図せず無限ループするのを防ぐための安全装置です。
別ワークフローを動かしたい場合は、別途トークンを発行して使う必要があります。以前は Personal Access Token (PAT) が使われることが多かったですが、個人に紐づくPATは退職時の権限消失やセキュリティリスクがあるため、現在は GitHub App トークンを発行して使用する ことがベストプラクティスとされています。
フォークからの Pull Request における権限と pull_request_target
pull_request イベントでは、フォークされたリポジトリからのPRの場合、セキュリティ保護のため自動的に GITHUB_TOKEN が Read-only になりシークレットにもアクセスできなくなる仕様があります。
この制約を回避する目的で pull_request_target イベントを使用することがありますが、これはワークフローがPR元の(潜在的に悪意のある)コードのコンテキストではなく、ターゲットブランチのコンテキストで実行され、高い権限の付与とシークレットへのアクセスが許可される強力なイベントです。そのため、PR元のコードを不用意に checkout してビルド(または任意のスクリプト実行)を行うと、悪意のあるコードにシークレットを読み取られるなどの重大な脆弱性に繋がるため、利用には細心の注意が必要です。
Checkout での Git 履歴の取得(fetch-depth)
actions/checkout@v4 を使う際、デフォルトでは「最新の1コミット」のみを取得します(fetch-depth: 1)。「Git の差分から変更されたファイルだけを判定したい」といった場合には履歴が足りずにエラーになるため、with: fetch-depth: 0 を指定して全履歴を取得する必要があります。
アクションのバージョニングによるセキュリティ(SHAピン留め)
uses: actions/checkout@v4 のようなメジャーバージョン指定は手軽な反面、背後で参照される先が書き換えられて悪意あるコードが混入する(サプライチェーン攻撃)リスクがゼロではありません。また uses: actions/checkout@main のようにブランチ名を指定してしまうと、アクション提供者側の破壊的変更で突然CIが落ちる危険性があります。
より厳格なプロジェクトでは「コミットSHAでバージョンを固定し、Dependabotで自動更新させる」のがベストプラクティスとされています(例 uses: actions/checkout@1d96...)。
依存関係のキャッシュ(高速化)とスコープの罠
ワークフローの実行時間を短縮するため、言語やパッケージマネージャの依存関係をキャッシュするのはセオリーです。actions/setup-node や setup-python などの公式アクションには組み込みのキャッシュ機能(cache: npm など)が備わっているため、これらを積極的に活用しましょう。
【大ハマりポイント】キャッシュのスコープ(境界)
GitHub Actionsのキャッシュには厳しいアクセス制限があります。「デフォルトブランチ(main等)で作られたキャッシュは全PRから読み取れるが、機能ブランチで作られたキャッシュは他の機能ブランチから読み取れない」という仕様に注意してください。「なぜかPRのビルドでキャッシュがヒットしない」場合、このスコープ制限に引っかかっているケースが非常に多いです。
再利用可能ワークフローと複合アクションの違い
よく似た機能ですが、呼び出し方と実行単位に明確な違いがあります。
-
再利用可能ワークフロー (Reusable Workflows)
uses: ./.github/workflows/xxx.yml
呼び出し元とは別の新しいジョブとして実行されます。 -
複合アクション (Composite Actions)
uses: ./.github/actions/xxx
呼び出し元のジョブの中に、個々の独立したステップ群として展開(インライン化)されて実行されます。そのため、通常のステップと同じ制限を受けます。
再利用可能ワークフローとシークレットの引き継ぎ
uses を使って別のワークフローを呼び出す際(再利用可能ワークフロー)、呼び出し元のシークレットは 明示的に渡さない限り引き継がれません。secrets: inherit を指定してすべて引き継ぐか、
secrets:
TOKEN: ${{ secrets.TOKEN }}
のように個別に渡す必要があります。指定を忘れて呼び出し先のワークフローで認証エラーになるのは非常によくある落とし穴です。
※複合アクションを自作する際、アクション側の run を記述するすべてのステップに対して shell: bash などのシェル指定が必須となる厳しい制約があるため注意してください(これを忘れて文法エラーになるケースが非常に多いです)。
OIDC (OpenID Connect) を用いたクラウド連携
AWSやAzure、GCP等のクラウドへデプロイする際、以前は静的なシークレット(長期クレデンシャルなど)をハードコードしてリポジトリに保存するのが一般的でしたが、現在はセキュリティリスクの観点から推奨されていません。
代わりにOIDCを使った認証を採用することで、有効期限の短い一時的なクレデンシャルを動的に取得してクラウド連携を行うのが現代のベストプラクティスです。冒頭のワークフロー全体構造の例で示した permissions: id-token: write は、このOIDC連携を行う上で必須となる設定です。
デバッグログの出力方法 (Actions Debugging)
ワークフローがうまく動かず、変数の展開後の中身やパースエラーのより詳細な原因を調べたい場合、リポジトリのシークレット(または Variables)に特定の変数を設定することで、詳細なトレースログが出力できるようになります。
-
ACTIONS_STEP_DEBUG=true -
ACTIONS_RUNNER_DEBUG=true
これを設定するだけで、各ステップの内部挙動やランナーの通信が非常に詳しく追えるようになるため、トラブルシューティング時の非常に強力なテクニックとして覚えておきましょう。
まとめ
GitHub Actions はいろいろな機能がありますが、大枠の ルート ジョブ ステップ のそれぞれの階層に何が書けるかを整理しておくと、エラーになりにくく、目的の構文をすぐ見つけやすくなります。
ぜひブックマークして辞書代わりに使ってください!
お断り
記事内容は個人の見解であり、所属組織の立場や戦略・意見を代表するものではありません。
あくまでエンジニアとしての経験や考えを発信していますので、ご了承ください。