コンテキストと変数 — ${{ }}構文・env・secretsの使い分け
この章の目次開く
ここまでのワークフローは、毎回同じコマンドを実行するだけの「静的」なものでした。実務のワークフローでは、状況に応じたデータを扱う必要が出てきます。
- 「いまどのブランチで動いているのか」を知りたい
- APIキーやトークンを、コードに書かずに使いたい
- 「mainブランチのときだけこのステップを実行」のような条件分岐をしたい
この章では、その道具立てであるコンテキスト・変数・シークレット・条件式をまとめて整理します。
${{ }} — 式を埋め込む構文
YAMLの中に ${{ }} で囲んだ式を書くと、実行時に評価されて値に置き換わります。
steps:
- name: ブランチ名を表示する
run: echo "いまのブランチは ${{ github.ref_name }} です"mainブランチへのpushで動けば、ログには いまのブランチは main です と出力されます。この github.ref_name のような「実行時の情報が詰まったオブジェクト」をコンテキストと呼びます。
コンテキスト — 実行時情報の詰め合わせ
よく使うコンテキストは次の4つです。
| コンテキスト | 中身 | 例 |
|---|---|---|
github | イベントやリポジトリの情報 | github.ref_name(ブランチ名)、github.actor(実行者)、github.event_name(イベント種別) |
env | 自分で定義した環境変数 | env.NODE_ENV |
secrets | 登録した秘密情報 | secrets.API_TOKEN |
inputs | workflow_dispatchなどの入力値 | inputs.environment |
学習者github コンテキストの中身って、どうやったら全部見られるの?毎回リファレンスを調べるしかない?
デバッグに便利な小技があります。toJSON 関数でコンテキストを丸ごとダンプできるんです。
- name: githubコンテキストの中身を全部見る
run: echo '${{ toJSON(github) }}'「この情報どこに入ってるんだっけ?」となったら、まずこれで中身を覗くのが手っ取り早い方法です。
全コンテキストの一覧はコンテキストリファレンス(公式ドキュメント)にあります。
env — 環境変数を定義する
env: キーで環境変数を定義できます。ポイントは定義する場所によって有効範囲が変わることです。
name: Env Demo
on: push
env:
APP_NAME: my-app # ① ワークフロー全体で有効
jobs:
build:
runs-on: ubuntu-latest
env:
NODE_ENV: production # ② このジョブ内で有効
steps:
- name: ビルドする
env:
DEBUG: 'true' # ③ このステップ内でのみ有効
run: |
echo "$APP_NAME を $NODE_ENV でビルド (DEBUG=$DEBUG)"| 定義場所 | スコープ |
|---|---|
ワークフロー直下の env | 全ジョブ・全ステップ |
ジョブ直下の env | そのジョブの全ステップ |
ステップ内の env | そのステップのみ |
run のシェルの中では $APP_NAME のように普通の環境変数として参照できます。一方、if: や with: などYAML側で参照するときは ${{ env.APP_NAME }} と書きます。「シェルの中では $名前、YAMLの中では ${{ env.名前 }}」と覚えておきましょう。
secrets — 秘密情報を安全に扱う
デプロイ用のトークンや外部APIのキーを、YAMLに直書きするのは絶対にやってはいけません。リポジトリを見られる人全員に漏れますし、Gitの履歴に永久に残ります。

GitHub Actionsには専用の保管場所としてSecretsが用意されています。登録は、リポジトリの Settings → Secrets and variables → Actions → New repository secret から行います。名前(例: API_TOKEN)と値を入れて保存すると、ワークフローから参照できるようになります。
- name: APIを呼び出す
env:
API_TOKEN: ${{ secrets.API_TOKEN }}
run: curl -H "Authorization: Bearer $API_TOKEN" https://api.example.com/deploySecretsには次の性質があります。
- 一度登録したら、値は誰にも見えない(再表示は不可。上書きのみ)
- ログに出力しようとすると
***にマスクされる - Pull Requestを出したフォーク元の第三者からはアクセスできない
Variables — 秘密ではない設定値
同じ設定画面にVariablesというタブもあります。こちらは「秘密ではないが、YAMLにハードコードしたくない設定値」の置き場所です。
| Secrets | Variables | |
|---|---|---|
| 用途 | APIキー、トークン、パスワード | アプリ名、デプロイ先URL、Nodeバージョン |
| 参照 | ${{ secrets.名前 }} | ${{ vars.名前 }} |
| 登録後の閲覧 | 不可(マスクされる) | 可能 |
「漏れたら困るならSecrets、そうでないならVariables」というシンプルな基準で使い分けます。
if — 条件付きでステップを実行する
if: を付けると、条件を満たすときだけジョブやステップを実行できます。
- name: mainブランチのときだけデプロイする
if: github.ref_name == 'main'
run: echo "デプロイします"if: の中は最初から式として評価されるので、${{ }} は省略できます(付けても動きます)。よく使う条件のパターンを挙げます。
# イベント種別で分岐
if: github.event_name == 'pull_request'
# 複数条件(&& / ||)
if: github.ref_name == 'main' && github.event_name == 'push'
# 前のステップが失敗しても実行する
if: failure()
# 成否にかかわらず必ず実行する(後片付けなど)
if: always()failure() や always() はステータス関数と呼ばれ、「テストが落ちたときだけ通知する」「一時ファイルは必ず消す」といった制御に使います。
ステップ間で値を受け渡す — outputs
あるステップの計算結果を、後のステップで使いたいことがあります。その受け渡し口がoutputsです。ステップ側では $GITHUB_OUTPUT という特殊ファイルに 名前=値 を書き込みます。
- name: バージョンを調べる
id: version # 後から参照するためのIDを付ける
run: echo "value=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
- name: バージョンを使う
run: echo "リリースするバージョンは ${{ steps.version.outputs.value }}"流れを整理すると:
- 値を作るステップに
id:を付ける echo "名前=値" >> "$GITHUB_OUTPUT"で書き込む- 後続ステップから
steps.<id>.outputs.<名前>で参照する
メンター最初は「そういう書き方をするもの」と割り切ってコピペで構いません。ジョブをまたいだ受け渡し(jobsのoutputs)も同じ発想で、あとの章でも登場します。
まとめ
${{ }}は実行時に評価される式。コンテキスト(github/env/secrets/inputsなど)の値を参照できるenvは定義場所(ワークフロー/ジョブ/ステップ)でスコープが決まる。シェル内は$名前、YAML内は${{ env.名前 }}- 秘密情報はSecretsへ。YAML直書きは厳禁、ログでは自動マスクされる
- 秘密でない設定値はVariables(
${{ vars.名前 }})に分ける if:で条件実行。failure()/always()で失敗時・常時実行の制御ができる- ステップ間の値の受け渡しは
id+$GITHUB_OUTPUT+steps.<id>.outputs.<名前>
次章では、ジョブとランナーの実行モデルを掘り下げます。複数ジョブの並列実行、needs による依存関係、そして複数バージョンでまとめてテストするマトリックスビルドを扱います。