🍇
Github Actionsの変数とコンテキストのスコープについて (2022/11版)
Github Actionsの環境変数とスコープ
- 環境変数はenv要素で宣言する
- Workflow / Job / Stepのどこで呼ばれたかでスコープ範囲が変化する
1.トップのenv要素で宣言: Workflowで有効
2.jobs.<job_id>.envで宣言: Job内で有効
3.jobs.<job_id>.steps[*].envで宣言: Step内で有効
上記を一目で表すと以下のようになる
コンテキストと環境変数の違い
- Github Actionsにはコンテキストという値の保存機構が環境変数とは別に存在する。
- 環境変数には
$MY_VARIABLES
のようにアクセスできるのに対し、コンテキストには${{ CONTEXT_NAME.MY_CONTEXT }}
のようにアクセスする - 環境変数はGithub Actionsのrunner (stepsの具体的内容を処理するシェル環境)でしか参照できないが、コンテキストはrunnerに送られないGithub Actionsのコントローラ部分で処理されるステートメント中でも参照できる
- envという名前のコンテキストには今のスコープでアクセスできる環境変数が格納されている(ややこしい)
例えば、以下の下から4行目のif文に注目
name: test2
on:
workflow_dispatch:
env:
DAY_OF_WEEK: Monday
jobs:
greeting_job:
runs-on: ubuntu-latest
env:
Greeting: Hello
steps:
- name: "Say Hello Mona it's Monday"
if: ${{ env.DAY_OF_WEEK == 'Monday' }}
run: echo "$Greeting $First_Name. Today is $DAY_OF_WEEK!"
env:
First_Name: Mona
IF文は実行環境(runner)には送られないため環境変数の参照はできないのでコンテキストが用いられている
(わかりづらいが、「env」という名前のコンテキストに環境変数DAY_OF_WEEKの値が保存されている。環境変数を参照しているわけではない)
自分が扱っているのが環境変数なのかコンテキストなのかは常に意識しましょう
github actionsに用意された様々なコンテキストについてはこちらを参照
環境変数を本来のスコープ外で参照したい場合
どこで参照したかによって方法が異なる
a. 同じJob内の後続Stepで参照したい
やること:
以下のような構文を用いて $GITHUB_ENV (という環境変数が指し示すファイル)に環境変数名=変数値という内容を書き込むことで同Job内から参照できるようになる
宣言の構文
echo "{environment_variable_name}={value}" >> $GITHUB_ENV
使用例
name: test3
on:
workflow_dispatch:
env:
DAY_OF_WEEK: Monday
jobs:
greeting_job:
runs-on: ubuntu-latest
env:
Greeting: Hello
steps:
- name: Set the value
id: step_one
run: |
echo "action_state=$action_state" >> $GITHUB_ENV
env:
action_state: yellow
- name: Use the value (via env var)
id: step_two
run: |
echo "$action_state" # This will output 'yellow'
- name: Use the value (via context)
id: step_three
run: |
echo "${{ env.action_state }}" # This will output 'yellow'
上記の例では、もともとstep_oneというステップからしか参照できないaction_state変数が
- step_twoからは環境変数として
- step_threeからはenvコンテキストとして
それぞれ参照できている。
b. 異なるJobから参照したい
やること: ジョブの出力に変数名=変数値を追加する
宣言の構文
echo "{name}={value}" >> $GITHUB_OUTPUT
使用例
name: test4
on:
workflow_dispatch:
env:
DAY_OF_WEEK: Monday
jobs:
job1:
runs-on: ubuntu-latest
# Map a step output to a job output
outputs:
output1: ${{ steps.step1.outputs.test }}
output2: ${{ steps.step2.outputs.test }}
steps:
- id: step1
run: echo "test=hello" >> $GITHUB_OUTPUT
- id: step2
run: echo "test=$test" >> $GITHUB_OUTPUT
env:
test: world
job2:
runs-on: ubuntu-latest
needs: job1
steps:
- run: echo ${{needs.job1.outputs.output1}} ${{needs.job1.outputs.output2}}
最後の出力はhello world
となる。
step1とstep2で$GITHUB_OUTPUT
に登録された変数はどちらもtest
という名称である点に注目。ステップごとに別の名前空間が割り当てられているため、衝突することはない。
参考リンク:
Github Docs - Environment variables
Discussion