🍇

Github Actionsの変数とコンテキストのスコープについて (2022/11版)

2022/11/18に公開

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
https://docs.github.com/en/actions/learn-github-actions/environment-variables

Discussion