First cut of Capistrano 3 version
Working with a local project, no specs or doc updates yet
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,2 +1,4 @@
|
||||
.rbenv-version
|
||||
.bundle
|
||||
/bin
|
||||
Gemfile.lock
|
||||
|
||||
8
Gemfile
8
Gemfile
@@ -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
|
||||
|
||||
45
Gemfile.lock
45
Gemfile.lock
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
Dir[File.join(File.dirname(__FILE__), 'capistrano', '*')].each do |file|
|
||||
require file
|
||||
end
|
||||
|
||||
26
lib/capistrano-deploytags/capistrano.rb
Normal file
26
lib/capistrano-deploytags/capistrano.rb
Normal 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
|
||||
49
lib/capistrano-deploytags/tasks/deploytags.rake
Normal file
49
lib/capistrano-deploytags/tasks/deploytags.rake
Normal 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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user