Jenkins Rspec tests complaining about pending migrations? - ruby-on-rails

I'm attempting to setup a Jenkins automated job to run my Rspec tests before doing a deploy. The goal is to run the test suite on remote server without the runtime databases.
I'm using the rake plugin and have the following commands, (keep in mind these are both prepended by rake automatically)
db:test:prepare RAILS_ENV=test
ci:setup:rspec spec RAILS_ENV=test
This works fine in one of my projects, but the other complains about pending migrations. My job output is as follows,
[Dev portal-admin tests] $ /var/lib/jenkins/.rvm/gems/ruby-2.0.0-p353/bin/rake db:test:prepare RAILS_ENV=test
[Dev portal-admin tests] $ /var/lib/jenkins/.rvm/gems/ruby-2.0.0-p353/bin/rake ci:setup:rspec spec RAILS_ENV=test
rm -rf spec/reports
Run `rake db:migrate` to update your database then try again.
You have 16 pending migrations:
20131219204223 DeviseCreateUsers
20131219205648 DeviseInvitableAddToUsers
etc
As far as I understand, db:test:prepare should load the database scheme from the scheme.rb, so I should be good with migrations. I also don't understand why it complains AFTER I get to the Rspec step, instead of the first test:prepare step.
What am I doing wrong here?

I believe your first rake task, db:test:prepare, loaded the database from your existing schema.rb file without objection, as it has no requirement on the migrations being current.
I suspect your subsequent ci:setup:rspec rake task has a dependency on test:prepare which has a dependency on db:abort_if_pending_migrations, which caused the abort you see.
For Rails 4, at least, see activerecord-4.0.0/lib/active_record/railties/databases.rake in your gems directory for details of these rake task definitions.

Related

Automatically running rake tasks when you switch branches in git

Whenever I switch branches I am having to run the commands:
rake db:drop
rake db:migrate
rake db:setup
Is there a way to automatically run these commands in terminal for my application? I am developing a ruby on rails application and have many branches on GitHub. Is there a file I can add to that will automatically run this command?
For example, I will do this "git checkout branch101"
and then I want to run the 3 commands above.
Save this shell script to the file /path/to/repo/.git/hooks/post-checkout, and make it executable.
#! /bin/sh
# Start from the repository root.
cd ./$(git rev-parse --show-cdup)
# drop migrate and set up.
rake db:drop
rake db:migrate
rake db:setup
What you're looking for is something like Guard that runs your test suite whenever code changes in your repo. You should be able to tweak Guard to run your rake tasks instead of tests.
Railscasts has a great screencast explaining the Guard.
After a quick google search, looks like there's a gem available that can run rake tasks for you: guard-rake . Unfortunately, it doesn't seem to be widely used though.

How to understand "rake db:seed"

I am using Michael Hartl's rails tutorials.
Whenever I use the following
$ bundle exec rake db:migrate:reset
Then
$ bundle exec rake db:seed
It waits. It doesn't show anything.
And when I do:
bundle exec rake test
I get
ActiveRecord::PendingMigrationError: Migrations are pending.
To resolve this issue,
bin/rake db:migrate RAILS_ENV=test
When the above is done-"db:migrate RAILS_ENV=test", tests are clear.
However Michael doesn't mention anything happening about this scenario, Can anybody help and explain?
By default, most rake commands are going to run in the context of the RAILS_ENV passed to the command line. If no RAILS_ENV is passed to the command line, it will run in the development context, which is separate from the test context. There are a few exceptions, like rake db:create, which will create your development and test databases, but migrate will work against the specified environment.

Why Does First Deploy with Capistrano Run db:migrate?

