🛠️

GitHub Actions: ENVをシェルスクリプトで追加するときの仕様

2022/01/18に公開

GitHub Actions のrunでシェルスクリプトを実行して、その結果を Actions の ENV に追加したい時あると思います。そういう時は、

- name: Set a new env1
  run: echo "NEW_ENV1=Hoge1234" >> $GITHUB_ENV

- name: Set a new env2
  run: echo "NEW_ENV2=$(cat piyo.txt | sed -n "1,1p")" >> $GITHUB_ENV

のようにすればいいと情報をすぐ得られると思うのですが、少し特殊な場合はどういう挙動をするのか調査してみました。特に、変数に代入する文字列に空白が含まれている場合のクォートはどのように扱った方がいいか、$GITHUB_ENVに追記するときのechoはダブルクォートで囲んでおいた方がいいのか、YAML のnameに ENV は利用できるのかについて検証しました。

変数定義の際、クォートはなくても良い。というかない方が良い

一般的なシェルスクリプトだとHOGE=piyo meu poyoとするとmeuというコマンドはありませんとなってエラーになるので、HOGE='piyo meu poyo'とかHOGE="piyo meu poyo"のようにすると思いますが、$GITHUB_ENVに追記する時はなくてもなぜかうまく変数として認識されます。

run: echo "NEW_ENV=HOGE PIYO MEU" >> $GITHUB_ENV

# workflow内部で
# ${{ env.NEW_ENV }} とすると、 HOGE PIYO MEU に置換される

ここで、下のようにクォートをつけると、クォートごと変数として認識されます。

run: |
  echo "NEW_ENV1='HOGE PIYO MEU'" >> $GITHUB_ENV
  echo "NEW_ENV2=\"HOGE PIYO MEU\"" >> $GITHUB_ENV
  
# workflow内部で
# ${{ env.NEW_ENV1 }} とすると、 'HOGE PIYO MEU' にそのまま置換される
# ${{ env.NEW_ENV2 }} とすると、 "HOGE PIYO MEU" にそのまま置換される

例えば、nameに変数を利用したいとき(actions/upload-artifactで成果物をアップロードする時とか)はこの仕様を知った上で扱わないとうまくいきません。

- name: Upload Result
  uses: actions/upload-artifact@v2
  with:
    name: Test Result of ${{ env.NEW_ENV }}
    path: ${{ github.workspace }}/output
    retention-days: 3

# このようなパターンで、NEW_ENV にクォートが含まれていると
# `name`でシンタックスエラーになってworkflowが落ちる。

$GITHUB_ENVechoで追記するときはクォートなくても良い

- name: Set ENV
  run: |
    echo "ENV1=Hoge Piyo Meu" >> $GITHUB_ENV
    echo ENV2=Hoge Piyo Meu >> $GITHUB_ENV
    
# この2つは同じ結果になる

nameに使ったりできるか? → できる

上記のupload-artifactでもありましたが、${{ env.NEW_ENV }}のようにすれば、workflow 内で使えます。ただ、そのまま置き換えられるのでクォートには注意が必要です。

echoするときに後からクォートをつけたほうがいいパターン

$ echo hoge piyo (meu)

のように(, )を含む文字列を引数に取る場合、シンタックスエラーになります。
ですから、環境変数を使ってechoするときは、

# NEW_ENV には hoge piyo (meu) が入っているとする
run: echo "${{ env.NEW_ENV }}"

のようにダブルクォーテーションで囲むようにする必要があります。

Discussion