Capistrano.configuration(:must_exist).load do
set :svn_trunk_dir, 'trunk'
set :svn_tag_dir, 'tags'
set :svn_branch_dir, 'branches'
before "deploy" do
if rails_env == 'production'
abort "ERROR: Production deploys must be from a tag or branch." unless repository =~ /#{svn_tag_dir}|#{svn_branch_dir}/
end
end
desc <<-DESC
Deploy from a tag instead of from the trunk. This will prompt if no TAG value
is specified on the command line. No sanity checks for whether the tag actually
exists are performed.
DESC
task :deploy_tag do
set :repository, get_svn_url(svn_tag_dir, 'TAG')
run_deploy
end
desc "Create the specified tag and deploy from that tag."
task :deploy_new_tag do
trunk = "#{repository[/(.*?)(?:\/trunk)?$/, 1]}/#{svn_trunk_dir}"
set :repository, get_svn_url(svn_tag_dir, 'TAG')
puts "Creating new tagged release of trunk as #{ENV['TAG']}."
system "svn cp #{trunk} #{repository}"
run_deploy
end
desc "Deploy from a branch instead of a tag; same caviats as for :deploy_tag."
task :deploy_branch do
set :repository, get_svn_url(svn_branch_dir, 'BRANCH')
run_deploy
end
desc "Create a branch from the specified tag and deploy from that branch."
task :deploy_new_branch do
tag_url = get_svn_url(svn_tag_dir, 'TAG')
branch_url = get_svn_url(svn_branch_dir, 'BRANCH')
puts "Creating new branch #{ENV['BRANCH']} from tag #{ENV['TAG']}."
system "svn cp #{tag_url} #{branch_url}"
set :repository, branch_url
run_deploy
end
# Executes the ordinary deploy task
def run_deploy
puts "Deploying using repository url #{repository}"
execute_task(find_task("deploy"))
end
# Prompts the user for a tag and updates the repository url based upon that
# tag and the svn conventions.
def get_svn_url(tag_dir, env_var = 'TAG')
while ENV[env_var].nil? || ENV[env_var].strip.empty?
ENV[env_var] = Capistrano::CLI.ui.ask("Please specify #{env_var.downcase} name: ")
ENV[env_var].strip!
end
repo_root = repository[/(.*?)(?:\/trunk)?$/, 1]
"#{repo_root}/#{tag_dir}/#{ENV[env_var]}"
end
end
I just stuck all of this in lib/cap/tag_deployer.rb, then added
require 'lib/cap/tag_deployer.rb'
to my deploy.rb file, and away I go!