require 'rexml/document' #gem install rexml set :application, "yourappname" set :base_repository, "http://your.repository/#{application}" set :repository, "#{base_repository}/trunk" # default, but is overwritten by set_tag role :app, "some.prod.server", :primary => true set :deploy_to, "/some/server/path" set :use_sudo, false namespace :deploy do task :set_tag do # get the release path depend :local,:command,"svn" show_recent_tags("#{base_repository}/tags") tag = ::Capistrano::CLI.ui.ask("which tag (blank for trunk): ") if tag == "" new_tag = ::Capistrano::CLI.ui.ask("deploy from trunk, but you have to give it a tag: ") raise Capistrano::Error, "have to tag a new release" if new_tag == "" #raise error if there are invalid characters raise Capistrano::Error, "invalid characters in tag" if new_tag =~ /[|]|\?|:|\/|\*|\"|\'||\||(\s)/ cmd = "svn copy quiet message \"cap tagged release\" #{base_repository}/trunk #{base_repository}/tags/#{new_tag}" puts " * locally executing \"#{cmd}\"" system cmd tag = new_tag end set :repository, "#{base_repository}/tags/#{tag}" puts "repository: #{repository}" end # Overwrite update_code task to add call to set_tag task :update_code, :except => { :no_release => true } do set_tag on_rollback { run "rm -rf #{release_path}; true" } strategy.deploy! finalize_update end def show_recent_tags(repo) hsh = Hash.new cmd = "svn ls xml #{repo}" puts " >> Listing tags: " pipe = IO.popen cmd result = pipe.read pipe.close entries = REXML::Document.new(result).root.elements['list'] entries.elements.each do |e| # set hash key to release id and value to: name by: commit.author hsh[e.elements['commit'].attribute('revision').to_s] = e.elements['name'].text + " \tby: " + e.elements['commit'].elements['author'].text end sorted_arr = hsh.sort {|a,b| a[0].to_ib[0].to_i} if sorted_arr.size > 5 sorted_arr.to_a[-5, 5].each {|t| puts "#{t[1]} \trev: #{t[0]} "} else sorted_arr.to_a.each {|t| puts "#{t[1]} \trev: #{t[0]} "} end end end