— 4-minute read

Capistrano 2.4.0 is now available.

gem install capistrano

Report bugs to Capistrano’s Lighthouse project. And if you have some ideas for patches, please patch against the code at Capistrano’s GitHub repository.

Here’s the skinny on 2.4.0:

death to “git fetch --tags“

You git users out there will be pleased to learn that this release will no longer do “git fetch --tags”, meaning your git-based deploys will finally work again. Sorry that took so long to fix. It was really ridiculously simple. :(

cap -d

Mark Imbriaco added a debug switch for enabling conditional execution of commands. This is fantastic for debugging and testing tasks, since you can basically step through your tasks and approve or deny each remote command as it is executed. Just give cap the “-d” switch to enable this.

New and improved sudo helper

No, really. This time I mean it. I pulled the version of sudo introduced in 2.3.0 (where each sudo command was wrapped in an explicit sh invocation), and put it back almost exactly as it was. However, if you call sudo without a command to execute, it will instead return the sudo command to use. On top of that, if the run() helper detects that you’re using sudo, it will listen for password prompts. So you can now do arbitrarily complex sudo commands like this:

1 run " if [ -d /some/directory ]; then #{ sudo } chmod -R g+w /some/directory; fi "

In other words, just dump the sudo() call into your command as an interpolated value, and the real sudo command gets substituted. You can pass options to it as well:

1 run " #{ sudo :as => " bob " } something "

And, naturally, the original sudo() syntax we all know and love remains as before:

sudo "something", :as => "bob"

The deployment recipes themselves have been updated to use this new syntax, as needed.

:runner vs. :admin_runner

Some cappers have noted that having deploy:setup and deploy:cleanup run as the :runner user messed up their carefully crafted permissions. I agreed that this was a problem. With this release, deploy:start, deploy:stop, and deploy:restart all continue to use the :runner user when sudoing, but deploy:setup and deploy:cleanup will use the :admin_runner user. The :admin_runner variable is unset, by default, meaning those tasks will sudo as root, but if you want them to run as :runner, just do “set :admin_runner, runner”.

deploy:upload with globs

You can now specify glob patterns with deploy:upload:

1 $ cap deploy:upload FILES="config/apache/*.conf"

As before, you can also specify entire folders to upload, but now the upload is being done via the upload() helper (introduced in 2.3.0) so the behavior is more standardized.

before/after hooks use well-defined server scope

Prior to this release, if you defined a before hook using a block, the block would be executed within the same server scope as the original task that invoked task that this hook was attached to. (whew!)

In other words:

1 2 3 4 5 6 7 8 9 10 11 12 task :first , :roles => :app do # ... second end task :second , :roles => :db do # ... end before :second do # ... end

Prior to this release, when “first” calls “second”, the before hook at the bottom would get called, but it would get called with the :roles => :app server constraint active, instead of :roles => :db. This preview release makes those hooks use the server scope of the task they are attached to.

host reported correctly from SCM output

Prior to this release, when any output was processed by the :checkout, :export, or :remote_cache strategies, you’d not be able to tell what host the output was from (it’d just be prefixed [err] or [out]). With this release, that output is correctly tagged with the host that generated it, making it easier to troubleshoot issues with SCM command execution.

Disable asset timestamp normalization

Some SCM’s give you the option of forcing the modification times of files that are being checked out to be the time that they were last modified in the repository. If your SCM gives you that capability, and if you enable it (however that works in your SCM), then you don’t need the massive touch command that Capistrano’s default deployment tasks run on each deploy, which is cap’s way of forcing all assets on all of your servers to have the same timestamp.

To disable Capistrano’s default timestamp normalization step, just set the :normalize_asset_timestamps variable to false:

1 set :normalize_asset_timestamps , false

You could also do this if you are deploying to a single server only. Note, though, that if you do this when deploying to multiple servers, and you haven’t configured your SCM to set the timestamps on the files on checkout, then Rails may use inconsistent timestamps on the assets, causing caching of your assets to fail and resulting in longer load times for your users.

Other lesser fixes, straight from the CHANGELOG