📦

GithubActionsで環境変数を理解する。

2021/08/27に公開

概要

イマイチ分かっていなかったので、ここに取りまとめておきます。

ポイント

2種類の変数

ここがこんがらがるのですが、「ワークフロー内で利用できるコンテキストという変数」と、「実際のコンピュータ内で利用できる環境変数」があります。

1. コンテキスト

yaml内で利用できる環境変数的な存在。GithubActionsのOptionなどにも利用できる変数です。

下記のように独自に定義したりして利用する事ができます。
利用する場合は${{name}}みたいな形で参照する事ができます。

name: learn-github-actions
on: [push]
env:
  env_1 : hashito
jobs:
  check-bats-version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: |
          echo "ths is env=${{ env.env_1 }}"

または、下記のように環境自体に定義されている変数があります。
例えばCommitのハッシュ値とかはgithub.refで取得できます。
https://docs.github.com/ja/actions/reference/context-and-expression-syntax-for-github-actions#github-context

2. 環境変数

ワークフローで実行しているコンピューターで有効な環境変数です。

下記のような感じで定義する事ができます。

name: learn-github-actions
on: [push]
jobs:
  check-bats-version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: |
          echo "ths is env=$ENV_1"
        env: 
          ENV_1: hashito

場所に注意してください。
steps配下のactionという部分にenvとして定義しています。
前回はjobsなどと同列にあったことがわかります。

環境変数はaction内でしか有効にならない

環境変数は定義したaction内でしか利用できません。
例えば下記のようなgithubactionを実行した場合

name: learn-github-actions
on: [push]
jobs:
  check-bats-version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: |
          echo "(1) ths is env=$ENV_1"
        env: 
          ENV_1: hashito
      - run: |
          echo "(2) ths is env=$ENV_1"

以下のように2回目のrunには出力されません。

持ち越す方法:(1)一時ファイルに書き込む

$GITHUB_ENVという変数に共有可能な一時ファイルのPathが提供されており、そこに書き込む事により別のactionなどに引き継がせる事ができます。

上記のリンクで紹介されている通り、下記のコマンドで環境ファイルに書き込む事ができます。
echo "{name}={value}" >> $GITHUB_ENV

name: learn-github-actions
on: [push]
jobs:
  check-bats-version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: |
          echo "(1) ths is env=$ENV_1"
          echo "ENV_1=$ENV_1" >> $GITHUB_ENV
        env: 
          ENV_1: hashito
      - run: |
          echo "(2) ths is env=$ENV_1"

結果

https://docs.github.com/ja/actions/reference/workflow-commands-for-github-actions#environment-files

持ち越す方法:(2)set-outputコマンドを利用する

set-outputコマンドというものがあるらしく、これを利用するとactionの出力値のような設定が可能なようです。
これを利用すると、実際はコンテキストになるため、動いているLinux(ライナー)からコンテキストを定義できる感じとなります。

echo "::set-output name={name}::{value}"

name: learn-github-actions
on: [push]
jobs:
  check-bats-version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: |
          echo "(1) ths is env=$ENV_1"
          echo "::set-output name=ENV_2::$ENV_1"
        env: 
          ENV_1: hashito
        id: action1
      - run: |
          echo "(2) ths is env=${{ steps.action1.outputs.ENV_2 }}"

https://docs.github.com/ja/actions/reference/workflow-commands-for-github-actions

個人的には最初のやつのほうが分かりやすい感じがしました。

コンテキストを環境変数にする

もちろん、コンテキストで取得した値を環境変数にすることもできます。

name: learn-github-actions
on: [push]
jobs:
  check-bats-version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: |
          echo "(1) ths is env=$ENV_1"
        env: 
          ENV_1: ${{github.ref}}

実用例:BRUNCH毎に異なる環境変数を利用する。

これらのものを利用して、例えばDevelopとかStagingとか分けているBRUNCH毎にコンテキストや環境変数を自在に変える事ができます。
下記のコードではifでBRUNCH名がmainだった場合とmain2だった場合に違う環境変数を定義して、次の処理に渡す処理をしています。

name: learn-github-actions
on: [push]
jobs:
  check-bats-version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: echo "ENV_1=main" >> $GITHUB_ENV
        if: github.ref == 'refs/heads/main'
      - run: echo "ENV_1=main2" >> $GITHUB_ENV
        if: github.ref == 'refs/heads/main2'
      - run: echo "branch=$ENV_1"

コンテキストをBRUNCHによって変える

少しややこしいが環境変数をそのままコンテキストに変換すれば可能です。
(他にスマートなやり方があれば教えて下さい。)

name: learn-github-actions
on: [push]
jobs:
  check-bats-version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: echo "ENV_1=main" >> $GITHUB_ENV
        if: github.ref == 'refs/heads/main'
      - run: echo "ENV_1=main2" >> $GITHUB_ENV
        if: github.ref == 'refs/heads/main2'
      - run: echo "::set-output name=envname::$ENV_1"
        id: envs
      - run: echo "branch=${{steps.envs.outputs.envname}}"

Discussion