Reusable Workflow内のstepでは値が出ているのに、呼び出し元の次のjobでは空になる。この症状は、値を作る処理よりも、step outputをjob outputへ、job outputをworkflow_call outputへ公開する「境界の受け渡し」が一段抜けているときに起きやすいです。呼び出し元ではReusable Workflowを呼び出すjob自体のIDをneedsに指定し、workflow側で公開したoutput名を参照します。
確認は、値を作ったstepから呼び出し元の利用箇所まで、4層を順番にたどると切り分けやすくなります。先に結論を言えば、step内の値は自動的に呼び出し元へ渡りません。step ID、jobのoutputs、on.workflow_call.outputs、callerのneeds.<job_id>.outputs.<name>が名前でつながっているかを確認してください。
目次
まず4層の名前と受け渡しを図にする
Reusable Workflowのoutputは、次の流れです。
called workflow内のstep
└─ steps.<step_id>.outputs.<output_name>
↓ job側で公開
called workflow内のjob
└─ jobs.<job_id>.outputs.<job_output_name>
↓ workflow_callで公開
Reusable Workflowの外部output
└─ on.workflow_call.outputs.<workflow_output_name>.value
↓ caller側の呼び出しjobが受け取る
caller workflowの後続job
└─ needs.<call_job_id>.outputs.<workflow_output_name>
名前はそれぞれ別の階層です。stepに付けるid、GITHUB_OUTPUTへ書く名前、job outputのキー、workflow_call outputのキー、callerのjob IDを混同しないでください。ある階層で値が存在しても、その上の階層へ明示的にmapしていなければ次の階層では参照できません。
最小構成で一度だけ値を通す
次の例は、呼び出されたworkflowで安全な固定文字列を作り、呼び出し元の後続jobで表示する最小例です。実運用のトークン、個人情報、顧客データなどはoutputに入れず、まず「確認用」というような機密でない短い値で経路だけを検証してください。
Reusable Workflow(例:.github/
name: Reusable workflow
on:
workflow_call:
outputs:
result:
description: "確認用の結果"
value: ${{ jobs.build.outputs.result }}
jobs:
build:
runs-on: ubuntu-latest
outputs:
result: ${{ steps.emit.outputs.result }}
steps:
- id: emit
shell: bash
run: echo "result=確認用" >> "$GITHUB_OUTPUT"
呼び出し側(例:.github/
name: Caller
on:
workflow_dispatch:
jobs:
call-reusable:
uses: ./.github/workflows/reusable.yml
inspect:
runs-on: ubuntu-latest
needs: call-reusable
steps:
- name: Read reusable workflow output
env:
RESULT: ${{ needs.call-reusable.outputs.result }}
run: printf 'result=%s\n' "$RESULT"
この例では、step IDのemitからresultを取得し、job buildのoutputs.resultへ割り当てます。Reusable Workflowのon.workflow_call.outputs.resultではjobs.build.outputs.resultを参照します。呼び出し側はReusable Workflowを呼び出したjobのID call-reusableをneedsへ書き、外部に公開したresultを読みます。途中のどこかで名前を変えたら、そのmap先も合わせて直します。
どの境界で値が消えたか切り分ける
最初に、値を生成するstepの実行結果を確認します。stepがskipされていないか、失敗していないか、outputを書き出す行まで到達したかを見ます。step outputを使う場合は、そのstepにidがあり、参照式が同じIDを使っている必要があります。表示名nameは人向けのラベルで、steps.<id>.outputs.<name>の<id>の代わりにはなりません。
次に、値がGITHUB_OUTPUTへ書かれているかを確認します。現在の形式は、同じstepの後続処理から参照できるstep outputとして、環境変数GITHUB_OUTPUTが示すファイルへ「name=value」を追記する形です。シェルの引用符が不適切で、値が途中で分割されたり、式の評価前に空になったりしていないかも確認します。複数行値は単純な1行形式では扱えないため、公式の複数行記法に従うか、成果物ファイルを使う方法を検討します。
続いて、job outputsのmapを調べます。Reusable Workflow内にstep outputがあっても、jobs.<job_id>.outputsで参照する設定がなければ、workflow_callへ渡すjob-level outputはありません。ここではjob IDとstep IDを正確に区別し、式の大文字小文字やoutput名の綴りを照合します。job outputsはjobの完了時に後続jobから使われるので、同じjob内で後続stepが必要な値を読む設計ならstep outputを参照します。
三つ目に、on.workflow_call.outputsを確認します。ここで定義したoutput名がReusable Workflowの外部インターフェースです。valueはcalled workflow内のjob-level outputを参照します。step outputを直接指定したり、存在しないjob IDを参照したり、descriptionだけを追加してvalueを設定し忘れたりすると、呼び出し側が読む値につながりません。
最後にcaller側を確認します。後続jobがReusable Workflowを呼び出すjobにneedsで依存しているか、needs.<呼び出しjob ID>.outputs.<workflow_callで定義した名前>を参照しているかを見ます。別のjob IDや、called workflow内のjob IDを使っても呼び出し元からは解決できません。Reusable Workflowを呼び出すjobは通常のstep内で呼び出すのではなく、jobs配下のjobとしてusesを指定します。
症状から探す確認ポイント
表は横にスクロールできます
| 症状 | まず見る場所 | 確認すること |
|---|---|---|
| stepのログには値があるがjob outputが空 | job outputs | steps.<id>.outputs.<name>のID・名前とmap |
| called workflow内のjobでは値があるがcallerで空 | workflow_call outputs | valueが正しいjobs.<job_id>.outputs.<name>を参照しているか |
| callerの式が空または評価できない | caller job | needsが呼び出しjob IDを指定し、外部output名を使っているか |
| 特定の実行だけ空 | step/job条件 | ifによるskip、失敗、continue-on-error、依存関係、空文字を返す経路 |
| matrix呼び出しだけ値が期待と違う | matrix output仕様 | どの完了runの値が最終outputになるか、空文字を返すrunがあるか |
| workflowをネストしたときだけ空 | 各workflow境界 | A→B、B→Cの各段階で、次のworkflowへ必要なoutputを明示しているか |
失敗したjobの画面だけで判断せず、runごとに呼び出されたworkflow、job、stepの順にログを開きます。名前を一度に全部変更すると切り分けが難しくなるため、まず現在の名前を表に書き出し、1つのmapだけ直して再実行してください。直した後は、呼び出し元で確認した値と、その値を作ったstepの値が一致するか確認します。
4層の対応表を作る
編集前に次の空欄を埋めると、どこで参照が切れているか見つけやすくなります。
表は横にスクロールできます
| 層 | 記入する名前 | 参照例 |
|---|---|---|
| step ID | 値を出すstepのid | emit |
| step output | GITHUB_OUTPUTに書くキー | result |
| job ID / job output | 出力元jobと公開キー | build / result |
| workflow output | workflow_callで公開するキー | result |
| caller job ID | reusable workflowを呼ぶjob | call-reusable |
| caller参照 | needsとworkflow output名 | needs.call-reusable.outputs.result |
同じresultという名前を全階層で使う必要はありません。名前を変えるときは、対応表にそれぞれのmapを明記してください。短く同じ名前を使う例は読みやすい反面、階層の取り違えを隠すことがあります。大きなworkflowでは、job outputにjob_result、workflow outputにfinal_resultのような異なる名前を付け、どの境界の値かを判別しやすくする選択肢もあります。
matrix、skip、空文字の注意点
matrix strategyでReusable Workflowを複数回呼び出すときは、通常の単一実行と同じように「最後のrunの値」とだけ考えないでください。GitHub公式仕様では、outputはmatrixのうち最後に正常終了し、かつ値を設定したReusable Workflowの実行結果になります。最後に正常終了した実行が空文字を設定した場合、その直前に正常終了して値を設定した実行の値が採用されます。この動作を前提に集約が必要なら、各matrix結果を一つの文字列outputに上書きする設計ではなく、artifactや別の集約方法が適切か検討してください。
条件付きstepやjobでは、値を作る経路自体が実行されない場合があります。空文字は必ずしもマッピング設定の誤りを意味しません。if条件、needsによる依存、失敗時の扱い、デフォルト値の有無を見て、値が設定されない分岐を確認します。複数の分岐から同じoutputを返すなら、各分岐で同じ契約(型・意味・空値の扱い)を保てるかを決めます。未実行と「意図的に空」を同じ値で表すと、呼び出し元で原因を区別できなくなるため、必要ならstatus outputを別に設計します。
ネストしたReusable Workflowでは、ワークフローAがBを呼び、BがCを呼ぶ場合、AからCの値を直接参照できるわけではありません。各境界で外部に公開し、次のworkflowが受け取れるようにします。A→Bのmap、B→Cのmap、最上位callerの参照を一つずつ確認してください。
秘密情報をoutputへ載せない
workflow outputやログは、秘密を運ぶための代替手段ではありません。アクセストークン、署名鍵、個人情報をoutputへ出して、値が渡るか試すのは避けてください。GitHub Actionsにはsecretをmaskする仕組みがありますが、maskを機密データの一般的な受け渡し方法として扱わないでください。Reusable Workflowが必要とするsecretは、公式のinputs/secrets契約で渡し、outputには非機密の状態・識別子・集計結果など、呼び出し元が扱ってよい値だけを含めます。
確認用テストは「ok」のような固定値でよく、実運用値を出力する必要はありません。出力の内容がログに表示される設定なら、機密でないことを確認します。複数行の出力、JSON、ユーザー入力を含む出力では、区切り文字や改行による解釈の違いにも注意し、必要に応じてartifactsや明示的なファイル形式を選びます。
小さい変更で安全に再現する
原因を切り分ける際は、本番相当のtokenや実データを使わず、固定文字列を出す小さなworkflowを一時ブランチで動かします。再実行できるワークフローであっても、意図しない副作用を避けるため、読み取り専用の権限、テスト用の値、必要最小限のjobで確認してください。実行しないまま「動作確認済み」と書かず、記事内のYAMLは公式仕様に沿った例として提示します。
テストでは三箇所を照合します。第一にstep outputを作る処理が成功したか。第二にReusable Workflowのjob outputとworkflow_call outputの値が、同じ非機密文字列になったか。第三にcallerのneeds.<job_id>.outputs.<name>で同じ値を読めたかです。ログに値を出さない方針なら、後続処理の条件分岐やテスト用の一致確認で値を検証し、表示を最小限にします。
GITHUB_OUTPUTへ書く値の形式
1行の値なら、値の中の改行やシェル展開を意識して、公式のGITHUB_OUTPUT形式で書きます。例えば固定値なら次のようにできます。
- id: emit
shell: bash
run: echo "result=ok" >> "$GITHUB_OUTPUT"
変数を入れるときは、未信頼文字列をそのままシェルコードへ連結しないでください。環境変数として渡し、シェルで引用して扱い、改行や区切り文字を含む場合は公式の複数行output形式を用います。複雑な構造の大きなデータはjob outputに詰め込むより、artifactなど明示的なデータ受け渡し方法を選んだほうが扱いやすい場合があります。ここで説明しているのは伝達経路の確認であり、任意のバイナリや巨大データをoutputsに適用できるという意味ではありません。
値を書けたように見えても、output名が式と一致しなければ別のキーを読んでいるだけです。手入力で名前を変更する場合は、GITHUB_OUTPUTの左辺、steps参照、jobs.outputsのキー、workflow_call.outputsのキー、callerの式を同じ表で照合してください。YAMLのインデントがずれると、設定が期待する階層に入らないことがあります。workflowファイルの構文とGitHub上のrunログの両方で確認します。
よくある修正パターン
job outputsのmapがない場合: 該当step outputをjobs.<job_id>.outputsへ公開し、そのjob outputをworkflow_call側で参照します。別のjobのstep outputを直接使うことはできないため、値を作ったjobとmapするjobの関係も確認します。
workflow_callのvalueがない場合: 公開したい外部outputのvalueを設定し、正しいjob-level outputへつなぎます。descriptionだけでは値は返りません。
callerが別jobをneedsにしている場合: Reusable Workflowを呼び出すjob IDをneedsへ指定します。呼び出しjobがskipされる条件や、後続jobのif条件も確認します。
名前が途中で変わっている場合: 4層のどこで変換しているかを対応表に記録してから、必要な1か所だけ修正します。式全体を置換する前に、各キーが定義される場所と参照される場所を検索してください。
修正後のworkflowを実行できる権限がない場合は、静的にYAMLと名前の対応を点検した結果と、実行検証が未実施であることを分けて記録してください。記事だけから特定リポジトリの権限設定やGitHub Enterprise Serverのバージョンを決めつけることはできません。
確認チェックリスト
-
値を作るstepが実行され、意図した値を書いている
-
stepに一意なidがあり、式の参照と一致している
-
step outputの名前がGITHUB_OUTPUTのキーと一致している
-
job outputsが正しいstep outputをmapしている
-
on.workflow_call.outputs.valueが正しいjob outputを参照している
-
callerがReusable Workflowのcall jobをneedsに指定している
-
callerがworkflow_callで公開したoutput名を使っている
-
if、skip、失敗、matrix、空文字の経路を確認している
-
secretや個人情報をoutput・ログへ出していない
-
非機密の固定値で各境界を確認し、実運用値を使った未検証を避けている
次に行うこと
まず出力元workflowで、step IDとGITHUB_OUTPUTのキーを確認します。続いてjob outputs、workflow_call.outputs.value、callerのneeds参照を順に対応表へ記録し、空になった最初の境界だけ修正してください。matrixや条件分岐がある場合は、値を設定しない経路もテストします。変更を適用する前に、secretを含まない固定値で再現可能な最小ケースを作り、修正後はstep・Reusable Workflow output・caller outputの三点で一致を確かめます。
出典
-
GitHub Docs, Reuse workflows(Using outputs from a reusable workflow): https://docs.github.com/en/actions/how-tos/reuse-automations/reuse-workflows(新しいタブで開く)
-
GitHub Docs, Workflow syntax for GitHub Actions(on.workflow_call.outputs、jobs.
<job_id>.outputs、steps): https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax(新しいタブで開く)
確認日:2026-10-15
注:この記事は公式仕様に基づく一般的な切り分け手順です。特定のrepositoryやworkflowでの実行・hands-on検証は行っていません。
