noodling towards a functional brain

Wednesday, December 05, 2007

In looking around the web a bit, I've had a hard time finding any capistrano plugins that handle deployment of SVN tags and branches well. So, I wrote a little one of my own.



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!

About Me

My photo
aspiring to elegant simplicity