はじめに
先日、Github Actions を触る機会があり、前ステップのrun
内の変数を後ステップで利用したいという場面に出くわしました。
Github Actions では、各 step 内でスコープが閉じられているため、何らかの方法で step 間で変数を共用できるようにします。
そこで、今回は step 間で変数を共用する方法を備忘録します。
1. env に環境変数として格納する
公式 Docs:Setting an environment variable
1# envに格納する
2run: echo "key=value" >> $GITHUB_ENV
3
4# envから取り出す
5run: echo ${{ env.key }}
他の手法に比べて分かりやすく、多用しています。ただし、環境変数を設定した step 内では、その変数を取り出すことができません。
1# 実例
2- name: Store in env
3 run: |
4 echo "STAGE=production" >> $GITHUB_ENV
5 echo ${{ env.STAGE }} # printされません
6
7- if: ${{ env.STAGE == 'production' }}
8 run: |
9 echo ${{ env.STAGE }} # `production`がprint
以前は set-env が用いられましたが、脆弱性が報告され現在は使用できません。
2. set-output で step の出力パラメータとして扱う
公式 Docs:出力パラメータの設定
1# stepの出力パラメータとする、idが必須
2id: ${id}
3run: echo '::set-output name=${key}::${value}'
4
5# 指定idのstepの出力パラメータを取り出す
6run: echo ${{ steps.${id}.outputs.${key}}}
1 の env から取り出すのに比べて値を取り出すのが面倒だと思います。
1# 実例
2- name: Set output
3 id: configure # idをつける必要があります
4 run: |
5 echo '::set-output name=stage::production'
6
7- if: steps.configure.outputs.stage == 'production'
8 run: |
9 echo ${{ steps.configure.outputs.stage }} # `production`がprint
余談
GitHub Actions の難しさに(面倒臭い)デバックのし辛さがあると思います。構文不正が Actions で実際に動かして初めて分かるからです。
そこで、私は GitHub Actions 自体の lint をしてくれるactionlint、ローカルで Actions を実行できるactを併用して、デバックしていました。しかし、act は Gtihub Actions を完全に再現しているわけではないので、Actions で動くはずの構文が act で動かない場合もあります。(制作者も注意しています)
私はハマりした。ローカルの act で env
の構文が動かないので、set-output
を利用したが、よくよく調べると Actions 上だと期待通りenv
が動くではないですか、と言う顛末です。
なので、サンドボックス用のリポジトリで検証することが近道だと最近は考えています。
おわりに
1 の方法は、環境変数をグローバル変数のように扱っていて、env は定性的な値を扱うものとして認識している私には多少違和感があります。なので、2 の方がしっくりくるのですが、値を取り出すのにあそこまで長くなるのは面倒なので、1 で落ち着いています。