Rails 5.x and PostgreSQL configuration for CircleCI 2.0

Getting Rails 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
  • Running bundle exec rspec 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: |
            bundle exec rspec --format progress \
                            --format RspecJunitFormatter \
                            --out /tmp/test-results/rspec.xml \
                            --format progress

      # collect reports
      - store_test_results:
          path: /tmp/test-results
      - store_artifacts:
          path: /tmp/test-results
          destination: test-results