概要
- CircleCI2.1のcommandsとexecutorsは便利なので使ってないなら使いましょう
- CircleCIというよりはYAMLの記法にあるアンカー(
&
)、エイリアス(*
)、マージ(<<
)をうまいこと使いましょう
commandsとexecutorsについて
commands (requires version: 2.1)
よく使うパターンのstepsをパラメータ指定で使い回せる。
commands:
sayhello:
description: "A very simple command for demonstration purposes"
parameters:
to:
type: string
default: "Hello World"
steps:
- run: echo << parameters.to >>
ちなみに弊社で実際使ってる例はこのくらいでした (パラメータは結局使っていなかった )
commands:
xxxxxx_checkout: # 共通のチェックアウト
steps:
- checkout:
path: /xxxxxx
go_mod_download: # go moduleのdownloadとcache
steps:
- restore_cache:
name: Restore go modules cache
keys:
- mod-{{ .Environment.COMMON_CACHE_KEY }}-{{ checksum "../go.mod" }}
- run: go mod download
- save_cache:
name: Save go modules cache
key: mod-{{ .Environment.COMMON_CACHE_KEY }}-{{ checksum "../go.mod" }}
paths:
- /xxxxxx/server/pkg/mod/cache
executors (requires version: 2.1)
dockerイメージ、環境変数、workingDirectoryを1セットにして使い回せる感じです。
version: 2.1
executors:
my-executor:
docker:
- image: circleci/ruby:2.5.1-node-browsers
弊社だとMonorepoにしてるので、色々なbuildが存在しているのですがgolangのbuildは、同じexecutorを使いまわせたりできています。
executors:
lambda-build-executor:
docker:
- image: kyokomi/docker-golang
environment:
<<: *env-xxxxxx-go-path
working_directory: /xxxxxx/server/src/cluster/lambda
lambda-deploy-executor:
docker:
- image: hashicorp/terraform:latest
environment:
<<: *env-aws-key-zzzzzz-foobar-deploy
yyyyyy-build-executor:
docker:
- image: kyokomi/docker-golang
environment:
APP_NAME: yyyyyy
<<: *env-xxxxxx-go-path
working_directory: /xxxxxx/server/src/cluster/yyyyyy
aws-ecr-deploy-executor:
docker:
- image: kyokomi/docker-golang
aws-ecs-deploy-executor:
docker:
- image: hashicorp/terraform:latest
アンカー(&
)、エイリアス(*
)、マージ(<<
)
アンカーとエイリアス
たとえばこんな感じにmysqlが起動しているか確認する run
があるとして、 &run-waitmysql
というアンカーを設定すると run: *run-waitmysql
で同じ内容を実行してくれます。
...
- run: &run-waitmysql
name: Waiting for MySQL to be ready
command: |
i=0
while true; do
if exec 3<> /dev/tcp/127.0.0.1/3306; then
exit 0
else
((i++))
echo $i
[ $i -gt 30 ] && exit 1
fi
sleep 1
done
shell: /bin/bash
- run: *run-waitmysql # run: &run-waitmysql と同じ内容を実行してくれます
アンカーをマージ
AWS_ACCESS_KEY_IDやAWS_SECRET_ACCESS_KEYをそのままベタッと書くとあとで見たときにこのkeyって何のkeyだっけ?となることが多く。referencesに定義してアンカーを設定してマージを使うと整理できて便利です。
references:
# とある権限をもつaws keyその1
env-aws-key-xxxxxx-ci: &env-aws-key-xxxxxx-ci
AWS_DEFAULT_REGION: ap-northeast-1
AWS_ACCESS_KEY_ID: AKIAIxxxxxxxxxxxxxx
AWS_SECRET_ACCESS_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# とある権限をもつaws keyその2
env-aws-key-zzzzzzz-foobar-deploy: &env-aws-key-zzzzzz-foobar-deploy
AWS_DEFAULT_REGION: ap-northeast-1
AWS_ACCESS_KEY_ID: AKIxxxxxxxxxxxxxxx
AWS_SECRET_ACCESS_KEY: fffffffffffffffffffffffffffffffff
# 全buildでGOPATHは共通、GO111MODULEはデフォルトでONにしたい環境変数
env-go-path: &env-xxxxxx-go-path
GOPATH: "/xxxxxx/server:/go"
GO111MODULE: "on"
executors:
lambda-build-executor:
docker:
- image: kyokomi/docker-golang
environment:
<<: *env-xxxxxx-go-path # ここでマージしている
working_directory: /xxxxxx/server/src/cluster/lambda
lambda-deploy-executor:
docker:
- image: hashicorp/terraform:latest
environment:
<<: *env-aws-key-zzzzzz-foobar-deploy # ここでマージしている
executors:
lambda-build-executor:
docker:
- image: kyokomi/docker-golang
environment:
GOPATH: "/xxxxxx/server:/go"
GO111MODULE: "on"
working_directory: /xxxxxx/server/src/cluster/lambda
lambda-deploy-executor:
docker:
- image: hashicorp/terraform:latest
environment:
AWS_DEFAULT_REGION: ap-northeast-1
AWS_ACCESS_KEY_ID: AKIxxxxxxxxxxxxxxx
AWS_SECRET_ACCESS_KEY: fffffffffffffffffffffffffffffffff
ちなみに、この辺をうまいこと使えば実は commands
や executors
もなくてもなんとかなっていました。
が、使い方をミスるとわけわからないDSLみたいになるので一定のルールを決めておくといいと思います。
(prefix env-xxxx
なら 環境変数をマージする用、 run-xxxx
なら run:でエイリアスする等など)
おわり
.circleci/config.yml
なかなかリファクタせずにコピペで済ませてしまうことが多く、いざ編集するときメンテナンスが大変でしたが、こうやって整理していくことでプログラムぽくしていくことで1000step超えのymlでも見渡しがいいようしていけるといいですね。
(config.yml分割したい...)