I'm using Capistrano to deploy to production for the first time, and I'm getting an error when I run
cap production deploy
The error is:
** Invoke deploy:migrate (first_time)
** Invoke deploy:set_rails_env
** Execute deploy:migrate
DEBUG [048f89c6] Running /usr/bin/env if test ! -d /home/deployer_user/apps/ap_production/releases/20140209005208; then echo "Directory does not exist '/home/deployer_user/apps/ap_production/releases/20140209005208'" 1>&2; false; fi on eslope.net
DEBUG [048f89c6] Command: if test ! -d /home/deployer_user/apps/ap_production/releases/20140209005208; then echo "Directory does not exist '/home/deployer_user/apps/ap_production/releases/20140209005208'" 1>&2; false; fi
DEBUG [048f89c6] Finished in 0.160 seconds with exit status 0 (successful).
INFO [52f75214] Running ~/.rbenv/bin/rbenv exec bundle exec rake db:migrate on eserver.net
DEBUG [52f75214] Command: cd /home/deployer_user/apps/ap_production/releases/20140209005208 && ( RBENV_ROOT=~/.rbenv RBENV_VERSION=2.1.0 RAILS_ENV=production ~/.rbenv/bin/rbenv exec bundle exec rake db:migrate )
DEBUG [52f75214] rake aborted!
DEBUG [52f75214] An error has occurred, this and all later migrations canceled:
DEBUG [52f75214]
DEBUG [52f75214] PG::UndefinedTable: ERROR: relation "client_infos" does not exist
DEBUG [52f75214] : ALTER TABLE "client_infos" RENAME TO "clients
The error actually makes complete sense. The referenced table doesn't exist. What I don't understand is why the migration is running at all? Why isn't the the database just being created from the schema on the first run. Did I inadvertently remove a file that says what migrations have been run? Either by just deleting it, or by ".gitignoring" it?
I think I know how I can fix it (rake db:create or similar) but what I don't understand is, if in Capistrano v3 it knows it's a first time, why it would not use the schema directly rather than run all the migrations? I'm a noob, that seems reasonable, but on the other hand, running the migrations would achieve the same result, so... (But what about folks who don't what to use the migrations blindly in production; won't they be stuck?) Thanks.
Ultimately what I did was as lmars and Nick suggested. I ran something like this directly on the production machine:
RAILS_ENV=production bundle exec rake db:drop
RAILS_ENV=production bundle exec rake db:schema:create
RAILS_ENV=production bundle exec rake db:schema:load
This destroys the data in the datbase of course, but on first deploy, that's not an issue.
I would think there's an easier way, but... I don't know it.
db:migrate takes the migration files and executes them.
so if a table doesn't exist, it will tell you that so. If your deploy is the first deploy to that machine, or that the DB configured is yet have been initialized you should do:
Create DB
rake db:create
this is will create all tables
2 Run the Migrations
`rake db:migrate`
Here obviously, you need to have migrations in place.
It is highly recommended not to load a schema (unless you have no choice) since its hard to work on the schema after (rollbacking, etc) but if you have no choice you can do rake db:schema:load
see this for more info
rake db:schema:load vs. migrations
How to update production database schema safely in rails 3.1.3?
Check your database.yml config, production part, if it is correct. Then ensure Postgresql server is running on the production server and the application (as a user) has access rights. I assume "deployer" is the user, so check this user has all the necessary rights.
From the error it looks like you are trying to rename the client_infos table to clients but the client_infos table does not exist, but do you not have an earlier migration which created the client_infos table?
If you don't have a migration which creates the client_infos table, then where did it come from? Did you create it manually? All changes to the database should have an accompanying migration.
If you do have a migration for the client_infos table, the schema_migrations database table (which is where Rails keeps a record of what migrations have run) may of somehow got out of sync. Given you are deploying for the first time, its probably worth dropping the whole database and starting again.
What I don't understand is why the migration is running at all? Why isn't the the database just being created from the schema on the first run
If written correctly, the migrations should have the same effect as loading the schema, they will just do it incrementally. You can of course manually load the schema if you wish, but Capistrano will not do this as it is quite a dangerous thing to run (you likely never want to recreate your production database)

What does rake db:test:prepare actually do?

I am following the rails tutorial videos and I can't figure out what the db:test:prepare command actually does. Can someone provide an explanation?
The rake db:migrate above runs any pending migrations on the
development environment and updates db/schema.rb. The rake
db:test:load recreates the test database from the current
db/schema.rb. On subsequent attempts, it is a good idea to first run
db:test:prepare, as it first checks for pending migrations and warns
you appropriately.
-- http://guides.rubyonrails.org/testing.html
Basically it handles cloning the database so you don't have to run the migrations against test to update the test database.
Specifically, rake db:test:prepare will do the following:
Check for pending migrations and,
load the test schema
That is, it will look your db/schema.rb file to determine if any migrations that exist in your project that have not been run. Assuming there are no outstanding migrations, it will then empty the database and reload it based on the contents of the db/schema.rb file.
rake db:test:prepare is a good solution for PG issues like this.
“PG::UndefinedTable: ERROR: relation does not exist” with a correct Rails naming and convention" where I couldn't just execute rake db:migrate RAILS_ENV=production
When, for example you can't create test database for a bug discussed here: "PG undefinedtable error relation users does not exist"
All arround this error
"PG::UndefinedTable: ERROR: relation xxxxx does not exist”

Running migrations against the Rails test environment

I know that I can run specific migrations:
rake db:migrate:up VERSION=20080906120000
But can I run a specific migration against my test database? Will the following work?
RAILS_ENV=test rake db:migrate:up VERSION=20080906120000
In theory, running the migrations in default mode (which should affect the development database) and then running rake db:test:prepare should get the job done, but I found something strange with my test database after doing that, and I need to run a specific migration on the test database to aid my troubleshooting.
I'd just try out the above rake command, except I'm in the middle of a long data seeding run on my development database, and I can't risk the migration interfering with that, so I figured I'd see if anyone knows the answer before I can determine it myself. :)
In different order:
rake db:migrate:up VERSION=20080906120000 RAILS_ENV=test

Resources