Chapter 07

CirclCI の導入

hibriiiiidge
hibriiiiidge
2020.10.22に更新
このチャプターの目次

フロントエンド、バックエンド共にテストを実行することができるようになったので、次は CircleCI を導入してGithub のリモートブランチに push する度に CI が動くようにしていきます。

CircleCI のユーザー登録や Github 連携については 公式入門ガイド をご覧いただければと思います。
以下は、 ユーザー登録や CircleCI と Github の連携が完了した前提で進めていきます。

CircleCI のセットアップ

今まで基本的には main ブランチで実装を行ってきましたが、CI のセットアップなので、ブランチを切って、より実践的な形で進めようと思います。

$ cd zenn-app/
$ git checkout -b setup-circle-ci

CircleCI の Projects 一覧画面を開きます。
URL 的には以下の URL です。

https://app.circleci.com/projects/project-dashboard/github/#{YOUR_GITHUB_ACCOUNT}/

Projects (リポジトリ)一覧が表示されるので、連携したいリポジトリの [Set Up Project] ボタンをクリックします。

リポジトリの詳細画面に遷移します。
画面中央に、ダウンロードボタンがあるのでクリックして config.yml をダウンロードします。

ダウンロードボタンの右側にある [Add Config] ボタンをクリックすると、 config.yml を追加する PR が作成されるので、それ経由でセットアップしても問題ありません。

次に、zenn-app 配下に .circleci ディレクトリを作成し、ダウンロードした .config.yml を配置します。

# zenn-app/.circleci/config.yml

version: 2.1
orbs:
  ruby: circleci/ruby@0.1.2 

jobs:
  build:
    docker:
      - image: circleci/ruby:2.6.3-stretch-node
    executor: ruby/default
    steps:
      - checkout
      - run:
          name: Which bundler?
          command: bundle -v
      - ruby/bundle-install

config.yml を以下のように修正します。

version: 2.1

jobs:
  test_backend:
    docker:
      - image: circleci/ruby:2.6.6-stretch-node
        environment:
          RAILS_ENV: test
          DB_HOST: 127.0.0.1
      - image: circleci/mysql:5.7.30

    working_directory: ~/repo

    steps:
      - checkout

      # restore gem from cache
      - restore_cache:
          keys:
            - gem-cache-v1-{{ checksum "~/repo/backend/Gemfile.lock" }}
            - gem-cache-v1-
          working_directory: ~/repo/backend

      # gem install
      - run:
          command: |
            gem install bundler
            bundle config set path 'vendor/bundle'
            bundle install --jobs=4 --retry=3
          working_directory: ~/repo/backend

      - save_cache:
          key: gem-cache-v1-{{ checksum "~/repo/backend/Gemfile.lock" }}
          paths:
            - ~/repo/backend/vendor/bundle
          working_directory: ~/repo/backend

      # Database setup
      - run:
          command: bundle exec rails db:create
          working_directory: ~/repo/backend
      - run:
          command: bundle exec rails db:migrate
          working_directory: ~/repo/backend

      - run:
          name: create directory to store test results
          command: mkdir /tmp/test-results
          working_directory: ~/repo/backend

      # run tests
      - run:
          name: RSpec
          command: |
            bundle exec rspec $(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings) \
              || (printf "====== RETRYING...\n\n\n"; bundle exec rspec --only-failures)
          working_directory: ~/repo/backend

      # collect reports
      - store_test_results:
          path: /tmp/test-results
      - store_artifacts:
          path: /tmp/test-results
          destination: test-results
      - store_artifacts:
          path: /home/circleci/repo/tmp/screenshots

  test_frontend:
    docker:
      - image: circleci/node:14.3
        environment:
          NODE_ENV: test

    working_directory: ~/repo

    steps:
      - checkout
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "~/repo/frontend/package.json" }}
          working_directory: ~/repo/frontend
      - run:
          name: install-packages
          command: npm install
          working_directory: ~/repo/frontend
      - save_cache:
          paths:
            - node_modules
          key: v1-dependencies-{{ checksum "~/repo/frontend/package.json" }}
          working_directory: ~/repo/frontend
      - run:
          name: test
          command: npm run test
          working_directory: ~/repo/frontend

workflows:
  version: 2
  test:
    jobs:
      - test_backend:
          filters:
            branches:
              ignore: main
      - test_frontend:
          filters:
            branches:
              ignore: main

コミットを積んで、リモートブランチに push した時に CircleCI が動きいたら OK です。