概要
CircleCI 2.0でtagからのビルド&デプロイをできるようにします。
主に使う機能としては
- workflow
- cache
です。workflowはビルドパイプラインのようなもので、実行ジョブを細かく分けて順に実行させることができます。
上の例ではmasterブランチ
にマージ後、test
ジョブが実行されてからdeploy_dev
というdev環境にデプロイするジョブが実行されています。
ジョブ毎に分かれているお陰で、以下のように途中から(失敗したジョブから)実行することも可能です。
基本的な使い方
直列実行のworkflow
ref: Using Workflows to Schedule Jobs - CircleCI
この図のように幾つかのジョブを直列で実行したい場合は
workflows: version: 2 build-test-and-deploy: jobs: - build - test1: requires: - build - test2: requires: - test1 - deploy: requires: - test2
のように書きます。deployを実行したい場合、requires
という依存関係を見ると
- deployはtest2を必要とする
- test2はtest1を
- test1はbuildを
となり、結果として
build -> test1 -> test2 -> deploy
の順に実行されます。
※deploy
の発火条件はこの例では書かれていませんので注意
並列実行のworkflow
ref: Using Workflows to Schedule Jobs - CircleCI
並列に実行したい場合は
workflows: version: 2 build_accept_deploy: jobs: - build - acceptance_test_1: requires: - build - acceptance_test_2: requires: - build - acceptance_test_3: requires: - build - acceptance_test_4: requires: - build - deploy: requires: - acceptance_test_1 - acceptance_test_2 - acceptance_test_3 - acceptance_test_4
こんな感じになります。
build
ジョブ後にacceptance_test_1
~acceptance_test_4
が並行に実行され、それらがすべて完了するとdeploy
ジョブが実行されます。
※deploy
の発火条件はこの例では書かれていませんので注意
特定のブランチで発火させる
ブランチ毎に発火条件を変えたい要件があると思います。その場合
workflows: version: 2 dev_stage_pre-prod: jobs: - test_dev: filters: branches: only: - dev - /user-.*/ - test_stage: filters: branches: only: stage - test_pre-prod: filters: branches: only: /pre-prod(?:-.+)?$/
このようにfilters:
、branches:
の組み合わせで特定のジョブを実行できます。
この例だと
dev
ブランチ、user-xxx
ブランチに変化があったらtest_dev
を実行stage
ブランチに変化があったらtest_stage
を実行pre-prod
ブランチに変化があったらtest_pre-prod
を実行
と言った感じです。
gitのtagに連動させる
gitのtagを発行したらデプロイしたいという要件は多いと思います。この場合
workflows: version: 2 build-n-deploy: jobs: - deploy: filters: tags: only: /^release-v.*/ branches: ignore: /.*/
のようにfilters:
のtags:
セクションを設定すれば発火します。この例だとrelease-v1.0.0
といったtagで発火します。
またbranches:
セクションでignore: /.*/
としていることでブランチの変化(マージやプルリク)に反応しないようにしています。
ただtagの場合注意が必要で、require:
に設定しているジョブも同じtags:
セクションの設定が必要という点です。
例えば
build -> test -> deploy
と実行するworkflowの場合、
workflows: version: 2 build-n-deploy: jobs: - build: filters: tags: only: /^config-test.*/ - test: requires: - build filters: tags: only: /^config-test.*/ - deploy: requires: - test filters: tags: only: /^config-test.*/ branches: ignore: /.*/
このように、どのジョブにもtags:
セクションにonly: /^config-test.*/
という設定をしなくてはいけません。
実際の業務でのyaml
以下の要件を満たすyamlを用意します。
- プルリク時はtestを実行
- マージされたらtestを実行、その後
dev
環境へビルド - tagが発行されたらtestを実行し、その後
stg
環境へビルド
それでは設定を紹介します。
defaults: &defaults working_directory: /go/src/github.com/jun06t/sample-api environment: TZ: "/usr/share/zoneinfo/Asia/Tokyo" version: 2 jobs: test: <<: *defaults docker: - image: circleci/golang:1.9 steps: - checkout - restore_cache: key: vendor-{{ checksum "Gopkg.lock" }} - run: name: Setup For Test command: | if [ ! -e vendor ]; then dep ensure fi - run: name: Run Tests command: | make test - save_cache: key: vendor-{{ checksum "Gopkg.lock" }} paths: - vendor deploy_dev: <<: *defaults docker: - image: circleci/golang:1.9 steps: - checkout - restore_cache: key: vendor-{{ checksum "Gopkg.lock" }} - setup_remote_docker - run: name: Build docker image command: | make build - deploy: name: Deploy container command: | ./scripts/deploy.sh dev latest deploy_stg: <<: *defaults docker: - image: circleci/golang:1.9 steps: - checkout - restore_cache: key: vendor-{{ checksum "Gopkg.lock" }} - setup_remote_docker - run: name: Build docker image command: | make build - deploy: name: Deploy container command: | ./scripts/deploy.sh stg ${CIRCLE_TAG} workflows: version: 2 test_and_deploy: jobs: - test: filters: branches: only: /.*/ tags: only: /.*/ - deploy_dev: requires: - test filters: branches: only: master - deploy_stg: requires: - test filters: branches: ignore: /.*/ tags: only: /^v[0-9](\.[0-9]){2}$/
workflowの説明
testジョブ
- test: filters: branches: only: /.*/ tags: only: /.*/
テストはプルリクやマージで発火するようにしています。またtagに連動する際にrequire:
しているので、tags:
セクションも書いています。
deploy_devジョブ
- deploy_dev: requires: - test filters: branches: only: master
masterブランチにマージされたら発火するようにしています。test
ジョブをrequire:
しているので、テスト後に実行されます。
deploy_stgジョブ
- deploy_stg: requires: - test filters: branches: ignore: /.*/ tags: only: /^v[0-9](\.[0-9]){2}$/
v1.0.0
といったgit tagが発行されたら発火するようにしています。test
ジョブをrequire:
しているので、テスト後に実行されます。
save_cache
golangはvendor
ディレクトリに依存ライブラリを保持します。test時は良いのですが、その後のdeployフローでは再取得するのは無駄です。なので
- save_cache: key: vendor-{{ checksum "Gopkg.lock" }} paths: - vendor
でキャッシュします。key
名をlockファイルのハッシュベースで管理することで、lockファイルが更新されたら新しいキャッシュを作成&利用できます。
利用する際は
- restore_cache: key: vendor-{{ checksum "Gopkg.lock" }}
でできます。
またvendorディレクトリの有無でdep ensure
を実行するか判断します。
- run: name: Setup For Test command: | if [ ! -e vendor ]; then dep ensure fi
tag名を利用
- deploy: name: Deploy container command: | ./scripts/deploy.sh stg ${CIRCLE_TAG}
${CIRCLE_TAG}
という環境変数でtag名を利用できます。workflowでジョブが分けられていてもちゃんと参照できます。
環境変数の一覧は
Using Environment Variables - CircleCI
で確認できます。