Upgrade "Gotchas"
Capistrano 2.0 is just enough similar to, and yet different from, Capistrano 1.0 that you might find yourself getting bitten by things that you would expect to work. Here are a few things to watch for as you are upgrading your recipe files.
- Capistrano extensions
All bets are off if you are using any Capistrano extensions (this includes the capistrano-ext gem). Until those extensions are updated to work with Capistrano 2, they may very well fail to load at all in your recipes.
The reason for this breakage is that Capistrano 2.0 has significantly refactored its internals. Whereas Capistrano 1.x had both a Configuration class and an Actor class, Capistrano 2.0 has merged the two into a single Configuration class. That change alone will probably break a good many extensions.
- Task Namespaces
The deployment recipes are namespaced, now. This means that if you are explicitly overriding any of the deployment tasks, you'll need to change your recipe to include the namespace. For example, suppose you had overridden the "restart" task; you need to change your definition to look like this:
deploy.task :restart, :roles => :app do # ... end
The namespace comes first, followed by a '.', and then the task definition. You're effectively calling the @task@ method of the @deploy@ namespace. If you prefer longhand, or if you need to redefine multiple tasks, you can also do it like this:
namespace :deploy do task :restart, :roles => :app do # ... end endTechnically, the before and after hooks should be defined the same way, but to keep people from having to do too much work, Capistrano will search the parent namespaces for before and after hooks, too. So defining "after_update_code" in the top-level namespace will still work as an after hook for deploy:update_code.
- Renamed Tasks
In addition to namespacing being added, several of the deployment tasks have been renamed. These include are:
Old name New name diff_from_last_deploy deploy:pending:diff cold_deploy deploy:cold deploy_with_migrations deploy:migrations disable_web deploy:web:disable enable_web deploy:web:enable There is a "compatibility" mode available, which aliases many of the new task-names by their original names. You can access this compatibility mode by adding the following line to the top of your Capfile:
load 'compat'
Alternatively, if you just want compatibility mode for one invocation, you can just invoke cap with the -f option, and specifying the "compat" recipes:
cap -f compat ...
At any time, you can pass the -T option to cap to see a list of all available tasks. This new format is much more concise and scannable than the older "cap show_tasks" format. Additionally, longer help may be available for many tasks; you can read it by passing the name of the task to the -e ("explain") switch:
cap -e deploy:cold
- SCM Module Changes
Your SCM-of-choice may not be supported right now, even if it was originally supported in Capistrano 1.x. Even if your SCM is supported, it may behave slightly differently, accepting different variables than it used to. In many cases, where you might have had a "svn_username" variable, it is now a more general "scm_username".
- No more "cap --apply-to"
With Capistrano 1.x, the easy way to make a new project play nicely with Capistrano was to use "cap -A", which set up the project with a set of tasks and such. It was very, very Rails-specific, and would not work unless you were applying Capistrano to a Rails project.
With Capistrano 2.0, there is now a separate "capify" script. It tries to be much more general, and will work with any kind of project. Just specify the path to the project you want capify, and it will take care of the rest.
- The "delete" helper is gone
Your recipes may be using the "delete" helper to delete files or directories on the remote server. That helper has been removed; you should just use the "run" helper directly, calling the "rm" command.
- No more "render" helper
The "render" helper was originally intended to be used for dynamically generating scripts and pages for use on the remote servers. After evaluating it a bit, though, it was really just a thin wrapper around ERB, and so in the interests of simplifying things, it got pulled.
If you need to do dynamic generation of scripts or pages from a template file, you should just call ERB directly:
require 'erb' template = File.read(path_to_template_file) result = ERB.new(template).result(binding)
