CircleCI
CircleCI2.0

CircleCI2.0のWorkflowを試してみる

CircleCI2.0の特徴のひとつであるWorkflowを触ってみます。

workflowを設定してみる

CircleCI2.0でWorkflowを設定しなかった場合、buildjobのみが走ります。

試しに以下を試してみます。

.circleci/config.yml
version: 2
jobs:
  hoge: # <-- ここ
    working_directory: ~/workspace
    docker:
      - image: node:9.4.0
    steps:
      - checkout
      - run:
          name: Echo
          command: echo hello, world.

すると、ビルドは失敗し、以下のようなエラーが出ます。

image.png

workflowでhogeを実行するように修正します。

.circleci/config.yml
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アプリケーションを土台に説明していきます。

「ビルドしてからテストを走らせる」例です。

.circleci/config.yml
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つのビルドが走っています。

image.png

build_and_testをクリックすると、Workflow図を見ることができます。

image.png

Workspaceを後続のビルドにシェアする

上記のビルドでは、buildでソースコードをビルドして、testでも同じことをやっていて非効率的ですので、buildでビルドしたものをtestでも使えるようにします。

.circleci/config.yml
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をアタッチします。

実行結果

buildpersist_to_workspaceの処理に4秒ほどとられていますが、22秒かかっていたtestが3秒になりました。

image.png

特定のブランチでしか実行しないようにする

「masterブランチのときのみdeployを実行する」というのをやってみます。

まずは、deployjobを作ります。

.circleci/config.yml
  deploy:
    working_directory: ~/workspace
    docker:
      - image: node:9.4.0
    steps:
      - attach_workspace:
          at: .
      - deploy:
          command: echo Deploy!

次にworkflowにdeployを追加します。

.circleci/config.yml
workflows:
  version: 2
  build_and_test:
    jobs:
      - build
      - test:
          requires:
            - build
      - deploy:
          requires:
            - build
            - test
          filters:
            branches:
              only: master

実行結果

masterにpushしたときはdeployしますが、

image.png

developにpushしたときはdeployを実行していません。

image.png

特定のjobを実行する前に人間の承認を待つようにする

自動で実行されると困るタスクに使います。

buildtestのみ自動で行い、deployは手動で承認ボタンを押したら実行するようにしてみます。

.circleci/config.yml
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なので、処理は行いません。なので、deploytype: approvalをつけると、deployが走らなくなります。

実行結果

testが成功した時点で、処理が止まるようになりました。

image.png

丸いの一時停止ボタンをクリックすると確認のダイアログが出現します。「Approve」を押すと、deployが実行されます。

image.png

tagがついているときのみ実行するようにする

「リリースノートを書いたらデプロイ」としたい場合は、タグ作成が行われたときのみ、deployが実行されるようにします。

.circleci/config.yml
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をかける

deployfilters「すべてのブランチで実行しない」と設定しています。これがないと、タグがなくても実行されてしまいます。

.circleci/config.yml
          filters:
            branches:
              ignore: /.*/

有効なtagのフォーマットを正規表現で指定する

tagsは正規表現でフィルタリングできます。

v1.0.0v1.0.0betaなどを許可する例がこちら。

.circleci/config.yml
            tags:
              only: /^v[0-9]+(\.[0-9]+){2}.*/

実行結果

pushをトリガーにしたworkflow

image.png

タグの作成をトリガーにしたworkflow

image.png

まとめ

workflowには他にもcronがあったりますが、ここまでで充分実践でも使えるようになるのではないでしょうか。

参考

https://circleci.com/docs/2.0/workflows/