Rails 5.x and PostgreSQL configuration for CircleCI 2.0
Revised November 17, 2017
There is a better way to solve this without removing the CircleCI TEST_FILES
section and preserve parallel container. I've updated the configuration below. Thanks to Jason Milkins for posting the fix to the rspec github.
Getting Rails (or Ruby) running on CircleCI's new 2.0 platform provides a sample configuration for Rails apps that does not work out-of-the-box. I figured I would save some folks the pain and provide an updated sample configuration.
No PG configuration and RSpec error
This configuration focuses on fixing two things:
- Rails does not have access to the PostgreSQL container (skip if your only concerned with a Ruby app)
- Running
bundle exec rspec
on CircleCI results in the following error:
#!/bin/bash -eo pipefail
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}"
bundler: failed to load command: rspec (/home/circleci/repo/vendor/bundle/ruby/2.4.0/bin/rspec)
NoMethodError: undefined method `captures' for nil:NilClass
/home/circleci/repo/vendor/bundle/ruby/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/example.rb:124:in `parse_id'
/home/circleci/repo/vendor/bundle/ruby/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/configuration.rb:2026:in `extract_location'
/home/circleci/repo/vendor/bundle/ruby/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/configuration.rb:1965:in `block in get_files_to_run'
/home/circleci/repo/vendor/bundle/ruby/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/flat_map.rb:7:in `each'
/home/circleci/repo/vendor/bundle/ruby/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/flat_map.rb:7:in `flat_map'
/home/circleci/repo/vendor/bundle/ruby/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/flat_map.rb:7:in `flat_map'
/home/circleci/repo/vendor/bundle/ruby/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/configuration.rb:1963:in `get_files_to_run'
/home/circleci/repo/vendor/bundle/ruby/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/configuration.rb:976:in `files_to_run'
/home/circleci/repo/vendor/bundle/ruby/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/configuration.rb:1492:in `load_spec_files'
/home/circleci/repo/vendor/bundle/ruby/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:100:in `setup'
/home/circleci/repo/vendor/bundle/ruby/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:86:in `run'
/home/circleci/repo/vendor/bundle/ruby/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:71:in `run'
/home/circleci/repo/vendor/bundle/ruby/2.4.0/gems/rspec-core-3.6.0/lib/rspec/core/runner.rb:45:in `invoke'
/home/circleci/repo/vendor/bundle/ruby/2.4.0/gems/rspec-core-3.6.0/exe/rspec:4:in `<top (required)>'
/home/circleci/repo/vendor/bundle/ruby/2.4.0/bin/rspec:23:in `load'
/home/circleci/repo/vendor/bundle/ruby/2.4.0/bin/rspec:23:in `<top (required)>'
Exited with code 1
Revised .circleci/config.yml
Below is a tweaked version that supports PostgreSQL and resolves the error above running bundle exec rspec
. Unfortunately I am stuck to the free version of CircleCI and do not have multiple containers. This configuration does not support split tests across multiple containers.
# 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.4.1-node-browsers
environment:
RAILS_ENV: test
PGHOST: 127.0.0.1
DATABASE_URL: postgres://myapp-user@127.0.0.1/myapp-test
# 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.6-alpine
POSTGRES_DB: myapp-test
POSTGRES_USER: myapp-user
working_directory: ~/myapp
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: |
bundle install --without development --jobs=4 --retry=3 --path vendor/bundle
- save_cache:
paths:
- ./venv
key: v1-dependencies-{{ checksum "Gemfile.lock" }}
# Database setup
- run: bundle exec rake db:create
- run: bundle exec rake db:schema:load
# 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 documentation \
--format RspecJunitFormatter \
--out /tmp/test-results/rspec.xml \
-- $(sed -e 's/\n/\\n/' -e 's/ /\ /' <<< "${TEST_FILES}")
# collect reports
- store_test_results:
path: /tmp/test-results
- store_artifacts:
path: /tmp/test-results
destination: test-results