Carpe Diem

備忘録

CircleCI 2.1 でconfigの記述をシンプルにする

概要

christina04.hatenablog.com

でCircleCIの使い方を説明しましたが、2.1からconfigの記述がよりシンプルになりましたので説明します。

環境

  • CircleCI 2.1

設定

CircleCI側

まずはAdvanced Settingsで2.1の機能が使えるようにします。

f:id:quoll00:20190125133015p:plain

古いプロジェクトだとOFFのままなのでONにしてください。新しいプロジェクトだと最初からONになっています。

configの修正

before

以前の記事のconfigは以下の感じでした。

yamlエイリアスを使った共通化

defaults: &defaults
  working_directory: /go/src/github.com/jun06t/sample-api
  environment:
    TZ: "/usr/share/zoneinfo/Asia/Tokyo"

jobs

deploy_devとdeploy_stgがほぼ同じ記述なのに、書かないといけなく冗長に感じますね。

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: Install dependencies
          command: |
            wget https://bootstrap.pypa.io/get-pip.py
            sudo python get-pip.py
            sudo pip install awscli
      - 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: Install dependencies
          command: |
            wget https://bootstrap.pypa.io/get-pip.py
            sudo python get-pip.py
            sudo pip install awscli
      - run:
          name: Build docker image
          command: |
            make build
      - deploy:
          name: Deploy container
          command: |
            ./scripts/deploy.sh stg ${CIRCLE_TAG}

workflows

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}$/

after

新しい書き方だと以下のようになります。

共通部分の切り出し

各jobで共通化できそうな部分を関数化できるようなりました。

executors

以前はyamlエイリアスを使っていた、環境周りの設定を関数化できます。

ref: Authoring Reusable Executors

commands

stepsでの処理を関数化できます。

ref: Authoring Reusable Commands

今回だと

  • aws cliのインストール
  • vendorのキャッシュ保存
  • キャッシュ取得

を共通化してみました。

version: 2.1
executors:
  default:
    working_directory: /go/src/github.com/jun06t/sample-api
    environment:
      TZ: "/usr/share/zoneinfo/Asia/Tokyo"
    docker:
      - image: circleci/golang:1.11
commands:
  setup_awscli:
    steps:
      - run:
          name: Install dependencies
          command: |
            wget https://bootstrap.pypa.io/get-pip.py
            sudo python get-pip.py
            sudo pip install awscli
  restore_cache_step:
    steps:
      - restore_cache:
          name: Restore cache
          key: vendor-{{ checksum "Gopkg.lock" }}
  save_cache_step:
    steps:
      - save_cache:
          name: Save cache
          key: vendor-{{ checksum "Gopkg.lock" }}
          paths:
            - vendor

jobs

deploy_devdeploy_stgというような別jobで定義する必要はなくなり1つにまとまりました。

parameters

あらかじめ変数定義しておき、似たようなjobを関数化して再利用できるようになりました。

ref: Using the parameters Declaration

parametersは関数の引数みたいな感じです。ここでは

  • env
  • tag

といった変数を定義しています。

また、先程の共通処理の関数化によって記述がシンプルになってます。

jobs:
  test:
    executor:
      name: default
    steps:
      - checkout
      - restore_cache_step
      - run:
          name: Install dependencies
          command: |
            if [ ! -e vendor ]; then
              dep ensure
            fi
      - run:
          name: Run Tests
          command: |
            make test
  deploy:
    executor:
      name: default
    parameters:
      env:
        type: enum
        enum: ["dev", "stg"]
      tag:
        type: string
    steps:
      - checkout
      - restore_cache_step
      - setup_remote_docker
      - setup_awscli
      - run:
          name: Deploy
          command: |
            ./scripts/deploy.sh << parameters.env >> << parameters.tag >>

workflows

workflowsではジョブ実行時のための変数(parameters)を指定するようになります。
定義した場合は必ず書かないといけません。

workflows:
  test_and_deploy:
    jobs:
      - test:
          filters:
            branches:
              only: /.*/
            tags:
              only: /.*/
      - deploy:
          name: deploy_dev
          env: dev
          tag: latest
          requires:
            - test
          filters:
            branches:
              only: master
      - deploy:
          name: deploy_stg
          env: dev
          tag: ${CIRCLE_TAG}
          requires:
            - test
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^v[0-9](\.[0-9]){2}$/

まとめ

CircleCI 2.1では2.0の冗長な書き方がかなり改善されました。
今後は差分ビルドなども対応してくれると嬉しいですね。

ソース