はじめに
最近Bitriseのワークフローをガッツリいじる機会があったのですが、環境変数周りの仕様について勘違いしていたところがあり、結構嵌って時間を取られてしまいました。
ググってもわかりやすい記事が意外と出てこなくて、簡単なワークフローを自分で作っていろいろ試してやっと理解できたので、ユースケースごとに整理してみます。
なお、以下ではSecrets
とEnv Vars
という用語を使い、総称として環境変数と表現します。
Env Vars
を上書きしたい
Env Vars
にSLACK_CHANNEL
を追加します。
Slackにメッセージを送信するステップにおいて、$SLACK_CHANNEL
を指定します。
ビルド時にCustom Environment Variables
を以下のように指定し、別のチャンネルにメッセージを送信するようにしてみましょう。
ところが、SLACK_CHANNEL
の値は上書きされず、#default-channel
にメッセージが送信されてしまいます。
実は環境変数には以下の評価順序があり、Custom Environment Variables
のあとにEnv Vars
が評価されるので、値を上書きできないのです。
Secrets
-> Custom Environment Variables
-> Env Vars
Don't use the same key as an App Env Var
App Environment Variables have precedence over custom Environment Variables! This means that if you define a custom Env Var with the same key as an App Env Var, the build will use the value of the App Env Var.
値を上書きするためには、Slackステップの前にScriptステップを配置し、以下のようなスクリプトを入れておきます。
#!/usr/bin/env bash
set -ex
if [ ! -z "$CUSTOM_SLACK_CHANNEL" ]; then
envman add --key SLACK_CHANNEL --value "$CUSTOM_SLACK_CHANNEL"
fi
# もしくはワンライナーで
envman add --key SLACK_CHANNEL --value ${CUSTOM_SLACK_CHANNEL:-$SLACK_CHANNEL}
これでCustom Environment Variables
にCUSTOM_SLACK_CHANNEL
を追加することで、Slackのメッセージの送信先チャンネルを変更することができます。
Secretsを上書きしたい
環境変数には以下の評価順序があると説明しました。
Secrets
-> Custom Environment Variables
-> Env Vars
つまり、Secrets
はビルド時にCustom Environment Variables
を同名で追加することで上書きが可能です。
Secrets
にSLACK_CHANNEL
を追加します。
Custom Environment Variables
でSLACK_CHANNEL
に#custom-channel
を指定します。
これで#custom-channel
にメッセージが送信されます。
Env Vars
、Secrets
で変数展開したい
環境変数の中で別の環境変数を使用したいケースがあります。
そんなときはEnv Vars
とSecrets
どちらでも使える変数展開の機能を使用します。
Env Vars
に以下のように環境変数を追加します。
SLACK_CHANNEL
の値に別の環境変数である$ENV_PRODUCTION
を使用しています。
変数展開して値を#ios-prod
となるようにするには、Replace variables in inputs?
のチェックをオンにします。
Secrets
も同様に変数展開可能なんですが、Secrets
の場合は環境変数が登録されている順番が重要らしく、以下のようにENV_PRODUCTION
がSLACK_CHANNEL
よりも下にあると参照できないようでした。
Env Vars
とSecrets
間で変数を参照し合うことはできるのか?
結論は以下の通りです。
-
Env Vars
からSecrets
の環境変数を参照して展開することはできる -
Secrets
からEnv Vars
の環境変数を参照して展開することはできない
前述の評価順序に従えば納得ですね。
Custom Environment Variables
を参照して変数展開することはできるのか?
Env Vars
でSLACK_CHANNEL
を以下のように追加しておきます。
Custom Environment Variables
でENV_PRODUCTION
にprod
を指定します。
こうすると変数展開されて、SLACK_CHANNEL
は#ios-prod
になります。
※下図において、Replace variables in input?
のチェックはここではどちらでも関係ありません
なお、Secrets
でCustom Environment Variables
を受け取って変数展開することはできませんでした。
これも評価順序を理解していれば想定通りです。
Custom Environment Variables
でEnv Vars
を参照して変数展開することはできるのか?
Env Vars
にENV_PRODUCTION
を追加します。
そしてCustom Environment Variables
で変数展開するように指定してみましたが、これはできませんでした。
値が#ios-
になってしまいます。
Custom Environment Variables
同士で参照して変数展開することはできるのか?
Custom Environment Variables
に以下の2つを追加すると、SLACK_CHANNEL
の値は#ios-prod
になります。
変数展開したい方の環境変数ではReplace variables in input?
のチェックをオンにします。
なお、このケースではSLACK_CHANNEL
を先に追加してしまうとENV_PRODUCTION
を参照できないので、追加順序に気をつけてください。
あとがき
ユニットテストやビルドの作成に限らず、Bitriseを使うと様々なことが自動化できて便利です。
使い込み出すと、環境変数を変えてワークフローの挙動を制御したりしたくなってくるのですが、環境変数がうまく上書きされなかったりして困ることが結構ありました。
特にReplace variables in input?
を盛大に勘違いしていて、これのチェックをオンにしてればCustom Environment Variables
で上書きできるんだろうと思っていたのですが、全然違いました。。
調べてみると、割と深く理解してないと環境変数をうまく使いこなせないことがわかり、今回時間をかけて整理をしてみました。
同じように困ってる人の助けになれば幸いです。