Rake Db:Migration Not Working on Travis-Ci Build

rake db:migration not working on travis-ci build

This blog post helped me tremendously when I was trying to get my Rails 3.2 app working with Travis CI, and write a .travis.yml file that actually worked. Here's mine for your reference, so hope it helps:

.travis.yml

language: ruby
rvm:
- 1.9.2
- 1.9.3
env:
- DB=sqlite
- DB=mysql
- DB=postgresql
script:
- RAILS_ENV=test bundle exec rake db:migrate --trace
- bundle exec rake db:test:prepare
- bundle exec rspec spec/
before_script:
- mysql -e 'create database my_app_test'
- psql -c 'create database my_app_test' -U postgres
bundler_args: --binstubs=./bundler_stubs

Don't know how to build task 'db:migrate' in Travis CI

Finally got it working.

The issue was that the application was a dummy application buried within spec/dummy, so running rake db:migrate wouldn't work from the root directory. In order to fix this, I followed the advice given here. Edit the Rakefile to point to spec/dummy and then run rspec tests:

APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
load 'rails/tasks/engine.rake'
require "rspec/core/rake_task"

task :default => :spec

RSpec::Core::RakeTask.new(:spec) do |spec|
spec.pattern = 'spec/**/*_spec.rb'
# spec.rspec_opts = ['-cfs --backtrace']
end

Rails database setup on Travis-CI

My solution for this problem is fully based on a blog post with a few differences:

  1. Travis CI specific settings in config/database.travis.yml;
  2. cp config/database.travis.yml config/database.yml in before script section of .travis.yml;
  3. I don't have config/database.yml in source tree.

Here is full listing for both files:

# .travis.yml
language: ruby
rvm:
- 1.9.3
env:
- DB=sqlite
- DB=mysql
- DB=postgresql
script:
- RAILS_ENV=test bundle exec rake db:migrate --trace
- bundle exec rake db:test:prepare
- bundle exec rake
before_script:
- cp config/database.travis.yml config/database.yml
- mysql -e 'create database strano_test'
- psql -c 'create database strano_test' -U postgres

# config/database.travis.yml
sqlite: &sqlite
adapter: sqlite3
database: db/<%= Rails.env %>.sqlite3

mysql: &mysql
adapter: mysql2
username: root
password:
database: strano_<%= Rails.env %>

postgresql: &postgresql
adapter: postgresql
username: postgres
password:
database: strano_<%= Rails.env %>
min_messages: ERROR

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

development:
<<: *defaults

test:
<<: *defaults

production:
<<: *defaults

Setting up travis.ci with Rails and Postgres

The problem was that I needed to enable the elasticsearch service on travis. Adding records to the database requires indexing and the refused connection was to a nonexistent elasticsearch server.

Travis CI: The command bundle exec rake exited with 1

It turns out the problem was related to the username for the test database in my database.yml file. I opted to not set the username for the test database after looking at this SO question. The build is finally passing. Hopefully this helps someone in the future.

Travis CI cant resolve association in rails

It looks like a migration issue. The database against which your tests are running by Travis CI, does not have the request_id for the BorrowRequest model. That's why you got that error. But it works locally because you ran the migration locally.

So, all you need is to run the migration so that request_id column is added to the borrow_requests table in your database against which the Travis CI runs the test. That should fix your problem.

Rails build fails in Travis due to undefined method 'encrypted_password=' for User

Well when I created my tables in MySQL I used capital names for all my table names. For some reason when running it locally, the table names were still uppercase in development mode, but were lowercase for test mode. So, in my user model, I simply changed the self.table_name = "USERS" to self.table_name = "users" and that fixed my problem.

Why does Travis-CI bomb with ruby 1.9.3 but not 1.9.2?

Replace gem shoulda with shoulda-matchers if you're using rspec instead of test::unit.

Rake db:test:prepare task deleting data in development database

Your development database is being purged because ActiveRecord::Base.configurations has the test database set to "development.sqlite3". When the rake task is run, the yaml configuration is eval'ed into the ActiveRecord::Base.configurations hash and at that time Rails.env is set to development.

If RAILS_ENV=development, the database value for test will be set to

database: db/development.sqlite3

or for a different adapter:

database: my_app_development

You can reproduce this with a simple sqlite only configuration buy changing the test block inside database.yml to the following:

test:
adapter: sqlite3
database: db/<%= Rails.env %>.sqlite3
pool: 5
timeout: 5000

If you inspect the full ActiveRecord::Base.configurations hash you'll see that test is set to use the development db if no RAILS_ENV is specified. And if you were to specify 'production' or 'staging' it would be set to that. From the console:

# rails c
> ActiveRecord::Base.configurations['test']['database']
=> "db/development.sqlite3"

compared with:

# RAILS_ENV=test rails c
> ActiveRecord::Base.configurations['test']['database']
=> "db/test.sqlite3"

Update

The issue you are seeing with db:reset is also because your yaml file is interpreted once and then the config is set.

db:reset will invoke db:drop and db:setup for the given environment. However, if the environment is development, it also does those tasks for the test environment. So it succeeds in dropping for the development environment and then when it executes for test, the database key of the configuration is identical to the development section, hence it can't drop something that no longer exists. Here is what the ActiveRecord::Base.configurations hash looks like when Rails.env == 'development'

"development" => {
"adapter" => "sqlite3",
"database" => "db/development.sqlite3",
"pool" => 5,
"timeout" => 5000
},
"test" => {
"adapter" => "sqlite3",
"database" => "db/development.sqlite3",
"pool" =>5,
"timeout"=>5000
},
"production" => {
"adapter" => "sqlite3",
"database" => "db/development.sqlite3",
"pool"=>5,
"timeout"=>5000
}

And once it's in that hash, it doesn't go back and re-read the database.yml file. That hash is what is generated given this database.yml

development:
adapter: sqlite3
database: db/<%= Rails.env %>.sqlite3
pool: 5
timeout: 5000

test:
adapter: sqlite3
database: db/<%= Rails.env %>.sqlite3
pool: 5
timeout: 5000

production:
adapter: sqlite3
database: db/<%= Rails.env %>.sqlite3
pool: 5
timeout: 5000

Travis CI: FATAL: database does not exist

I think the file extension should be .yml, not .yaml, as in .travis.yml



Related Topics



Leave a reply



Submit