Git push → CircleCI → Docker build → ECRという流れがあったとして、Docker imageのタグをブランチ名にしたいなんてことがあると思います。
今回はその設定をするのにひと手間かかったという話。
CircleCIにPushされたブランチ名を環境変数から取得してDockerのイメージタグとして登録させたい
題通りの背景があり、ステップやジョブ、Contextによる環境変数での設定(つまり予め決め打ちされたものではなくその都度変わる変数)が必要でした。*1
CircleCIで環境変数を設定する方法はいくつかありますね。
- シェルコマンドで環境変数を設定する
- ステップ内で環境変数を設定する
- ジョブ内で環境変数を設定する
- コンテナ内で環境変数を設定する
- Context内で環境変数を設定する
- プロジェクト内で環境変数を設定する
- API を使って環境変数をインジェクトする方法
- 定義済み環境変数
タグ設定に使ったのはシェルコマンドで環境変数を設定する方法と、定義済みの環境変数です。
CircleCIの定義済み環境変数
CircleCIはビルドしているGit Branchの情報を環境変数として持っています。
CIRCLE_BRANCH
現在ビルドしている Git のブランチ名。
というわけで、素直にこの環境変数を使ってタグを設定しようと考えます。
ECRへのPushはOrbsのJobで十分使えるのでこれを使います。
Dockerタグの命名規則
Dockerタグにはつけられる規則があります。
タグ名に含まれるのは(アルファベット)小文字と大文字、数字、アンダースコア、ピリオド、スラッシュです。タグ名はピリオドやダッシュで開始できません。そして最大で 128 文字です。
もしブランチ名に -
などが入っている場合、これを変更する必要が出てきます。
私の場合、ブランチ命名に -
が入っていました*2
ただ、ブランチ運用ルールをいきなり変えるというのも面倒くさいので、CircleCI上でシェルを実行して対応することにしました。
定義済みである$CIRCLE_BRANCHの値を取得→加工(-
を_
に変換)→新しい環境変数として登録をします。
定義済みの環境変数を加工して新しい環境変数として登録する
コードベースで言うとこうなりました。
echo 'export GIT_BRANCH=$(echo $CIRCLE_BRANCH | sed s#/#\_#g)' >> $BASH_ENV source $BASH_ENV
CircleCIに対して新しく環境変数を定義する場合は、$BASH_ENV
に記述する必要があります。*3
CircleCI は環境変数をセットする際のインターポレーションに対応していません
CircleCI は bash コマンドを用いて、ステップごとにその都度 BASH_ENV の内容を読み込みます。 これはつまり、BASH_ENV の読み込みと実行が自動的に行われ、インターポレーションを可能にし、run ステップ間で環境変数を共有できるということです。
さきほどのcommandを定義してステップの中で実行させれば、-
は_
に変換されて$GIT_BRANCHというこちらが定義した環境変数に格納されます。
set_GitBranch
という任意の名前でreferences.commandsに定義したあと、以下のようにJobのステップに組み込めばOKです。
api-build-and-push-image: &api-build-and-push-image <<: *machine steps: - run: *set_GitBranch - aws-ecr/build-and-push-image: account-url: AWS_ECR_ACCOUNT_URL aws-access-key-id: AWS_ACCESS_KEY_ID aws-secret-access-key: AWS_SECRET_ACCESS_KEY region: AWS_REGION dockerfile: Dockerfile repo: api tag: $GIT_BRANCH
このJobの書き方はOrbsなのでこちらを参考にしてください。
まとめ
- CircleCIで新しい環境変数を登録するときは$BASH_ENVへの記述と読み込みが必要
- Dockerイメージのタグの命名に注意する
これをクリアすれば他で躓くことはあまりないと思います。
それではenjoy CI!