CircleCIを2.0に移行してみた

旅するエンジニアの三宅です。来年の3月にはまた長期で台湾に行ってこようと思ってます。

TimeCrowdではCIツールとしてCircleCIを利用しています。

2.0の正式リリースから3ヶ月が経ち、色々なところでCircleCIを2.0に移行したという記事が上がってきたので、この度私たちのチームでもブログ駆動開発という名の元バージョンアップしてみることにしました。

お品書き

  1. 1.0と2.0の設定ファイル比較
  2. 修正のポイント
  3. さいごに

1.0と2.0の設定ファイル比較

まずは最終的な設定ファイルの比較から入りたいと思います。

1.0と2.0で記述量が全く違うのがわかるかと思います。

1.0ではCircleCI側でよしなに実行してくれていたコマンド類を自前で1つずつ書く必要があるため、総じて設定ファイルは大きくなります。

ただ実行すべきコマンドを1つずつ書くことで何をやっているのかということが明確になって、処理の改善など手を入れやすくなったのではないかなと思います。

1.0

machine:
  node:
    version: 6.9.1

dependencies:
  pre:
    - echo '[mysqld]' | sudo sh -c 'cat >>  /etc/mysql/my.cnf'
    - echo 'innodb_file_format=Barracuda' | sudo sh -c 'cat >>  /etc/mysql/my.cnf'
    - echo 'innodb_file_per_table=1' | sudo sh -c 'cat >>  /etc/mysql/my.cnf'
    - echo 'innodb_large_prefix=1' | sudo sh -c 'cat >>  /etc/mysql/my.cnf'
    - sudo service mysql restart

general:
  artifacts:
    - tmp/rubycritic/rubycritic.html

test:
  post:
    - ./bin/comment_coverage
  pre:
    - mkdir -p tmp/rubycritic
    - bundle exec rubycritic --no-browser -p tmp/rubycritic/rubycritic.html app lib
    - bundle exec rubycritic -f json -p tmp/rubycritic/rubycritic.json app lib

deployment:
  pull_request:
    branch: /.+/
    commands:
      - PASSENGER=1 bundle exec cap pull_request deploy
      - ./bin/comment_pr_url

2.0

version: 2

jobs:
  build:
    working_directory: ~/timecrowd
    docker:
      - image: circleci/ruby:2.4.2
        environment:
          RAILS_ENV: test
          DB_HOST: 127.0.0.1
          REDIS_HOST: 127.0.0.1
      - image: circleci/mysql:5.6
        command: mysqld --innodb-file-format=Barracuda --innodb_file_per_table=true --innodb-large-prefix=true 
      - image: redis

    steps:
      - checkout

      - run: |
          curl -sL https://deb.nodesource.com/setup_6.x | sudo bash -
          sudo apt-get install -y nodejs

      - restore_cache:
          keys:
            - rails-gemfile-{{ checksum "Gemfile.lock" }}
      - run: bundle install --path vendor/bundle
      - save_cache:
          key: rails-gemfile-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle

      - run: npm i

      - run: cp config/database.yml.ci config/database.yml
      - run: bundle exec rake db:create
      - run: bundle exec rake db:schema:load
      - run: |
          bundle exec rspec --format progress \
                            $(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)
      - store_test_results:
          path: /tmp/coverage
      - run: bundle exec rubycritic --no-browser -p /tmp/rubycritic/rubycritic.html app lib
      - run: bundle exec rubycritic -f json -p /tmp/rubycritic/rubycritic.json app lib
      - store_test_results:
          path: /tmp/rubycritic
      - run:
          command: ./bin/comment_coverage
      - store_artifacts:
          path: /tmp/coverage
      - store_artifacts:
          path: /tmp/rubycritic

      - deploy:
          command: |
             if [ "${CIRCLE_BRANCH}" != "master" ]; then
               PASSENGER=1 bundle exec cap pull_request deploy
             fi
      - run:
          command: ./bin/comment_pr_url

修正のポイント

移行するにあたってハマったところや、気をつけなければいけないところをピックアップしてまとめておきます。

  • rubyとmysqlはtcp接続のため、DB_HOSTを127.0.0.1を設定する。
  • サンプルで使用されているcircle/ruby-2.4.1-nodeのバージョンは新しいものが入っているので、古いバージョンを使用している場合には自前でインストールする。
  • テスト結果を表示する場合にはstore_artifactsを、テスト結果の内容を使って何かする際にはstore_test_resultsで出力先を指定する必要がある。

ちなみに、TimeCrowdではPRごとにカバレッジ、コードマトリックスを生成、デモ環境を自動で構築して、その内容をGithubにコメントするようにしています。(comment_coverage, comment_pr_urlがそれにあたります。)

こうすることで常にコードの品質を意識することが出来るような環境を作っています。

さいごに

結果としてTimeCrowdとしてはCIの時間が短くなった!ということはなかったのですが、これから新機能を使うことでCIの実行時間を短縮できるのではないかと期待しています。

今回の対応では触れなかったのですが、2.0からはworkflowという仕組みが追加され、テストを並列に実行したり、途中でCIが失敗した際に、失敗したところから再開するということができるようになるようです。

このあたりはまだちゃんと調べられていないのですが、今後改善を進めていく中でわかったことなどを随時共有していけたらと思います!

今回は以下の記事を参考にさせていただきました。

TimeCrowdでは開発体制をバリバリ強化してくれるエンジニアを絶賛募集中です!興味のある方はぜひ一緒に仕事しましょう!

 

 

TimeCrowdに戻る