CircleCI 2.0への移行

前提

Webページを静的サイトジェネレータで作成し,Githubで管理して,S3に公開している(参考| Webサイト管理・公開をhugo+GitHub+S3で).

GitHubにpushするとCircleCIが自動的にビルドとデプロイをするよう設定している. 現状で利用しているcircle.ymlはこんな感じ.

checkout:
  post:
    - git submodule sync
    - git submodule update --init --recursive

machine:
  timezone:
    Asia/Tokyo

dependencies:
  override:
    - sudo pip install awscli
    - sudo pip install Pygments
    - sudo pip install pygments-github-lexers
  pre:
    - go get -v github.com/gohugoio/hugo
    - git config --global user.name "noshita"
    - git config --global user.email "noshita@morphometrics.jp"
  post:
    - aws configure set region us-west-2
    - aws configure set preview.cloudfront true

test:
  override:
    - echo "Nothing to do here"

deployment:
  production:
    branch: master
    commands:
      - hugo --cleanDestinationDir 
      - aws s3 sync ~/koji.noshita.net/public/ s3://koji.noshita.net/ --delete
      - aws cloudfront create-invalidation --distribution-id <CloudFront ID> --paths '/*'

これをCircleCI 1.0が終了するので2.0へ移行することにした.

config-translation APIによる移行

CircleCIは1.0から2.0への移行のためのツールconfig-translationを用意してくれている. 今回はAPIから利用した.

 curl "https://circleci.com/api/v1.1/project/github/USERNAME/REPOSITORYNAME/config-translation?circle-token=$CIRCLE_TOKEN" > tmp.yml

GitHubのユーザー名(USERNAME),対象となるリポジトリ(REPOSITORYNAME),CircleCI API トークンCIRCLE_TOKEN)はそれぞれ自身の環境に合わせたものを利用する.

ここでは出力結果をtmp.ymlに保存しているので,これを参考にしていく.

# This configuration was automatically generated from a CircleCI 1.0 config.
# It should include any build commands you had along with commands that CircleCI
# inferred from your project structure. We strongly recommend you read all the
# comments in this file to understand the structure of CircleCI 2.0, as the idiom
# for configuration has changed substantially in 2.0 to allow arbitrary jobs rather
# than the prescribed lifecycle of 1.0. In general, we recommend using this generated
# configuration as a reference rather than using it in production, though in most
# cases it should duplicate the execution of your original 1.0 config.
version: 2
jobs:
  build:
    working_directory: ~/noshita/koji.noshita.net
    parallelism: 1
    shell: /bin/bash --login
    # CircleCI 2.0 does not support environment variables that refer to each other the same way as 1.0 did.
    # If any of these refer to each other, rewrite them so that they don't or see https://circleci.com/docs/2.0/env-vars/#interpolating-environment-variables-to-set-other-environment-variables .
    environment:
      CIRCLE_ARTIFACTS: /tmp/circleci-artifacts
      CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
    # In CircleCI 1.0 we used a pre-configured image with a large number of languages and other packages.
    # In CircleCI 2.0 you can now specify your own image, or use one of our pre-configured images.
    # The following configuration line tells CircleCI to use the specified docker image as the runtime environment for you job.
    # We have selected a pre-built image that mirrors the build environment we use on
    # the 1.0 platform, but we recommend you choose an image more tailored to the needs
    # of each job. For more information on choosing an image (or alternatively using a
    # VM instead of a container) see https://circleci.com/docs/2.0/executor-types/
    # To see the list of pre-built images that CircleCI provides for most common languages see
    # https://circleci.com/docs/2.0/circleci-images/
    docker:
    - image: circleci/build-image:ubuntu-14.04-XXL-upstart-1189-5614f37
      command: /sbin/init
    steps:
    # Machine Setup
    #   If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each
    # The following `checkout` command checks out your code to your working directory. In 1.0 we did this implicitly. In 2.0 you can choose where in the course of a job your code should be checked out.
    - checkout
    # Prepare for artifact and test results  collection equivalent to how it was done on 1.0.
    # In many cases you can simplify this from what is generated here.
    # 'See docs on artifact collection here https://circleci.com/docs/2.0/artifacts/'
    - run: mkdir -p $CIRCLE_ARTIFACTS $CIRCLE_TEST_REPORTS
    # This is based on your 1.0 configuration file or project settings
    - run:
        working_directory: ~/noshita/koji.noshita.net
        command: 'echo ''Asia/Tokyo'' | sudo tee -a /etc/timezone; sudo dpkg-reconfigure
          -f noninteractive tzdata; sudo service mysql restart; sudo service postgresql
          restart; '
    # Checkout
    #   This would typically go in either a build or a build-and-test job when using workflows
    # This is based on your 1.0 configuration file or project settings
    - run: git submodule sync
    - run: git submodule update --init --recursive
    # Dependencies
    #   This would typically go in either a build or a build-and-test job when using workflows
    # Restore the dependency cache
    - restore_cache:
        keys:
        # This branch if available
        - v1-dep-{{ .Branch }}-
        # Default branch if not
        - v1-dep-master-
        # Any branch if there are none on the default branch - this should be unnecessary if you have your default branch configured correctly
        - v1-dep-
    # This is based on your 1.0 configuration file or project settings
    - run: go get -v github.com/gohugoio/hugo
    - run: git config --global user.name "noshita"
    - run: git config --global user.email "noshita@morphometrics.jp"
    # This is based on your 1.0 configuration file or project settings
    - run: sudo pip install awscli
    - run: sudo pip install Pygments
    - run: sudo pip install pygments-github-lexers
    # This is based on your 1.0 configuration file or project settings
    - run: aws configure set region us-west-2
    - run: aws configure set preview.cloudfront true
    # Save dependency cache
    - save_cache:
        key: v1-dep-{{ .Branch }}-{{ epoch }}
        paths:
        # This is a broad list of cache paths to include many possible development environments
        # You can probably delete some of these entries
        - vendor/bundle
        - ~/virtualenvs
        - ~/.m2
        - ~/.ivy2
        - ~/.bundle
        - ~/.go_workspace
        - ~/.gradle
        - ~/.cache/bower
    # Test
    #   This would typically be a build job when using workflows, possibly combined with build
    # This is based on your 1.0 configuration file or project settings
    - run: echo "Nothing to do here"
    # Deployment
    # Your existing circle.yml file contains deployment steps.
    # The config translation tool does not support translating deployment steps
    # since deployment in CircleCI 2.0 are better handled through workflows.
    # See the documentation for more information https://circleci.com/docs/2.0/workflows/
    # Teardown
    #   If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each
    # Save test results
    - store_test_results:
        path: /tmp/circleci-test-results
    # Save artifacts
    - store_artifacts:
        path: /tmp/circleci-artifacts
    - store_artifacts:
        path: /tmp/circleci-test-results

