[Rails] CircleCIでRubocop・RSpecを実施しCapistranoを走らせAWS(EC2)に自動で
#はじめに
CircleCIをポートフォリオに組み込みデプロイの自動化はしたものの、テストの自動化は行なっていなかったので、そちらの実装ができたので、記事にしていこうと思います。
#前提
- テストを実装済み(RSpec)
- Rubocop導入済み
- EC2にデプロイ済み
- 開発環境にDockerを用いている
#開発環境
- Ruby 2.6.5
- Rails6
- MySQL 5.6.50
- Docker
- docker-compose
- Capistrano(自動デプロイツール)
#完成コード
version: 2.1
orbs:
ruby: circleci/ruby@1.1.0
jobs:
build:
docker:
- image: circleci/ruby:2.6.5-node-browsers
environment:
BUNDLER_VERSION: 2.1.4
steps:
- checkout
- ruby/install-deps
test:
parallelism: 3
docker:
- image: circleci/ruby:2.6.5-node-browsers
environment:
DB_HOST: 127.0.0.1
RAILS_ENV: test
BUNDLER_VERSION: 2.1.4
- image: circleci/mysql:8.0
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "true"
MYSQL_ROOT_HOST: "%"
steps:
- checkout
- ruby/install-deps
- run: yarn install
- run: mv config/database.yml.ci config/database.yml
- run:
name: Wait for DB
command: dockerize -wait tcp://localhost:3306 -timeout 1m
- run: bundle exec rake db:create
- run: bundle exec rake db:schema:load
- run:
name: RuboCop
command: bundle exec rubocop
- run: bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3
- run: mkdir ~/rspec
- run:
command: bundle exec rspec --format progress --format RspecJunitFormatter -o ~/rspec/rspec.xml
when: always
- store_test_results:
path: ~/rspec
deploy:
docker:
- image: circleci/ruby:2.6.5-node-browsers
environment:
BUNDLER_VERSION: 2.1.4
steps:
- checkout
- ruby/install-deps
- add_ssh_keys:
fingerprints: "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
- deploy:
name: Capistrano deploy
command: bundle exec cap production deploy
workflows:
version: 2
build_accept_deploy:
jobs:
- build
- test:
requires:
- build
- deploy:
requires:
- test
filters:
branches:
only: master
解説をすると、環境を指定するところではtest
環境を指定します。
そして、DBもtest
環境に合わせるためconfigディレクトリ
にdatabase.yml.ciファイル
を作成します。
作成したら以下のように編集しましょう。
test:
adapter: mysql2
encoding: utf8
pool: 5
username: 'root'
port: 3306
host: '127.0.0.1'
database: ci_test
このようにtest
環境用のDBを設定できればCircleCIでの環境構築は終了です。
ここからは実際にテストをするための準備に取り掛かります。コードでいうとtest
(testジョブ
)の部分に当たります。
主に公式を参考にして作業しましたので、公式も参考にしてください。
また、その際にCircleCI用にRSpecのrspec_junit_formatter
というGemをインストールする必要があります。
こちらも公式に書いてあります。
group :test do
# Adds support for Capybara system testing and selenium driver
gem 'capybara', '>= 2.15'
gem 'selenium-webdriver'
# Easy installation and use of web drivers to run system tests with browsers
# rspec_junit_formatterをgroup :test do内に記述
gem 'rspec_junit_formatter'
gem 'webdrivers'
end
忘れずにbundle install
をしてサーバーの再起動を行いましょう。
これで準備が整いました。
test
の部分を見ていきましょう。
testジョブ
test:
parallelism: 3
docker:
- image: circleci/ruby:2.6.5-node-browsers
environment:
DB_HOST: 127.0.0.1
RAILS_ENV: test
BUNDLER_VERSION: 2.1.4
- image: circleci/mysql:8.0
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "true"
MYSQL_ROOT_HOST: "%"
steps:
- checkout
- ruby/install-deps
- run: yarn install
- run: mv config/database.yml.ci config/database.yml
- run:
name: Wait for DB
command: dockerize -wait tcp://localhost:3306 -timeout 1m
- run: bundle exec rake db:create
- run: bundle exec rake db:schema:load
- run:
name: RuboCop
command: bundle exec rubocop
- run: bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3
- run: mkdir ~/rspec
- run:
command: bundle exec rspec --format progress --format RspecJunitFormatter -o ~/rspec/rspec.xml
when: always
- store_test_results:
path: ~/rspec
この記述でテストを実行することができます。
ただ、自分の場合はテスト時に以下のエラーが出ました。
Webpacker::Manifest::MissingEntryError
というエラーが出て、コンパイルができないとRSpecさんに怒られてしまいました。
ということでsteps
でyarn install
コマンドを実行するように追記しました。
steps:
- checkout
- ruby/install-deps
- run: yarn install
- run: mv config/database.yml.ci config/database.yml
- run:
name: Wait for DB
command: dockerize -wait tcp://localhost:3306 -timeout 1m
- run: bundle exec rake db:create
- run: bundle exec rake db:schema:load
- run:
name: RuboCop
command: bundle exec rubocop
- run: bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3
- run: mkdir ~/rspec
- run:
command: bundle exec rspec --format progress --format RspecJunitFormatter -o ~/rspec/rspec.xml
when: always
- store_test_results:
path: ~/rspec
これでテストが上手く通れば、デプロイが自動で行われます。
成功するとGUI上でこのように表示されます。
ちなみに、このテスト実行時、Rubocopでのエラーが起こることがあるようです。
その場合はrubocop.yml
に記述を加えます。
AllCops:
TargetRubyVersion: # 自分のRubyのバージョン
このように記述するとエラーが解決できるようです。
詳しくは下記の記事を参考にしてみてください。
ちなみに、.circleci/config.yml
の記述などは以下の記事も非常にわかりやすいので参考にしてみてください。
ということで、残すはデプロイということなので、そこも見ていきましょう。
deployジョブ
deploy:
docker:
# 自分のRubyのバージョンを指定
- image: circleci/ruby:2.6.5-node-browsers
environment:
# ローカルでインストールされているbundlerのバージョンを指定
BUNDLER_VERSION: 2.1.4
steps:
- checkout
- ruby/install-deps
- add_ssh_keys:
fingerprints: "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
- deploy:
name: Capistrano deploy
command: bundle exec cap production deploy
この辺は僕も記事にしているのでそちらのほうが参考になるかなと思います。ここはほぼ公式どおりなのでそちらを読み進めてもらったほうがいいかなと、下記を参考にしてみてください。
Workflows
workflows:
version: 2
build_accept_deploy:
jobs:
- build
- test:
requires:
- build
- deploy:
requires:
- test
filters:
branches:
only: master
Gitのmasterブランチにpush・mergeされるたびにCircleCIが走って、CI/CDしてくれるようルールを決めているような感じです。
以上で、RailsとAWSのCI/CDの実装は完了です。
参考になれば幸いです。
#参考文献
CircleCI 公式ドキュメント 言語ガイド: Ruby
CircleCI 公式ドキュメント テスト メタデータの収集
Discussion