How to warn of pending migrations when deploying with Capistrano

We use Capistrano for automatic deployment. A common problem is that you don't remember whether your current release includes migrations and you therefore have to run cap deploy:migrate to update your remote database after deployment. A small piece of code warns us if there are pending migrations:

namespace :db do

  desc "Warns if there are pending migrations"
  task :warn_if_pending_migrations => :environment do
    if defined? ActiveRecord
      pending_migrations = ActiveRecord::Migrator.new(:up, 'db/migrate').pending_migrations

      puts ""
      puts " * * * * * * * * * * * * * * * * * * * * * * * * * * * *"
      puts " *                                                     *"
      if pending_migrations.any?
        puts " * You have #{pending_migrations.size} pending migrations:"
        pending_migrations.each do |pending_migration|
          puts ' * %4d %s' % [pending_migration.version, pending_migration.name]
        end
        puts " *"
        puts " * Run cap deploy:migrate!"
      else
        puts " *               No pending migrations.                *"
      end
      puts " *                                                     *"
      puts " * * * * * * * * * * * * * * * * * * * * * * * * * * * *"
      puts ""
      
    end
  end

end

All you need to do is put this snippet into lib/tasks/pending_migrations.rb and add this line end the end of config/deploy.rb in your project:

after "deploy", "db:warn_if_pending_migrations"

You can follow any response to this post through the Atom feed.

Avatar

Mon, 16 Aug 2010 17:49:00 GMT

by thomas

Tags:

  • Kevin Ansfield said 3 days later:

    Great bit of code there, I’m always seeming to forget the migrations with capistrano deployments!

    However, there does seem to be a bit of an error in the task definition. When I run it here it errors out with:

    undefined method `to_sym' for {:warn_if_pending_migrations=>:environment}:Hash (NoMethodError)

  • Thomas said 4 days later:

    Can you give us some details e.g. full stacktrace etc.? Where did you place the code?

  • Nick said 3 months later:

    You can have a look through the differences using cap deploy:pending:diff and see if there are any migrations in there

  • Thomas said 3 months later:

    Thanks Nick, seems to be a good way if nothing but the migration changed. If there is more stuff that diffs it seems to be a bit confusing to me.

    Cheers

  • Ramon said about 1 year later:

    I get this error: the task `db:warn_if_pending_migrations’ does not exist

    If I remember correctly, cap tasks run in the machine that’s deploying. It seems you’re trying to run a rake task after deploy – which you may have to do something like http://stackoverflow.com/questions/312214/how-do-i-run-a-rake-task-from-capistrano

  • thomas said about 1 year later:

    Ramon, you’re right. Cap tasks run on the local machine you’re deploying from. The error you mention means that Capistrano is unable to find the task. Did you put the code snippet into the correct namespace (db)?

    Use

    # cap -T

    to get a list of all Capistrano tasks. It should look like that:

    ...
    cap db                 # Create database yaml in shared path
    cap db:dump            # Do a dump of the DB on the remote machine...
    cap db:show_dump_usage # Show usage of ~/dumps/ on remote host
    cap db:symlink         # Make symlink for database yaml
    cap db:warn_if_pending_migrations # Warn about pending migrations
    
    ...
    

    Cheers, Thomas

Leave a comment