First cut of Capistrano 3 version

Working with a local project, no specs or doc updates yet
This commit is contained in:
Gavin Heavyside
2014-06-14 20:54:53 +01:00
parent 1e2687ce83
commit 0cdc527259
8 changed files with 85 additions and 164 deletions

2
.gitignore vendored
View File

@@ -1,2 +1,4 @@
.rbenv-version
.bundle
/bin
Gemfile.lock

View File

@@ -1,9 +1,3 @@
source "https://rubygems.org"
group :test do
gem 'rake'
gem 'rspec'
gem 'capistrano'
gem 'capistrano-ext'
gem 'capistrano-spec', :git => 'git://github.com/mydrive/capistrano-spec.git'
end
gemspec

View File

@@ -1,45 +0,0 @@
GIT
remote: git://github.com/mydrive/capistrano-spec.git
revision: dcc0908dc00872272b1d495bcce70e82240fa8f7
specs:
capistrano-spec (0.1.0)
GEM
remote: https://rubygems.org/
specs:
capistrano (2.11.2)
highline
net-scp (>= 1.0.0)
net-sftp (>= 2.0.0)
net-ssh (>= 2.0.14)
net-ssh-gateway (>= 1.1.0)
capistrano-ext (1.2.1)
capistrano (>= 1.0.0)
diff-lcs (1.1.3)
highline (1.6.11)
net-scp (1.0.4)
net-ssh (>= 1.99.1)
net-sftp (2.0.5)
net-ssh (>= 2.0.9)
net-ssh (2.3.0)
net-ssh-gateway (1.1.0)
net-ssh (>= 1.99.1)
rake (0.9.2.2)
rspec (2.8.0)
rspec-core (~> 2.8.0)
rspec-expectations (~> 2.8.0)
rspec-mocks (~> 2.8.0)
rspec-core (2.8.0)
rspec-expectations (2.8.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.8.0)
PLATFORMS
ruby
DEPENDENCIES
capistrano
capistrano-ext
capistrano-spec!
rake
rspec

View File

@@ -1,16 +1,18 @@
Gem::Specification.new do |s|
s.name = 'capistrano-deploytags'
s.version = '0.9.2'
s.date = '2014-05-01'
s.version = '1.0.0'
s.date = '2014-06-14'
s.summary = "Add dated, environment-specific tags to your git repo at each deployment."
s.description = <<-EOS
Capistrano Deploytags is a simple plugin to Capistrano that works with your deployment framework to track your code releases. All you have to do is require capistrano-deploytags and each deployment will add a new tag for that deployment, pointing to the latest commit. This lets you easily see which code is deployed on each environment, and allows you to figure out which code was running in an environment at any time in the past.
Capistrano Deploytags is a simple plugin to Capistrano 3 that works with your deployment framework to track your code releases. All you have to do is require capistrano-deploytags and each deployment will add a new tag for that deployment, pointing to the latest commit. This lets you easily see which code is deployed on each environment, and allows you to figure out which code was running in an environment at any time in the past.
EOS
s.authors = ["Karl Matthias"]
s.email = 'relistan@gmail.com'
s.files = `git ls-files lib`.split(/\n/) + %w{ README.md LICENSE }
s.homepage = 'http://github.com/mydrive/capistrano-deploytags'
s.add_dependency 'capistrano'
s.add_dependency 'capistrano-ext'
s.add_dependency 'capistrano', '>= 3.2.0'
s.add_development_dependency 'capistrano-spec'
s.add_development_dependency 'rake'
s.add_development_dependency 'rspec'
s.require_path = 'lib'
end

View File

@@ -1,3 +0,0 @@
Dir[File.join(File.dirname(__FILE__), 'capistrano', '*')].each do |file|
require file
end

View File

@@ -0,0 +1,26 @@
# Ensure deploy tasks are loaded before we run
require 'capistrano/deploy'
# Load extra tasks into the deploy namespace
load File.expand_path("../tasks/deploytags.rake", __FILE__)
module CapistranoDeploytags
class Helper
def self.git_tag_for(stage)
"#{stage}-#{formatted_time}"
end
def self.formatted_time
Time.new.utc.strftime(fetch(:deploytag_time_format, "%Y.%m.%d-%H%M%S-utc"))
end
def self.commit_message(current_sha, stage)
if fetch(:deploytag_commit_message, false)
deploytag_commit_message
else
tag_user = (ENV['USER'] || ENV['USERNAME'] || 'deployer').strip
"#{tag_user} deployed #{current_sha} to #{stage}"
end
end
end
end

View File

