CircleCI2入門④ Workflowsを使う
こんにちは、プログラマーの@Yuuです。
前回の記事でCircleCI上でLintを通せるようにしました。今回は前回のコードを使いつつ、CircleCI2の新機能「Workflows」を使って並列処理・直接処理を試してみます。
プラスで下記2点も合わせてやってみます。
- 特定ブランチにpushした場合のみCircleCIを起動する
approval
で人が承認した場合のみその後の処理を動作させる
出来るかドキドキ。
スポンサーリンク
Workflowsとは
Workflowsを調べてるとよく「ビルドパイプラインみたいなもの」て出てきてビルドパイプラインてなんぞ?て思ってたんだんですけど、Jenkinsの機能の1つなんですね。
Jenkinsとの違いは1回目の記事で書いたので興味あればどぞー
CircleCI2入門① CirlceCIについて | Yuuの悠々自適Blog
で、結局Workflowsて何?て話なんですが、
テストなどを細かい単位に分け、それぞれの処理が正常に出来ているか確認出来るようにするものです。
例えば、Workflowsを使わない場合
このように「1つの箱のどこかで失敗したよ」というのが表示されてしまい、どこで失敗したのか分からない。(実際は処理の中を見ればどこで失敗したかは分かりますが)
これをWorkflowsを使うことで
このように「あ、静的解析3で落ちたのね」と処理の切り分けが分かりやすくなります。
また、CircleCI1でも並列処理は出来るようですが、Workflowsを使う事でより分かりやすく並列処理を行う事ができるみたいです。
(CircleCI1は使った事がないですが、記事見る限りそんな印象)
上記画像ではユニットテストと静的解析の部分が並列処理ですねー。
更にapproval
という機能があり人がCircleCI上で承認をした場合その先の処理を実行するという事も出来ます。
上記画像であれば「承認する?」と書かれたところで人がGOサインを出す事でデプロイする事が出来るというわけです、結果を見て判断出来るので便利〜!
Workflowsの説明は、ymlの設定ファイルとイメージも一緒に載っているCircleCIの公式サイトが英語ですが、すごく分かりやすく書かれていました。英語分からくてもイメージと紐付いて理解できます、自分全く英語出来ないけどなんとなく理解出来たのでw
Orchestrating Workflows - CircleCI
Workflowsを試す
では、本題に。
前回使用したプロジェクトのCircleCIの設定ファイルを変更してWorkflowsに対応させていきます。
新たに環境構築して試してみたい人は以下のコマンドで環境構築して下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# cloneしたいフォルダに移動 cd project/path # cloneする git clone https://github.com/meganedogYuu/CircleciGithubSample2.git # npm installする cd CircleciGithubSample2 npm install # Lintが通るかテスト npm run lint1 # => 成功すればOK npm run lint2 # => 失敗すればOK |
あと完成系というか、苦しみまくった痕跡が残っている全処理が終わった後のリポジトリもあるので、良ければそちらも合わせて参考にしてみて下さい。
meganedogYuu/CircleciGithubSample3: CircleCI2のWorkflowsを試す
Workflows - 直列処理
cloneしてきたところから cicleci/config.yml
を以下のように編集する事でWorkflowsを使って直接処理が出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
version: 2 jobs: build: working_directory: ~/mern-starter docker: - image: circleci/node:7.10 steps: - checkout - restore_cache: key: node_modules - run: name: Install npm command: npm install - save_cache: key: node_modules paths: - node_modules echo_version: docker: - image: circleci/node:7.10 steps: - checkout - run: name: echo npm version command: npm -v lint1: working_directory: ~/mern-starter docker: - image: circleci/node:7.10 steps: - checkout - restore_cache: key: node_modules - run: name: check test1.js lint command: npm run lint1 lint2: working_directory: ~/mern-starter docker: - image: circleci/node:7.10 steps: - checkout - restore_cache: key: node_modules - run: name: check test2.js lint command: npm run lint2 workflows: version: 2 build_and_lint: jobs: - build - echo_version: requires: - build - lint1: requires: - echo_version - lint2: requires: - lint1 |
CircleCI公式にnodeの場合のサンプルが載っていたのでそれを参考にしましたー、1点かなり苦しんだ部分があったので後述します。(ハイライトしている部分です)
Sample 2.0 config.yml Files - CircleCI
処理について
まずjobs
のところでbuild
・echo_version
・lint1
・lint2
の4つの処理を定義しています。
そしてWorkflowsでどのような順番で処理をするか定義します。
lint1
やlint2
のようにrequires
が書かれたものは、そこに定義された処理が終わらないと処理が実行されません。
そのため上記処理の場合build
→ echo_version
→ lint1
→ lint2
と順番に処理が行われます。
実際にCircleCI上では以下のように結果が表示されます。
(Lint2は処理が失敗するのでCI上で☓になる)
苦労した点
苦労したのはハイライトしている15行目の部分。
公式に書かれているとおりdependency-cache-{{ checksum "package.json" }}
と書くと失敗しちゃうんですよね・・何でだろ?
1 2 3 4 |
- save_cache: key: dependency-cache-{{ checksum "package.json" }} paths: - node_modules |
良く分からんと思って苦し紛れに上記のconfig.ymlのように key: node_modules
としたら通ったという。。。
他の方が書かれている記事を見る限りプレースホルダ使った方が良いみたいなのでいずれ直さなければ。
キャッシュはkeyを設定して名前をつけることができる。ここでは-{{ epoch }}というプレースホルダがついているが、こうすることで毎回のビルドでキャッシュを分離するということが可能になる(1.0時代はキャッシュでハマることがあったのでこれはありがたい)。
CircleCI2.0事始め -新しいcircle.ymlとworkflows編- #circleci · tehepero note 2.0より引用
引用元の記事Workflows理解する上でとっても分かりやすい記事でした、感謝!!
Workflows - 並列処理
変更した箇所は workflows:
以下のみです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
version: 2 jobs: build: working_directory: ~/mern-starter docker: - image: circleci/node:7.10 steps: - checkout - restore_cache: key: node_modules - run: name: Install npm command: npm install - save_cache: key: node_modules paths: - node_modules echo_version: docker: - image: circleci/node:7.10 steps: - checkout - run: name: echo npm version command: npm -v lint1: working_directory: ~/mern-starter docker: - image: circleci/node:7.10 steps: - checkout - restore_cache: key: node_modules - run: name: check test1.js lint command: npm run lint1 lint2: working_directory: ~/mern-starter docker: - image: circleci/node:7.10 steps: - checkout - restore_cache: key: node_modules - run: name: check test2.js lint command: npm run lint2 workflows: version: 2 build_and_lint: jobs: - build - echo_version - lint1: requires: - build - lint2: requires: - build |
2つのLintの処理はbuild
してからでないと失敗するのでこのようにしてます。
これで実行すると無事並列処理が出来てますね!
Workflows - approval・特定ブランチの場合のみ動作させる
承認を行うapproval
処理と、その後にデプロイを想定したdeploy
処理の2つを追加します。
プラスで以下3つの条件も追加します。
lint1
とlint2
が正常に通ったらapproval
処理を実行approval
はブランチがmaster
の時のみ実行approval
で人が承認を出した場合のみdeploy
を実行
まず lint2
を通るようにしないといけないので、test2.jsの内容をtest1.jsと同じ内容にしてESLintのテストが通るようにします。
1 2 3 4 5 6 |
function hello(name) { var val = "Hello " + name; document.body.textContent = val; } hello("CircleCI"); |
上記のようにtest2.jsを修正後 npm run lint2
でエラーが起きなければOK。
そして circle/config.yml
のように変更します。
変更内容は hold
・deploy
2つの処理の追加、Workflowsの処理の追加です。
hold
がapproval
処理を想定したものです。
(hold
という書き方は公式を参考にしました)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
version: 2 jobs: build: working_directory: ~/mern-starter docker: - image: circleci/node:7.10 steps: - checkout - restore_cache: key: node_modules - run: name: Install npm command: npm install - save_cache: key: node_modules paths: - node_modules echo_version: docker: - image: circleci/node:7.10 steps: - checkout - run: name: echo npm version command: npm -v lint1: working_directory: ~/mern-starter docker: - image: circleci/node:7.10 steps: - checkout - restore_cache: key: node_modules - run: name: check test1.js lint command: npm run lint1 lint2: working_directory: ~/mern-starter docker: - image: circleci/node:7.10 steps: - checkout - restore_cache: key: node_modules - run: name: check test2.js lint command: npm run lint2 hold: working_directory: ~/mern-starter docker: - image: circleci/node:7.10 steps: - run: name: hold command: echo approve? deploy: working_directory: ~/mern-starter docker: - image: circleci/node:7.10 steps: - run: name: deploy command: echo deploy workflows: version: 2 build_and_lint: jobs: - build - echo_version - lint1: requires: - build - lint2: requires: - build - hold: type: approval requires: - lint1 - lint2 filters: branches: only: master - deploy: requires: - hold |
83行目のようにtype: approval
と書くとCircleCI上で人が承認した場合のみ、その後の処理が動作します。
上記のようにholdで一旦処理が停止しているのでholdと書かれた部分をクリックすると
ここでApproveを選択するとこの後のdeploy処理が実行されます。
SUCCESSED!!
特定ブランチのみに動作させる
87~89行目のように書くことでmaster
ブランチにpushした場合のみ動作させる事が出来ます。
複数ブランチを指定する場合は以下のように書きます。
1 2 3 4 5 |
filters: branches: only: - master - beta |
あとがき
想定通りかなり苦しみながらどうにか出来ました、Workflows。笑
公式通りに色々やってみて出来なかった時は「あれ?この記事公開出来ないんじゃね...??」と本気で思ってました^^;
良かった良かった。
Workflowsの機能を使って思った事は、jobsで必要な処理を定義し、Workflowsで順番や条件を記載するのでかなり分かりやすいな、ということ。
今回のような単純ものではなく、複数人で開発するプロジェクトの場合、かなり見通しが良く分かりやすくなるだろうなぁと感じました。
そしてきちんとテストを定義して、CircleCIの設定さえしてしまえば、後はGitHubやBitBucketにpushすれば自動的にテストしてくれるというのはすごく楽でいいですね。
Jenkinsを使った事がないのでなんともですが、Jenkinsサーバの管理もしなくていいしCircleCIでかなりの事が出来そうだからやっぱりCIサービスて素敵だなぁと思いました。
最後に途中でさらっと書いていた今回記事を書くにあたり使用したリポジトリを置いておきます。
meganedogYuu/CircleciGithubSample3: CircleCI2のWorkflowsを試す