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:
- Travis CI specific settings in
config/database.travis.yml
; cp config/database.travis.yml config/database.yml
in before script section of.travis.yml
;- 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
Built in Way to List Directories in a Directory in Ruby
How to Detect the End of a Method Chain in Ruby
How to Transfer Files Using Ssh and Scp Using Ruby Calls
Consuming Non-Rest APIs in Rails with Activeresource
Add a Callback Function to a Ruby Array to Do Something When an Element Is Added
How to Do Named Capture in Ruby
Is It a Bad Idea to Reload Routes Dynamically in Rails
Run a Ruby Library from the Command-Line
Ruby on Rails: Conditionally Display a Partial
Appending Headers to Rspec Controller Tests
Testing Simple Sti with Factorygirl
How to Connect to Postgresql Database After Upgrading to Yosemite 10.10
Dynamically Defined Setter Methods Using Define_Method
Solving the Travelling Salesman Problem in Ruby (50+ Locations)
Rspec Testing Has_Many :Through and After_Save
Running Phantomjs from a Ruby on Rails Application