Skip to content

Instantly share code, notes, and snippets.

@csouls
Last active August 29, 2015 14:00
Show Gist options
  • Save csouls/11398285 to your computer and use it in GitHub Desktop.
Save csouls/11398285 to your computer and use it in GitHub Desktop.
Extension of capistrano command on simple deploy
require 'erubis'
require 'aws-sdk'
module CapistranoExtentions
# Run a git command in the `current_path` directory
def git(command)
run "cd #{current_path} && umask 002 && git #{command}"
end
# Capture the result of a git command run within the `current_path` directory
def capture_git(command)
capture "cd #{current_path} && umask 002 && git #{command}"
end
def exit_code(command)
capture("#{command} > /dev/null 2>&1; echo $?").strip
end
def run_current(command)
run "cd #{current_path} && RAILS_ENV=#{rails_env} #{command}"
end
def run_bundle(command)
run_current "bundle exec #{command}"
end
def release_tag_from_repository
rails_env + '/' + Time.now.strftime("%Y%m%d%H%M%S")
end
# Find the latest tag from the repository. As `git tag` returns tags in order, and our release
# tags are timestamps, the latest tag will always be the last in the list.
def latest_tag(use_cache=true)
return @latest_tag if use_cache && @latest_tag
tags = capture_git("tag").strip.split
@latest_tag = tags.grep(/\A#{rails_env}\/[0-9]{14}\Z/).last
end
# Does the given file exist within the deployment directory?
def deployed_file_exists?(path, root_path = current_path)
exit_code("cd #{root_path} && [ -f #{path} ]") == "0"
end
# Has the given path been created or changed since the previous deployment? During the first
# successful deployment this will always return true if the file exists.
def deployed_file_changed?(path)
return deployed_file_exists?(path) unless latest_tag
exit_code("cd #{current_path} && git diff --exit-code #{latest_tag} origin/#{branch} #{path}") == "1"
end
def changed_files
@changed_files ||=
if latest_tag
capture_git("diff --name-only #{latest_tag} origin/#{branch} | cat").split
else
capture_git("ls-files | cat").split
end
end
def trigger_update?(path)
changed_files.detect {|p| p[0, path.length] == path}
end
def tagged_servers(tag_key, tag_value, default=[])
@ec2 ||= AWS::EC2.new(ec2_endpoint: 'ec2.ap-northeast-1.amazonaws.com')
ret = @ec2.instances.map do |instance|
next if instance.tags[tag_key] != tag_value
next if instance.status != :running
instance.dns_name || instance.ip_address || instance.private_dns_name
end.compact
return default if ret.empty?
ret
end
def tag(tag_value, *args)
AWS.memoize {
tagged_servers(tag_key, tag_value).each do |host|
server(host, *args)
end
}
end
def first_server(tag_value)
AWS.memoize {
tagged_servers(tag_key, tag_value).first
}
end
def god_execute(act, name)
"cd #{current_path} && #{god_cmd} #{act} #{name}"
end
def god_status_cmd(name='')
"cd #{current_path} && #{god_cmd} status #{name} >/dev/null 2>/dev/null"
end
def god_config_reload(config_name)
"cd #{current_path} && #{god_cmd} load config/god/#{config_name}.god"
end
def start_process(proc, conf, act)
script = <<-END
set -x;
if #{god_status_cmd(proc)}; then
#{act == :restart ? god_execute(:restart, proc) : "echo running"};
else
#{god_config_reload(conf)};
#{god_execute(:start, proc)};
fi
END
run script
end
def conf_template(file, binding)
dir = File.join(File.dirname(__FILE__), '..', 'templates')
Erubis::Eruby.new(File.read("#{dir}/#{file}.erb")).result(binding)
end
Capistrano::Configuration.send :include, self
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment