article Travis CI Multi Database Rails

27 Sep 2013
I started to use Travis CI for continous integration. They have a free plan for open source which makes a good opportunity to try out the service. Travis supports various runtimes and databases and I was going to test my app against ruby 1.9 and ruby 2 and 3 different databases: sqlite, mysql, postgres. To setup these runtimes I created a travis.yml config file like this:
language: ruby
rvm:
  - 2.0.0
  - 1.9.3
env:
  - DB=sqlite
  - DB=mysql
  - DB=postgresql
We need a bit more work to make this work though as we need to specify the database config for each runtime. In my Gemfile I decide which database gem to bundle from the database config but on travis that won't exists so the bundle command will fail. Travis sets a DB environment variable which we can use to determine which gem to bundle:
require 'yaml'

env = ENV["RAILS_ENV"] || 'development'
dbconfig = File.expand_path("../config/database.yml", __FILE__)

raise "You need to configure config/database.yml first" unless File.exists?(dbconfig)
require 'erb'
config = YAML.load(ERB.new(File.read(dbconfig)).result)

environment = config[env]

adapter = environment['adapter'] if environment
raise "Please set an adapter in database.yml for #{env} environment" if adapter.nil?
case adapter
when 'sqlite3'
  gem 'sqlite3'
when 'postgresql'
  gem 'pg'
when 'mysql2'
  gem 'mysql2'
else
  raise "Not supported database adapter: #{adapter}"
end
Note that we process the database.yml with ERB first. It needs because we use the ENV['DB'] variable in the yaml file. I don't have a database.yml in source control just an example for the different database options and I thought the best way would be to keep all the travis related db config in a separate file so I created a database.travis.yml file:
sqlite: &sqlite
  adapter: sqlite3
  database: db/<%= ENV['RAILS_ENV'] %>.sqlite3

mysql: &mysql
  adapter: mysql2
  username: root
  password:
  database: invoicer_<%= ENV['RAILS_ENV'] %>

postgresql: &postgresql
  adapter: postgresql
  username: postgres
  password:
  database: invoicer_<%= ENV['RAILS_ENV'] %>
  min_messages: ERROR

defaults: &defaults
  pool: 5
  timeout: 5000
  host: localhost
  <<: *<%= ENV['DB'] || "sqlite" %>

development:
  <<: *defaults

test:
  <<: *defaults

production:
  <<: *defaults
With this in place we just need to extend the travis config to set the rails environment and run a before script:
language: ruby
rvm:
  - 2.0.0
  - 1.9.3
env:
  - DB=sqlite
  - DB=mysql
  - DB=postgresql
before_install: cp config/database.travis.yml config/database.yml
script:
  - export RAILS_ENV=test
  - bundle exec rake db:create db:migrate
  - bundle exec rake db:test:prepare
Now we just need to push a commit and wait for the build result.

Did you enjoy reading this? Sign up to the Rails Tricks newsletter for more content like this!

Or follow me on Twitter

Job listings

Post a Job for FREE!

Related posts