@@ -0,0 +1,49 @@
namespace :deploy do
desc 'prepare git tree so we can tag on successful deployment'
before :deploy, :prepare_tree do
run_locally do
if ENV['NO_DEPLOYTAGS'] || fetch(:no_deploytags, false)
info "[deploytags] Skipping deploytags"
else
branch = fetch(:branch, false)
stage = fetch(:stage, false)
unless branch && stage
warn 'capistrano-deploytags requires that :branch and :stage be defined'
raise 'define :branch and :stage'
end
strategy.git "fetch #{fetch(:git_remote, 'origin')}"
diff_output = capture :git, "diff #{branch} --shortstat"
unless diff_output.empty?
error "Whoa there, partner. Dirty trees can't deploy. Git yerself clean first"
raise 'Dirty git tree'
end
strategy.git "checkout #{branch}"
info "Pulling from #{branch}"
strategy.git "pull #{fetch(:git_remote, 'origin')} #{branch}"
end
end
end
desc 'add git tags for each successful deployment'
after :cleanup, :tagdeploy do
run_locally do
if ENV['NO_DEPLOYTAGS'] || fetch(:no_deploytags, false)
info "[deploytags] Skipping deploytags"
else
tag_name = CapistranoDeploytags::Helper.git_tag_for(fetch(:stage))
latest_revision = fetch(:current_revision)
commit_message = CapistranoDeploytags::Helper.commit_message(latest_revision, fetch(:stage))
strategy.git "tag -a #{tag_name} -m \"#{commit_message}\" #{latest_revision}"
strategy.git "push #{fetch(:git_remote, 'origin')} #{tag_name}"
info "[cap-deploy-tagger] Tagged #{latest_revision} with #{tag_name}"
end
end
end
end

View File

@@ -1,104 +0,0 @@
module Capistrano
module DeployTags
def pending_git_changes?
# Do we have any changes vs HEAD on deployment branch?
`git fetch #{remote}`.tap do |output|
return !(`git diff #{branch} --shortstat`.strip.empty?) if exec_success?
raise "'git fetch #{remote}' failed:\n #{output}"
end
end
def git_tag_for(stage)
"#{stage}-#{formatted_time}"
end
def formatted_time
Time.new.utc.strftime(fetch(:deploytag_time_format, "%Y.%m.%d-%H%M%S-utc"))
end
def safe_run(*args)
raise "#{args.join(" ")} failed!" unless system(*args)
end
def exec_success?
$?.success?
end
def validate_git_vars
unless exists?(:branch) && exists?(:stage)
logger.log Capistrano::Logger::IMPORTANT, 'Capistrano Deploytags requires that :branch and :stage be defined.'
raise 'define :branch and :stage'
end
end
def git_tag?(tag)
!`git tag -l #{tag}`.strip.empty?
end
def has_remote?
!`git remote`.strip.empty?
end
def remote
exists?(:git_remote) ? git_remote : `git remote`.strip.split(/\n/).first
end
def commit_message(current_sha)
if exists?(:deploytag_commit_message)
deploytag_commit_message
else
tag_user = (ENV['USER'] || ENV['USERNAME'] || 'deployer').strip
"#{tag_user} deployed #{current_sha} to #{stage}"
end
end
def self.load_into(configuration)
configuration.load do
before 'deploy', 'git:prepare_tree'
before 'deploy:migrations', 'git:prepare_tree'
after 'deploy', 'git:tagdeploy'
after 'deploy:migrations', 'git:tagdeploy'
desc 'prepare git tree so we can tag on successful deployment'
namespace :git do
task :prepare_tree, :except => { :no_release => true } do
next if fetch(:no_deploytags, false)
cdt.validate_git_vars
logger.log Capistrano::Logger::IMPORTANT, "Preparing to deploy HEAD from branch '#{branch}' to '#{stage}'"
if cdt.pending_git_changes?
logger.log Capistrano::Logger::IMPORTANT, "Whoa there, partner. Dirty trees can't deploy. Git yerself clean first."
raise 'Dirty git tree'
end
cdt.safe_run 'git', 'checkout', branch
logger.log Capistrano::Logger::IMPORTANT, "Pulling from #{branch}"
cdt.safe_run 'git', 'pull', cdt.remote, branch if cdt.has_remote?
end
desc 'add git tags for each successful deployment'
task :tagdeploy, :except => { :no_release => true } do
next if fetch(:no_deploytags, false)
cdt.validate_git_vars
current_sha = `git rev-parse #{branch} HEAD`.strip[0..8]
logger.log Capistrano::Logger::INFO, "Tagging #{current_sha} for deployment"
cdt.safe_run 'git', 'tag', '-a', cdt.git_tag_for(stage), '-m', cdt.commit_message(current_sha)
cdt.safe_run 'git', 'push', '--tags' if cdt.has_remote?
end
end
end
end
end
end
Capistrano.plugin :cdt, Capistrano::DeployTags
if Capistrano::Configuration.instance
Capistrano::DeployTags.load_into(Capistrano::Configuration.instance(:must_exist))
end