From 0cdc5272596fd0813f4a7e7f9a661b6cb47e1031 Mon Sep 17 00:00:00 2001 From: Gavin Heavyside Date: Sat, 14 Jun 2014 20:54:53 +0100 Subject: [PATCH 1/5] First cut of Capistrano 3 version Working with a local project, no specs or doc updates yet --- .gitignore | 2 + Gemfile | 8 +- Gemfile.lock | 45 -------- capistrano-deploytags.gemspec | 12 +- lib/capistrano-deploytags.rb | 3 - lib/capistrano-deploytags/capistrano.rb | 26 +++++ .../tasks/deploytags.rake | 49 +++++++++ lib/capistrano/deploy_tags.rb | 104 ------------------ 8 files changed, 85 insertions(+), 164 deletions(-) delete mode 100644 Gemfile.lock create mode 100644 lib/capistrano-deploytags/capistrano.rb create mode 100644 lib/capistrano-deploytags/tasks/deploytags.rake delete mode 100644 lib/capistrano/deploy_tags.rb diff --git a/.gitignore b/.gitignore index 730ea3f..d29994d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .rbenv-version .bundle +/bin +Gemfile.lock diff --git a/Gemfile b/Gemfile index a9d8e26..b4e2a20 100644 --- a/Gemfile +++ b/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 diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 6459018..0000000 --- a/Gemfile.lock +++ /dev/null @@ -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 diff --git a/capistrano-deploytags.gemspec b/capistrano-deploytags.gemspec index a6a2c59..adf1771 100644 --- a/capistrano-deploytags.gemspec +++ b/capistrano-deploytags.gemspec @@ -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 diff --git a/lib/capistrano-deploytags.rb b/lib/capistrano-deploytags.rb index f74b9e1..e69de29 100644 --- a/lib/capistrano-deploytags.rb +++ b/lib/capistrano-deploytags.rb @@ -1,3 +0,0 @@ -Dir[File.join(File.dirname(__FILE__), 'capistrano', '*')].each do |file| - require file -end diff --git a/lib/capistrano-deploytags/capistrano.rb b/lib/capistrano-deploytags/capistrano.rb new file mode 100644 index 0000000..f9530eb --- /dev/null +++ b/lib/capistrano-deploytags/capistrano.rb @@ -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 diff --git a/lib/capistrano-deploytags/tasks/deploytags.rake b/lib/capistrano-deploytags/tasks/deploytags.rake new file mode 100644 index 0000000..8c41373 --- /dev/null +++ b/lib/capistrano-deploytags/tasks/deploytags.rake @@ -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 diff --git a/lib/capistrano/deploy_tags.rb b/lib/capistrano/deploy_tags.rb deleted file mode 100644 index 7ba2c4a..0000000 --- a/lib/capistrano/deploy_tags.rb +++ /dev/null @@ -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 From 0ad8061fbbbc064b0a1c09bdcde5ff697a86609a Mon Sep 17 00:00:00 2001 From: Gavin Heavyside Date: Sun, 15 Jun 2014 14:35:07 +0100 Subject: [PATCH 2/5] Tweak gemspec, elide specs which don't work with Cap 3 :( --- capistrano-deploytags.gemspec | 12 +-- spec/capistrano_deploy_tags_spec.rb | 150 +--------------------------- 2 files changed, 9 insertions(+), 153 deletions(-) diff --git a/capistrano-deploytags.gemspec b/capistrano-deploytags.gemspec index adf1771..7b17dcd 100644 --- a/capistrano-deploytags.gemspec +++ b/capistrano-deploytags.gemspec @@ -2,17 +2,17 @@ Gem::Specification.new do |s| s.name = 'capistrano-deploytags' 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.summary = 'Add dated, environment-specific tags to your git repo at each deployment.' s.description = <<-EOS - 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. + 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/capistrano 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.authors = ['Karl Matthias', 'Gavin Heavyside'] + s.email = ['relistan@gmail.com', 'gavin.heavyside@mydrivesolutions.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', '>= 3.2.0' - s.add_development_dependency 'capistrano-spec' +# s.add_development_dependency 'capistrano-spec' s.add_development_dependency 'rake' - s.add_development_dependency 'rspec' + s.add_development_dependency 'rspec', '~> 3.0.0' s.require_path = 'lib' end diff --git a/spec/capistrano_deploy_tags_spec.rb b/spec/capistrano_deploy_tags_spec.rb index 7006ab4..9b5320a 100644 --- a/spec/capistrano_deploy_tags_spec.rb +++ b/spec/capistrano_deploy_tags_spec.rb @@ -1,149 +1,5 @@ -require 'capistrano' -require 'capistrano-spec' -require 'fileutils' -mypath = File.expand_path(File.dirname(__FILE__)) -require File.expand_path(File.join(mypath, '..', 'lib', 'capistrano', 'deploy_tags')) +require 'rspec' -describe Capistrano::DeployTags do - let(:configuration) { Capistrano::Configuration.new } - let(:tmpdir) { "/tmp/#{$$}" } - let(:mypath) { mypath } - - before :each do - Capistrano::DeployTags.load_into(configuration) - end - - def with_clean_repo(&block) - FileUtils.rm_rf tmpdir - FileUtils.mkdir tmpdir - FileUtils.chdir tmpdir - raise unless system("`which tar` xzf #{File.join(mypath, 'fixtures', 'git-fixture.tar.gz')}") - FileUtils.chdir "#{tmpdir}/git-fixture" - yield - FileUtils.rm_rf tmpdir - end - - context "prepare_tree" do - before do - configuration.set(:branch, 'master') - configuration.set(:stage, 'test') - end - - it 'raises an error when not in a git tree' do - FileUtils.chdir '/tmp' - configuration.cdt.stub(exec_success?: true) - expect { configuration.find_and_execute_task('git:prepare_tree') }.to raise_error('git checkout master failed!') - end - - it 'raises when unable to fetch' do - with_clean_repo do - configuration.cdt.should_receive(:exec_success?).and_return(false) - expect { configuration.find_and_execute_task('git:prepare_tree') }.to raise_error(/'git fetch ' failed/) - end - end - - context "with a clean git tree" do - before :each do - configuration.set(:branch, 'master') - configuration.set(:stage, 'test') - end - - it 'raises an error if :stage or :branch are undefined' do - with_clean_repo do - configuration.unset(:branch) - configuration.unset(:stage) - expect { configuration.find_and_execute_task('git:prepare_tree') }.to raise_error('define :branch and :stage') - end - end - - it 'does not raise an error when run from a clean tree' do - with_clean_repo do - configuration.cdt.stub(exec_success?: true) - expect { configuration.find_and_execute_task('git:prepare_tree') }.to_not raise_error - end - end - - it 'does not run when :no_deploytags is defined by (i.e. by the stage)' do - with_clean_repo do - configuration.set(:no_deploytags, true) - configuration.cdt.should_not_receive(:validate_git_vars) - configuration.find_and_execute_task('git:prepare_tree') - end - end - - it 'uses a different remote when one is defined' do - with_clean_repo do - system('git remote add nowhere git@example.com:nowhere') - configuration.set(:git_remote, 'nowhere') - configuration.cdt.stub(pending_git_changes?: false) - configuration.cdt.should_receive(:safe_run).with('git', 'checkout', 'master') - configuration.cdt.should_receive(:safe_run).with('git', 'pull', 'nowhere', 'master') - configuration.find_and_execute_task('git:prepare_tree') - end - end - - it 'uses the first remote when one is not specified' do - with_clean_repo do - configuration.cdt.stub(pending_git_changes?: false) - system('git remote add somewhere git@example.com:somewhere') - configuration.cdt.should_receive(:safe_run).with('git', 'checkout', 'master') - configuration.cdt.should_receive(:safe_run).with('git', 'pull', 'somewhere', 'master') - configuration.find_and_execute_task('git:prepare_tree') - end - end - end - end - - context "tagdeploy" do - before :each do - configuration.set(:branch, 'master') - configuration.set(:stage, 'test') - end - - it 'does not raise an error when run from a clean tree' do - with_clean_repo do - expect { configuration.find_and_execute_task('git:tagdeploy') }.to_not raise_error - end - end - - it 'adds appropriate git tags' do - with_clean_repo do - configuration.find_and_execute_task('git:tagdeploy') - - tags = `git tag -l`.split(/\n/) - tags.should have(1).items - tags.first.should =~ /^test-\d{4}\.\d{2}\.\d{2}/ - end - end - - it 'does not run when :no_deploytags is defined by (i.e. by the stage)' do - with_clean_repo do - configuration.set(:branch, 'master') - configuration.set(:stage, 'test') - configuration.set(:no_deploytags, true) - configuration.cdt.should_not_receive(:validate_git_vars) - expect { configuration.find_and_execute_task('git:prepare_tree') }.to_not raise_error - end - end - - it 'supports configurable timestamp formats' do - with_clean_repo do - configuration.set(:deploytag_time_format, '%Y-%m-%d') - configuration.find_and_execute_task('git:tagdeploy') - tags = `git tag -l`.split(/\n/) - tags.should have(1).items - tags.first.should =~ /^test-\d{4}-\d{2}-\d{2}/ - end - end - - it 'supports configurable commit messages' do - with_clean_repo do - configuration.set(:deploytag_commit_message, 'This is my custom commit message') - configuration.find_and_execute_task('git:tagdeploy') - tags = `git tag -l -n40`.split(/\n/) - tags.should have(1).items - tags.first.should =~ /This is my custom commit message/ - end - end - end +describe 'Capistrano::Deploytags' do + pending "capistrano-spec doesn't support Capistrano 3" end From 7f0a7e516ba5a78d985fb625452fcf002b562fbd Mon Sep 17 00:00:00 2001 From: Gavin Heavyside Date: Sun, 15 Jun 2014 14:39:39 +0100 Subject: [PATCH 3/5] Update readme for Cap 3 and new conventions --- README.md | 132 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index e0032c9..c3a7d83 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,20 @@ [![Gem Version](https://badge.fury.io/rb/capistrano-deploytags.svg)](http://badge.fury.io/rb/capistrano-deploytags) -Capistrano Deployment Tags -========================== -This plugin to Capistrano will add a timestamped Git tag -at each deployment, automatically. It is intended to be used with -the multistage recipe and will tag each release by environment. -You can, however, use it without multistage simply by setting :branch -and :stage in your recipe. -What It Does ------------- +## Capistrano Deployment Tags + +This plugin for Capistrano 3 will add a timestamped Git tag +at each deployment, automatically. It requires :branch and :stage to be set, +but as Capistrano 3 is multistage by default (unlike Cap 2) :stage should +already be set, but you can override the variable if you want to change the +name of the tag. + +### Requires Capistrano 3 + +As of version 1.0.0, this plugin requires Cap 3. If you need a Capistrano +2 compatible version, then use `gem 'capistrano-deploytags', '~> 0.9.2'` + +### What It Does + Simply: it makes it so you can track your deployments from Git. If I were to issue the command: @@ -24,21 +30,29 @@ generating statistics about deployments per day/week/year, tracking code size over a period of time, detecting Rails migrations, and probably a thousand other things I haven't thought of. -Usage ------ +### Usage + capistrano-deploytags is available on [rubygems.org](https://rubygems.org/gems/capistrano-deploytags). -You can install it from there with: +In keeping with the pattern used by Capistrano itself and other plugins, add it +to the `development` group of your Gemfile with `require: false`: -`gem install capistrano-deploytags` +```ruby +# Gemfile +group :deployment do + gem 'capistrano-deploytags', '~> 1.0.0', require: false +end +``` -If you use Bundler, be sure to add the gem to your Gemfile. -In your Capistrano `config/deploy.rb` you should add: +Then require `capistrano-deploytags/capistrano` in your Capfile -`require 'capistrano-deploytags'` +``` +# Capfile +require 'capistrano-deploytags/capistrano' +``` -This will create two tasks, one that runs before deployment and one -that runs after. +This will create two tasks, one that runs before the `deploy` task, and one +that runs after the `cleanup` task. *NOTE:* You will be creating and pushing tags from the version of the code in the current checkout. This plugin needs to be run from a clean checkout of your @@ -51,15 +65,14 @@ system that will actually be deployed before checking the tree for changes. Know this ahead of time as this may affect how you deal with your deployment branches. -Setting the Remote ------------------- -By default, Capistrano Deploytags will use the first remote in the list returned -by `git remote`. If you prefer to use a different remote, then you may change the -`:git_remote` setting from your `deploy.rb`, the stage, or on the command line with -`-S git_remote=your-remote`. +### Setting the Remote + +By default, Capistrano Deploytags will use the remote names `origin`. If you +use a different remote name, then you may change the `:git_remote` setting +from your `deploy.rb` or the stage. + +### Working on Your Deployment Scripts -Working on Your Deployment Scripts ----------------------------------- Because you must have a clean tree to deploy, working on your deployment scripts themselves can be a bit frustrating unless you know how to make it work. The easiest way around this problem is to simply commit your changes @@ -69,8 +82,8 @@ happily carry on deploying without complaint. Alternatively, you could disable the plugin temporarily with one of the methods described below. -Disabling Tagging for a Stage ------------------------------ +### Disabling Tagging for a Stage + Sometimes you do not want to enable deployment tagging for a particular stage. In that event, you can simply disable tagging by setting `no_deploytags` like so: @@ -79,7 +92,8 @@ like so: set :no_deploytags, true ``` -You can also set this from the command line at any time with `-S no_deploytags=true`. +You can also set this from the command line at any time with an environment +variable `cap stage deploy NO_DEPLOYTAGS=true`. *NOTE:* this will disable the use of the plugin's functionality entirely for that stage. The tasks will run, but will do nothing. This means that tasks that @@ -87,24 +101,24 @@ are hooked to the Capistrano Deploytags tasks will also still run, but they may find their expectations are not met with regards to the cleanliness of the git tree. -Customizing the Tag Format --------------------------- -You may override the time format in `config/deploy.rb`: +### Customizing the Tag Format + +You may override the time format in `deploy.rb` or your stage: ```ruby set :deploytag_time_format, "%Y.%m.%d-%H%M%S-utc" ``` -Customizing the Tag Commit Message ----------------------------------- +### Customizing the Tag Commit Message + By default, Capistrano Deploytags will create a tag with a message that indicates the local user name on the box where the deployment is done, and the hash of the tagged commit. If you prefer to have a more detailed commit message you may override -the `:deploytag_commit_message` setting from your `deploy.rb` or on the command line -with `-S deploytag_commit_message='This is my commit message for the deployed tag'`. +the `:deploytag_commit_message` setting from your `deploy.rb`, e.g. +`set :deploytag_commit_message, 'This is my commit message for the deployed tag'` + +### Viewing Deployment History -Viewing Deployment History --------------------------- It's trivial to view the deployment history for a repo. From a checkout of the repo, type `git tag -l -n1`. The output looks something like: @@ -113,7 +127,7 @@ dev-2013.07.22-105130 baz deployed a4d522d9d to dev dev-2013.07.22-113207 karl deployed 4c43f8464 to dev dev-2013.07.22-114437 gavin deployed 776e15414 to dev dev-2013.07.22-115103 karl deployed 619ff5724 to dev -dev-2013.07.22-144121 joshmyers deployed cf1ed1a02 to dev +dev-2013.07.22-144121 josh deployed cf1ed1a02 to dev ``` A little use of `grep` and you can easily get the history for a particular (e.g. `git tag -l -n1 | grep dev`). @@ -121,8 +135,8 @@ particular (e.g. `git tag -l -n1 | grep dev`). It should be noted that the names used when tags are created are the local user name on the box where the deployment is done. -Helpful Git Config ------------------- +### Helpful Git Config + You might find it useful to add this to your ~/.gitconfig in order to get a nice history view of the commits and tags. @@ -134,29 +148,43 @@ to get a nice history view of the commits and tags. You can then view the list by typing `git lol` from the checked out code path. -Deploying a Previous Commit ---------------------------- +### Deploying a Previous Commit + Because you have to actually be on the head of the branch you are deploying in order for tagging to work properly, deploying a previous -commit doesn't work as you might expect. The simple solution is to -create a new branch from the previous commit you wish to deploy and -supplying `-S branch=` as arguments to Capistrano. +commit doesn't work as you might expect. + +One simple solution is to configure your `config.rb` to accept an ENV var +override. Then if you need to deploy a previous commit you can check out that +commit (SHA or branch), and supply the var on the command line. e.g. with this +in your `config.rb`: + +```ruby +set :branch, ENV["REVISION"] || ENV["BRANCH_NAME"] || "master" +``` + +you can deploy a previous commit with + +```shell +git checkout +cap deploy REVISION= +``` + +### Running from Jenkins -Running from Jenkins --------------------- Because Jenkins will check out the code with the current revision number you will be in a detached state. This causes the plugin to be unhappy about the git tree. The solution is to add `-S branch=$GIT_COMMIT` to the cap deploy line called from your Jenkins build. This will cause the diffs and comparisons done by the deploytags gem to be correct. -Credits -------- +### Credits + This software was written by [Karl Matthias](https://github.com/relistan) with help from [Gavin Heavyside](https://github.com/gavinheavyside) and the support of [MyDrive Solutions Limited](http://mydrivesolutions.com). -License -------- +### License + This plugin is released under the BSD two clause license which is available in both the Ruby Gem and the source repository. From 8ed22009d7b8dce958cbc107407cc720db0648df Mon Sep 17 00:00:00 2001 From: Gavin Heavyside Date: Sun, 15 Jun 2014 14:53:40 +0100 Subject: [PATCH 4/5] Use error-level logging for error --- lib/capistrano-deploytags/tasks/deploytags.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/capistrano-deploytags/tasks/deploytags.rake b/lib/capistrano-deploytags/tasks/deploytags.rake index 8c41373..62818e5 100644 --- a/lib/capistrano-deploytags/tasks/deploytags.rake +++ b/lib/capistrano-deploytags/tasks/deploytags.rake @@ -9,7 +9,7 @@ namespace :deploy do stage = fetch(:stage, false) unless branch && stage - warn 'capistrano-deploytags requires that :branch and :stage be defined' + error 'capistrano-deploytags requires that :branch and :stage be defined' raise 'define :branch and :stage' end From 0945596b2f615800fd3e094549e726dd05a7e6e5 Mon Sep 17 00:00:00 2001 From: Gavin Heavyside Date: Wed, 25 Jun 2014 12:08:35 +0100 Subject: [PATCH 5/5] Rename to capistrano/deploytags --- README.md | 4 ++-- .../capistrano.rb => capistrano/deploytags.rb} | 0 .../tasks/deploytags.rake | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename lib/{capistrano-deploytags/capistrano.rb => capistrano/deploytags.rb} (100%) rename lib/{capistrano-deploytags => capistrano}/tasks/deploytags.rake (100%) diff --git a/README.md b/README.md index c3a7d83..1be7fa6 100644 --- a/README.md +++ b/README.md @@ -44,11 +44,11 @@ group :deployment do end ``` -Then require `capistrano-deploytags/capistrano` in your Capfile +Then require `capistrano/deploytags` in your Capfile ``` # Capfile -require 'capistrano-deploytags/capistrano' +require 'capistrano/deploytags' ``` This will create two tasks, one that runs before the `deploy` task, and one diff --git a/lib/capistrano-deploytags/capistrano.rb b/lib/capistrano/deploytags.rb similarity index 100% rename from lib/capistrano-deploytags/capistrano.rb rename to lib/capistrano/deploytags.rb diff --git a/lib/capistrano-deploytags/tasks/deploytags.rake b/lib/capistrano/tasks/deploytags.rake similarity index 100% rename from lib/capistrano-deploytags/tasks/deploytags.rake rename to lib/capistrano/tasks/deploytags.rake