Configuring a GitLab CI pipeline for Rails, PostgreSQL, rspec, and rubocop

Steven Jackson
3 min readJan 15, 2017

--

While setting up a new side project using rails 5, I wanted a quick-and-easy CI service to help verify my code quality. GitLab has a CI service built into their (free) private git repository service, so it seemed worth giving a shot. The verdict? It’s easy to use and straightforward to configure, but it’s a lot slower than having your own CI machine. That’s good enough for my use case.

For this project, I have two requirements for my CI service:

  • Run my rspec test suite and ensure the tests pass
  • Run static code analysis against the ruby code (with rubocop) and fail for serious violations

Running rspec test suite with PostgreSQL as the database

To use the GitLab CI, you need to add a .gitlab-ci.yml file to your project. This file tells the CI build system:

  • How to set up the VM — which packages to install, installing ruby, how to bundle your Gemfile, create your test databases, etc.
  • Which checks to run: your test suite, static code analysis tools, etc.

The GitLab docs were helpful for configuring the CI for rspec, but switching the database to postgresql required a couple changes. Here’s a complete .gitlab-ci.yml that installs ruby 2.3, the required packages, sets up a blank test database, then runs rspec.

image: "ruby:2.3"services:
- postgres:latest
variables:
POSTGRES_DB: test_db
POSTGRES_USER: runner
POSTGRES_PASSWORD: ""
before_script:
- apt-get update -qq && apt-get install -y -qq postgresql postgresql-contrib libpq-dev cmake
- ruby -v
- which ruby
- gem install bundler --no-ri --no-rdoc
- RAILS_ENV=test bundle install --jobs $(nproc) "${FLAGS[@]}"
- cp config/database.yml.gitlab config/database.yml
- RAILS_ENV=test bundle exec rake db:create db:schema:load
rspec:
script:
- RAILS_ENV=test bundle exec rspec

Take note of this line:

- cp config/database.yml.gitlab config/database.yml

This expects you to have a file in your project config/database.yml.gitlab which stores the CI database connection info. It should match the info you have specified in the variables section of this file. e.g.:

test:
adapter: postgresql
encoding: unicode
pool: 5
timeout: 5000
host: postgres
username: runner
password: ""
database: test_db

That’s it!

Rubocop

Besides rspec, I like to run rubocop against my code to ensure a consistent coding style. Rubocop only provides a list of violations for the entire project, so it’s not useful as a merge request linting tool alone. The gem pronto allows you to output only violations that are on lines of code changed in a given merge request.

We won’t cover setting up rubocop and pronto — but they’re both straightforward. Install the gems (including pronto-rubocop), and create a .rubocop.yml with your configuration.

Once you have the gems installed, you may add an entry to your CI pipeline:

pronto:
script:
- bundle exec pronto run -c=origin/master --exit-code

This tells pronto to run rubocop against the lines of code that are different from origin/master. exit-code tells pronto to fail the build if any serious violations are found.

Summary

That’s it! You now have CI running your test suite and code analysis for your GitLab MRs. Here’s the complete .gitlab-ci.yml:

image: "ruby:2.3"

services:
- postgres:latest

variables:
POSTGRES_DB: test_db
POSTGRES_USER: runner
POSTGRES_PASSWORD: ""

before_script:
- apt-get update -qq && apt-get install -y -qq postgresql postgresql-contrib libpq-dev cmake
- ruby -v
- which ruby
- gem install bundler --no-ri --no-rdoc
- RAILS_ENV=test bundle install --jobs $(nproc) "${FLAGS[@]}"
- cp config/database.yml.gitlab config/database.yml
- RAILS_ENV=test bundle exec rake db:create db:schema:load

rspec:
script:
- RAILS_ENV=test bundle exec rspec

pronto:
script:
- bundle exec pronto run -c=origin/master --exit-code

--

--

Steven Jackson

Web developer (Rails + React), American expat living in Chengdu, China. http://sjackson.net