deployとworkflow

概ね自動で変換してくれたが,config-translationはdeploymentステップはサポートしていないので,追記する.

	deploy:
	  environment:
	    TZ: /usr/share/zoneinfo/Asia/Tokyo
	  docker:
	    - image: circleci/python:3.6-stretch
	  working_directory: ~/noshita/koji.noshita.net
	  steps:
	    - attach_workspace:
	        at: ~/koji.noshita.net
	    - run:
	        name: Install awscli
	        command: sudo pip install awscli
	    - run: aws configure set region us-west-2
	    - run: aws configure set preview.cloudfront true
	    - run:
	        name: Deploy to S3
	        command: aws s3 sync ~/koji.noshita.net/public/ s3://koji.noshita.net/ --delete
	    - run:
	        name: Deploy to CloundFront
	        command: aws cloudfront create-invalidation --distribution-id <CloudFront ID> --paths '/*'

deployステップはjobs以下に追加する.

また,CircleCI 2.0で導入されたworkflowにより実行の順序を制御する.

workflows:
  version: 2
  build-deploy:
    jobs:
      - build
      - deploy:
          requires:
            - build
          filters:
            branches:
              only: master

workflowsは最上位に配置(ネストしない).

docker imageの変更とコンテナをまたいだデータの受け渡し

buildステップで利用するdocker imageをgolang版に変更した.

また,buildステップとdeployステップで利用するコンテナが異なるので, ビルドしたwebページ関連のファイルを渡せるようにpersist_to_workspaceattach_workspaceを設定した.

最終的には以下の様になった.

version: 2
jobs:
  build:
    working_directory: ~/noshita/koji.noshita.net
    parallelism: 1
    environment:
      CIRCLE_ARTIFACTS: /tmp/circleci-artifacts
      CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
      TZ: /usr/share/zoneinfo/Asia/Tokyo
    docker:
    - image: circleci/golang:1.10-stretch
      # command: /sbin/init
    steps:
      - checkout
      - run: mkdir -p $CIRCLE_ARTIFACTS $CIRCLE_TEST_REPORTS
      - run: git submodule sync
      - run: git submodule update --init --recursive
      - run: go get -v github.com/gohugoio/hugo
      - run: git config --global user.name "noshita"
      - run: git config --global user.email "noshita@morphometrics.jp"
      # This is based on your 1.0 configuration file or project settings
      # - run: sudo pip install awscli
      - run: sudo apt-get install python-pip
      - run: sudo pip install Pygments
      - run: sudo pip install pygments-github-lexers
      - run: hugo --cleanDestinationDir 
      # This is based on your 1.0 configuration file or project settings
      # Test
      - run: echo "Nothing to do here"
      # Save test results
      - store_test_results:
          path: /tmp/circleci-test-results
      # Save artifacts
      - store_artifacts:
          path: /tmp/circleci-artifacts
      - store_artifacts:
          path: /tmp/circleci-test-results
      - persist_to_workspace:
            root: ~/noshita/koji.noshita.net
            paths:
              - public
  deploy:
    environment:
      TZ: /usr/share/zoneinfo/Asia/Tokyo
    docker:
      - image: circleci/python:3.6-stretch
    working_directory: ~/noshita/koji.noshita.net
    steps:
      - attach_workspace:
          at: ~/koji.noshita.net
      - run:
          name: Install awscli
          command: sudo pip install awscli
      - run: aws configure set region us-west-2
      - run: aws configure set preview.cloudfront true
      - run:
          name: Deploy to S3
          command: aws s3 sync ~/koji.noshita.net/public/ s3://koji.noshita.net/ --delete
      - run:
          name: Deploy to CloundFront
          command: aws cloudfront create-invalidation --distribution-id <CloudFront ID> --paths '/*'
workflows:
  version: 2
  build-deploy:
    jobs:
      - build
      - deploy:
          requires:
            - build
          filters:
            branches:
              only: master

確認

設定ファイルは従来circle.ymlであったが,2.0からは.circleci/config.ymlとなるので,そのように保存する.

circleciコマンドから設定ファイルの検証ができるので,まずはこれで確認する. macOSではhomebrewで導入できる.

circleci config validate -c .circleci/config.yml
# 問題なければ

.circleci/config.yml is valid

# と表示される

問題なければ,GitHubへプッシュし,ビルドが成功すれば移行できたことになる.

Webのインターフェースの方では特に操作は必要ないが,Circle2.0で実行されていることだけ確認しておくと良い.