転職活動用のポートフォリオをCircleCIで自動テストできるように設定しました。
CircleCIの設定は.circleci/config.yml
だけだから簡単だと思ったら大間違いでした。
思いのほか時間がかかりました。
自分がつまずいたところを備忘録として残しておきます。
最初に設定した.circleci/config.yml
「CircleCI Rails MySQL」等で検索して、他の人たちが.circleci/config.ymlをどのように書いているのか探して参考にしようと思いました。
最初はこちらのQiita記事 [CircleCIでSystemSpec(RSpec)とRubocopを走らせる] (https://qiita.com/YK0214/items/bbed63ea7ca5367dae2f) を参考にしましたが、rubocopのところでエラーが出ました(エラーは後述)。
version: 2.1
orbs:
ruby: circleci/ruby@1.1.0
jobs:
build:
docker:
- image: circleci/ruby:2.5.1-node-browsers
environment:
BUNDLER_VERSION: 2.1.4
steps:
- checkout
- ruby/install-deps
# 時間短縮のためテストを並列実行する
test:
parallelism: 3
docker:
- image: circleci/ruby:2.5.1-node-browsers
environment:
DB_HOST: 127.0.0.1
RAILS_ENV: test
BUNDLER_VERSION: 2.1.4
- image: circleci/mysql:5.6
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'true'
MYSQL_ROOT_HOST: '%'
steps:
- checkout
- ruby/install-deps
- 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 rspec in parallel
- ruby/rspec-test
- ruby/rubocop-check
workflows:
version: 2
build_and_test:
jobs:
- build
- test:
requires:
- build
Rubocopが起動できない
#!/bin/bash -eo pipefail
mkdir -p /tmp/rubocop-results
bundle exec rubocop . --out /tmp/rubocop-results/check-results.xml --format progress
rubocopがインストールされておらず起動されていないのではないかと思います。
command
を指定して起動できると考えやってみましたが、どうしても解決できませんでした。
その次に参考にした記事
【circleCI】Railsアプリでgithubと連携してrubocopとrspecテストを走らせる
今度はこちらの記事を参考にしました。
rubyのバージョン、アプリのディレクトリ、bundlerのバージョンのところだけ変えてやりました。
.circleci/config.ymlの修正
# Ruby CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
#
version: 2
jobs:
build:
docker:
# specify the version you desire here
- image: circleci/ruby:2.5.1-node-browsers
environment:
- BUNDLER_VERSION: 2.1.4
- RAILS_ENV: 'test'
- image: circleci/mysql:5.6
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD: 'true'
- MYSQL_ROOT_HOST: '%'
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/postgres:9.4
working_directory: ~/projects/pfc-master
steps:
- checkout
# Download and cache dependencies
- restore_cache:
keys:
- v1-dependencies-{{ checksum "Gemfile.lock" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run:
name: install dependencies
command: |
gem install bundler -v 2.1.4
bundle install --jobs=4 --retry=3 --path vendor/bundle
- save_cache:
paths:
- ./vendor/bundle
key: v1-dependencies-{{ checksum "Gemfile.lock" }}
- run: mv config/database.yml.ci config/database.yml
# Database setup
- run: bundle exec rake db:create
- run: bundle exec rake db:schema:load
# rubocopを走らせる記述です。
- run:
name: Rubocop
command: bundle exec rubocop
# run tests!
- run:
name: run tests
command: |
mkdir /tmp/test-results
TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
circleci tests split --split-by=timings)"
bundle exec rspec \
--format progress \
--format RspecJunitFormatter \
--out /tmp/test-results/rspec.xml \
--format progress \
$TEST_FILES
# collect reports
- store_test_results:
path: /tmp/test-results
- store_artifacts:
path: /tmp/test-results
destination: test-results
YAMLの文法エラー
Unable to parse YAML
YAMLを解析できません
while parsing a block mapping
ブロックマッピングを解析中です
ブロックマッピングは、-runのひとまとまりのことを指しているのだろう
in 'string', line 41, column 11:
name: install dependencies
^
expected <block end>, but found '<scalar>'
ブロックの終わりがあるべきなのに、次のブロックの始まり(scalar:-runの「-」のこと)が見つかりません
in 'string', line 44, column 13:
gem install bundler -v 2.1.4
これの原因は、途中にコメントアウトのテキストを挟んで記述していたからでした。
他の記事からそのままペーストして使おうとするとこういうエラーが発生するようなので注意が必要ですね。
コメントアウトの記述を消してくっつけて記述したら解決しました。
Rubocopで修正が必要な箇所を指摘される
Rubocopはコードを検査して「ここは修正した方がいいよ」と教えてくれるツールです。
なんと300個くらい指摘されてしまいました。
300個もあると1つ1つ修正してたら途方もないので、一気に修正してくれるコマンドを使いました。
こちらの記事 Rubocopをインストールして、Rails本家の設定を使う方法 に教えてもらったのですが、下記のコマンドを使うと、指摘された箇所のほとんどを一気に修正してくれます。
bundle exec rubocop --auto-correct
ただ、これで全部は解決されず、私の場合2つは自分で修正する必要がありました。
そのどちらも、「使われてない変数があります(Lint/UselessAssignment)」という指摘だったので、コメントアウトしても問題ないことを確認してから、その部分の記述を消して解決しました。
Rubocopのファイルがloadされない
cannot load such file -- rubocop-packaging
cannot load such file -- rubocop-performance
cannot load such file -- rubocop-rails
Gemfileのgroup :development, :test do
にgem "rubocop"を加えてbundle installすると、.rubocop.yml
に
require:
- rubocop-packaging
- rubocop-performance
- rubocop-rails
となるので、これでこれら3つのファイルは読み込まれてくれるのかと思っていましたが、読み込まれてくれませんでした。
結局このようにGemfileに書き加えてbundle installしたら解決しました。
group :development, :test do
gem "rubocop"
gem "rubocop-packaging"
gem "rubocop-performance"
gem "rubocop-rails"
end
最終的にうまくいった.circleci/config.ymlのコード
# Ruby CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
#
version: 2
jobs:
build:
docker:
- image: circleci/ruby:2.5.1-node-browsers
environment:
- BUNDLER_VERSION: 2.1.4
- RAILS_ENV: 'test'
- image: circleci/mysql:5.6
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD: 'true'
- MYSQL_ROOT_HOST: '%'
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/postgres:9.4
working_directory: ~/projects/pfc-master
steps:
- checkout
- restore_cache:
keys:
- v1-dependencies-{{ checksum "Gemfile.lock" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run:
name: install dependencies
command: |
gem install bundler -v 2.1.4
bundle install --jobs=4 --retry=3 --path vendor/bundle
- save_cache:
paths:
- ./vendor/bundle
key: v1-dependencies-{{ checksum "Gemfile.lock" }}
- run: mv config/database.yml.ci config/database.yml
# Database setup
- run: bundle exec rake db:create
- run: bundle exec rake db:schema:load
- run:
name: run rubocop
command: bundle exec rubocop
# run tests!
- run:
name: run tests
command: |
mkdir /tmp/test-results
TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
circleci tests split --split-by=timings)"
sudo gem install bundler
sudo gem install rspec
sudo gem install rspec-core
bundle exec rspec \
--format progress \
--format RspecJunitFormatter \
--out /tmp/test-results/rspec.xml \
--format progress \
$TEST_FILES
# collect reports
- store_test_results:
path: /tmp/test-results
- store_artifacts:
path: /tmp/test-results
destination: test-results
config/database.yml.ciの設定
run: mv config/database.yml.ci config/database.yml
config/database.yml.ci
のパスをconfig/database.yml
に変更しています。
config/database.yml.ci
をconfig/database.yml
として認識させている=config/database.yml.ci
を反映させている、ということだと思います。
test:
adapter: mysql2
encoding: utf8
pool: 5
username: 'root'
port: 3306
host: '127.0.0.1'
database: ci_test
test:
adapter: mysql2
encoding: utf8
database: pfc-master_test
pool: 5
username: 'root'
password: password
host: '127.0.0.1'