CircleCI2.0の特徴のひとつであるWorkflowを触ってみます。
workflowを設定してみる
CircleCI2.0でWorkflowを設定しなかった場合、buildjobのみが走ります。
試しに以下を試してみます。
version: 2
jobs:
hoge: # <-- ここ
working_directory: ~/workspace
docker:
- image: node:9.4.0
steps:
- checkout
- run:
name: Echo
command: echo hello, world.
すると、ビルドは失敗し、以下のようなエラーが出ます。
workflowでhogeを実行するように修正します。
version: 2
jobs:
hoge:
working_directory: ~/workspace
docker:
- image: node:9.4.0
steps:
- checkout
- run:
name: Echo
command: echo hello, world.
workflows:
version: 2
fuga:
jobs:
- hoge
これでhogeが実行され、ビルドが通るようになりました。
ビルドとテストを走らせる
ここからは前記事のNuxtアプリケーションを土台に説明していきます。
「ビルドしてからテストを走らせる」例です。
version: 2
jobs:
build:
working_directory: ~/workspace
docker:
- image: node:9.4.0
steps:
- checkout
- restore_cache:
key: yarn-{{ .Branch }}-{{ checksum "yarn.lock" }}
- run:
name: Install dependencies
command: yarn
- run:
name: Build
command: yarn build
- save_cache:
key: yarn-{{ .Branch }}-{{ checksum "yarn.lock" }}
paths:
- ~/workspace/node_modules
test:
working_directory: ~/workspace
docker:
- image: node:9.4.0
steps:
- checkout
- restore_cache:
key: yarn-{{ .Branch }}-{{ checksum "yarn.lock" }}
- run:
name: Install dependencies
command: yarn
- run:
name: Build
command: yarn build
- run:
name: Test
command: yarn test
workflows:
version: 2
build_and_test: # workflow名
jobs:
- build
- test:
requires: # buildが成功したら実行する
- build
test
基本的な構造はbuildと同じで、Testを追加しました。
workflows
実行する順序を規定しています。
その他、コメントを参照。
実行結果
実行結果を見てみると2つのビルドが走っています。
build_and_testをクリックすると、Workflow図を見ることができます。
Workspaceを後続のビルドにシェアする
上記のビルドでは、buildでソースコードをビルドして、testでも同じことをやっていて非効率的ですので、buildでビルドしたものをtestでも使えるようにします。
version: 2
jobs:
build:
working_directory: ~/workspace
docker:
- image: node:9.4.0
steps:
- checkout
- restore_cache:
key: yarn-{{ .Branch }}-{{ checksum "yarn.lock" }}
- run:
name: Install dependencies
command: yarn
- run:
name: Build
command: yarn build
- save_cache:
key: yarn-{{ .Branch }}-{{ checksum "yarn.lock" }}
paths:
- ~/workspace/node_modules
- persist_to_workspace:
root: . # workspaceのrootパス(絶対パスかworking_directoryからの相対パス)
paths:
- . # 共有するパス(絶対パスかrootからの相対パス)
test:
working_directory: ~/workspace
docker:
- image: node:9.4.0
steps:
- attach_workspace: # workspaceをアタッチする
at: .
- run:
name: Test
command: yarn test
workflows:
version: 2
build_and_test:
jobs:
- build
- test:
requires:
- build
persist_to_workspace
共有するパスを設定します。
pathsでは共有するパスを指定します。
.としているので、~/workspaceディレクトリがまるごと共有されます。
例えば、.をdistと置き換えた場合は、distディレクトリのみが共有されます。
attach_workspace
persist_to_workspaceで共有したworkspaceをアタッチします。
実行結果
buildのpersist_to_workspaceの処理に4秒ほどとられていますが、22秒かかっていたtestが3秒になりました。
特定のブランチでしか実行しないようにする
「masterブランチのときのみdeployを実行する」というのをやってみます。
まずは、deployjobを作ります。
deploy:
working_directory: ~/workspace
docker:
- image: node:9.4.0
steps:
- attach_workspace:
at: .
- deploy:
command: echo Deploy!
次にworkflowにdeployを追加します。
workflows:
version: 2
build_and_test:
jobs:
- build
- test:
requires:
- build
- deploy:
requires:
- build
- test
filters:
branches:
only: master
実行結果
masterにpushしたときはdeployしますが、
developにpushしたときはdeployを実行していません。
特定のjobを実行する前に人間の承認を待つようにする
自動で実行されると困るタスクに使います。
buildとtestのみ自動で行い、deployは手動で承認ボタンを押したら実行するようにしてみます。
workflows:
version: 2
build_and_test:
jobs:
- build
- test:
requires:
- build
- deploy-approval:
type: approval
requires:
- build
- test
filters:
branches:
only: master
- deploy:
requires:
- deploy-approval
deploy-approvalは承認を待つだけのjobなので、処理は行いません。なので、deployにtype: approvalをつけると、deployが走らなくなります。
実行結果
testが成功した時点で、処理が止まるようになりました。
丸いの一時停止ボタンをクリックすると確認のダイアログが出現します。「Approve」を押すと、deployが実行されます。
tagがついているときのみ実行するようにする
「リリースノートを書いたらデプロイ」としたい場合は、タグ作成が行われたときのみ、deployが実行されるようにします。
workflows:
version: 2
build_and_test:
jobs:
- build:
filters:
tags:
only: /.*/
- test:
requires:
- build
filters:
tags:
only: /.*/
- deploy:
requires:
- build
- test
filters:
branches:
ignore: /.*/
tags:
only: /^v[0-9]+(\.[0-9]+){2}/
すべてのjobにtags filterをかける
すべてのjobに、全タグで実行すると明示的に記述していることに違和感があると思いますが、これは、filterのデフォルト設定が**「すべてのブランチに対して実行する」に対して、「いかなるタグにも実行しない」**ということになっているからです。
CircleCIのドキュメントには以下のように書いてあります。
- If neither only nor ignore are specified then all branches will run the job.
- If neither only nor ignore are specified then the job is skipped for all tags.
特定のtagのみで実行したいjobにbranches filterをかける
deployのfiltersに**「すべてのブランチで実行しない」**と設定しています。これがないと、タグがなくても実行されてしまいます。
filters:
branches:
ignore: /.*/
有効なtagのフォーマットを正規表現で指定する
tagsは正規表現でフィルタリングできます。
v1.0.0やv1.0.0betaなどを許可する例がこちら。
tags:
only: /^v[0-9]+(\.[0-9]+){2}.*/
実行結果
pushをトリガーにしたworkflow
タグの作成をトリガーにしたworkflow
まとめ
workflowには他にもcronがあったりますが、ここまでで充分実践でも使えるようになるのではないでしょうか。
参考









