capistrano-deploytags 0.9.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +82 -53
- data/lib/capistrano-deploytags.rb +0 -3
- data/lib/capistrano/deploytags.rb +26 -0
- data/lib/capistrano/tasks/deploytags.rake +49 -0
- metadata +33 -13
- data/lib/capistrano/deploy_tags.rb +0 -104
data/README.md
CHANGED
@@ -1,13 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/capistrano-deploytags.svg)](http://badge.fury.io/rb/capistrano-deploytags)
|
2
|
+
|
3
|
+
## Capistrano Deployment Tags
|
4
|
+
|
5
|
+
This plugin for Capistrano 3 will add a timestamped Git tag
|
6
|
+
at each deployment, automatically. It requires :branch and :stage to be set,
|
7
|
+
but as Capistrano 3 is multistage by default (unlike Cap 2) :stage should
|
8
|
+
already be set, but you can override the variable if you want to change the
|
9
|
+
name of the tag.
|
10
|
+
|
11
|
+
### Requires Capistrano 3
|
12
|
+
|
13
|
+
As of version 1.0.0, this plugin requires Cap 3. If you need a Capistrano
|
14
|
+
2 compatible version, then use `gem 'capistrano-deploytags', '~> 0.9.2'`
|
15
|
+
|
16
|
+
### What It Does
|
17
|
+
|
11
18
|
Simply: it makes it so you can track your deployments from Git.
|
12
19
|
If I were to issue the command:
|
13
20
|
|
@@ -23,21 +30,29 @@ generating statistics about deployments per day/week/year, tracking
|
|
23
30
|
code size over a period of time, detecting Rails migrations, and
|
24
31
|
probably a thousand other things I haven't thought of.
|
25
32
|
|
26
|
-
Usage
|
27
|
-
|
33
|
+
### Usage
|
34
|
+
|
28
35
|
capistrano-deploytags is available on
|
29
36
|
[rubygems.org](https://rubygems.org/gems/capistrano-deploytags).
|
30
|
-
|
37
|
+
In keeping with the pattern used by Capistrano itself and other plugins, add it
|
38
|
+
to the `development` group of your Gemfile with `require: false`:
|
31
39
|
|
32
|
-
|
40
|
+
```ruby
|
41
|
+
# Gemfile
|
42
|
+
group :deployment do
|
43
|
+
gem 'capistrano-deploytags', '~> 1.0.0', require: false
|
44
|
+
end
|
45
|
+
```
|
33
46
|
|
34
|
-
|
35
|
-
In your Capistrano `config/deploy.rb` you should add:
|
47
|
+
Then require `capistrano/deploytags` in your Capfile
|
36
48
|
|
37
|
-
|
49
|
+
```
|
50
|
+
# Capfile
|
51
|
+
require 'capistrano/deploytags'
|
52
|
+
```
|
38
53
|
|
39
|
-
This will create two tasks, one that runs before
|
40
|
-
that runs after.
|
54
|
+
This will create two tasks, one that runs before the `deploy` task, and one
|
55
|
+
that runs after the `cleanup` task.
|
41
56
|
|
42
57
|
*NOTE:* You will be creating and pushing tags from the version of the code in the
|
43
58
|
current checkout. This plugin needs to be run from a clean checkout of your
|
@@ -50,15 +65,14 @@ system that will actually be deployed before checking the tree for changes.
|
|
50
65
|
Know this ahead of time as this may affect how you deal with your deployment
|
51
66
|
branches.
|
52
67
|
|
53
|
-
Setting the Remote
|
54
|
-
|
55
|
-
By default, Capistrano Deploytags will use the
|
56
|
-
|
57
|
-
|
58
|
-
|
68
|
+
### Setting the Remote
|
69
|
+
|
70
|
+
By default, Capistrano Deploytags will use the remote names `origin`. If you
|
71
|
+
use a different remote name, then you may change the `:git_remote` setting
|
72
|
+
from your `deploy.rb` or the stage.
|
73
|
+
|
74
|
+
### Working on Your Deployment Scripts
|
59
75
|
|
60
|
-
Working on Your Deployment Scripts
|
61
|
-
----------------------------------
|
62
76
|
Because you must have a clean tree to deploy, working on your deployment
|
63
77
|
scripts themselves can be a bit frustrating unless you know how to make it
|
64
78
|
work. The easiest way around this problem is to simply commit your changes
|
@@ -68,8 +82,8 @@ happily carry on deploying without complaint.
|
|
68
82
|
Alternatively, you could disable the plugin temporarily with one of the
|
69
83
|
methods described below.
|
70
84
|
|
71
|
-
Disabling Tagging for a Stage
|
72
|
-
|
85
|
+
### Disabling Tagging for a Stage
|
86
|
+
|
73
87
|
Sometimes you do not want to enable deployment tagging for a particular
|
74
88
|
stage. In that event, you can simply disable tagging by setting `no_deploytags`
|
75
89
|
like so:
|
@@ -78,7 +92,8 @@ like so:
|
|
78
92
|
set :no_deploytags, true
|
79
93
|
```
|
80
94
|
|
81
|
-
You can also set this from the command line at any time with
|
95
|
+
You can also set this from the command line at any time with an environment
|
96
|
+
variable `cap stage deploy NO_DEPLOYTAGS=true`.
|
82
97
|
|
83
98
|
*NOTE:* this will disable the use of the plugin's functionality entirely for
|
84
99
|
that stage. The tasks will run, but will do nothing. This means that tasks that
|
@@ -86,24 +101,24 @@ are hooked to the Capistrano Deploytags tasks will also still run, but they may
|
|
86
101
|
find their expectations are not met with regards to the cleanliness of the git
|
87
102
|
tree.
|
88
103
|
|
89
|
-
Customizing the Tag Format
|
90
|
-
|
91
|
-
You may override the time format in `
|
104
|
+
### Customizing the Tag Format
|
105
|
+
|
106
|
+
You may override the time format in `deploy.rb` or your stage:
|
92
107
|
|
93
108
|
```ruby
|
94
109
|
set :deploytag_time_format, "%Y.%m.%d-%H%M%S-utc"
|
95
110
|
```
|
96
111
|
|
97
|
-
Customizing the Tag Commit Message
|
98
|
-
|
112
|
+
### Customizing the Tag Commit Message
|
113
|
+
|
99
114
|
By default, Capistrano Deploytags will create a tag with a message that indicates
|
100
115
|
the local user name on the box where the deployment is done, and the hash of the
|
101
116
|
tagged commit. If you prefer to have a more detailed commit message you may override
|
102
|
-
the `:deploytag_commit_message` setting from your `deploy.rb
|
103
|
-
|
117
|
+
the `:deploytag_commit_message` setting from your `deploy.rb`, e.g.
|
118
|
+
`set :deploytag_commit_message, 'This is my commit message for the deployed tag'`
|
119
|
+
|
120
|
+
### Viewing Deployment History
|
104
121
|
|
105
|
-
Viewing Deployment History
|
106
|
-
--------------------------
|
107
122
|
It's trivial to view the deployment history for a repo. From a checkout
|
108
123
|
of the repo, type `git tag -l -n1`. The output looks something like:
|
109
124
|
|
@@ -112,7 +127,7 @@ dev-2013.07.22-105130 baz deployed a4d522d9d to dev
|
|
112
127
|
dev-2013.07.22-113207 karl deployed 4c43f8464 to dev
|
113
128
|
dev-2013.07.22-114437 gavin deployed 776e15414 to dev
|
114
129
|
dev-2013.07.22-115103 karl deployed 619ff5724 to dev
|
115
|
-
dev-2013.07.22-144121
|
130
|
+
dev-2013.07.22-144121 josh deployed cf1ed1a02 to dev
|
116
131
|
```
|
117
132
|
A little use of `grep` and you can easily get the history for a
|
118
133
|
particular (e.g. `git tag -l -n1 | grep dev`).
|
@@ -120,8 +135,8 @@ particular (e.g. `git tag -l -n1 | grep dev`).
|
|
120
135
|
It should be noted that the names used when tags are created are the
|
121
136
|
local user name on the box where the deployment is done.
|
122
137
|
|
123
|
-
Helpful Git Config
|
124
|
-
|
138
|
+
### Helpful Git Config
|
139
|
+
|
125
140
|
You might find it useful to add this to your ~/.gitconfig in order
|
126
141
|
to get a nice history view of the commits and tags.
|
127
142
|
|
@@ -133,29 +148,43 @@ to get a nice history view of the commits and tags.
|
|
133
148
|
You can then view the list by typing `git lol` from the checked out
|
134
149
|
code path.
|
135
150
|
|
136
|
-
Deploying a Previous Commit
|
137
|
-
|
151
|
+
### Deploying a Previous Commit
|
152
|
+
|
138
153
|
Because you have to actually be on the head of the branch you are
|
139
154
|
deploying in order for tagging to work properly, deploying a previous
|
140
|
-
commit doesn't work as you might expect.
|
141
|
-
|
142
|
-
|
155
|
+
commit doesn't work as you might expect.
|
156
|
+
|
157
|
+
One simple solution is to configure your `config.rb` to accept an ENV var
|
158
|
+
override. Then if you need to deploy a previous commit you can check out that
|
159
|
+
commit (SHA or branch), and supply the var on the command line. e.g. with this
|
160
|
+
in your `config.rb`:
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
set :branch, ENV["REVISION"] || ENV["BRANCH_NAME"] || "master"
|
164
|
+
```
|
165
|
+
|
166
|
+
you can deploy a previous commit with
|
167
|
+
|
168
|
+
```shell
|
169
|
+
git checkout <previous-commit>
|
170
|
+
cap <stage> deploy REVISION=<previous-commit>
|
171
|
+
```
|
172
|
+
|
173
|
+
### Running from Jenkins
|
143
174
|
|
144
|
-
Running from Jenkins
|
145
|
-
--------------------
|
146
175
|
Because Jenkins will check out the code with the current revision
|
147
176
|
number you will be in a detached state. This causes the plugin to be
|
148
177
|
unhappy about the git tree. The solution is to add `-S branch=$GIT_COMMIT`
|
149
178
|
to the cap deploy line called from your Jenkins build. This will cause
|
150
179
|
the diffs and comparisons done by the deploytags gem to be correct.
|
151
180
|
|
152
|
-
Credits
|
153
|
-
|
181
|
+
### Credits
|
182
|
+
|
154
183
|
This software was written by [Karl Matthias](https://github.com/relistan)
|
155
184
|
with help from [Gavin Heavyside](https://github.com/gavinheavyside) and the
|
156
185
|
support of [MyDrive Solutions Limited](http://mydrivesolutions.com).
|
157
186
|
|
158
|
-
License
|
159
|
-
|
187
|
+
### License
|
188
|
+
|
160
189
|
This plugin is released under the BSD two clause license which is
|
161
190
|
available in both the Ruby Gem and the source repository.
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Ensure deploy tasks are loaded before we run
|
2
|
+
require 'capistrano/deploy'
|
3
|
+
|
4
|
+
# Load extra tasks into the deploy namespace
|
5
|
+
load File.expand_path("../tasks/deploytags.rake", __FILE__)
|
6
|
+
|
7
|
+
module CapistranoDeploytags
|
8
|
+
class Helper
|
9
|
+
def self.git_tag_for(stage)
|
10
|
+
"#{stage}-#{formatted_time}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.formatted_time
|
14
|
+
Time.new.utc.strftime(fetch(:deploytag_time_format, "%Y.%m.%d-%H%M%S-utc"))
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.commit_message(current_sha, stage)
|
18
|
+
if fetch(:deploytag_commit_message, false)
|
19
|
+
deploytag_commit_message
|
20
|
+
else
|
21
|
+
tag_user = (ENV['USER'] || ENV['USERNAME'] || 'deployer').strip
|
22
|
+
"#{tag_user} deployed #{current_sha} to #{stage}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
namespace :deploy do
|
2
|
+
desc 'prepare git tree so we can tag on successful deployment'
|
3
|
+
before :deploy, :prepare_tree do
|
4
|
+
run_locally do
|
5
|
+
if ENV['NO_DEPLOYTAGS'] || fetch(:no_deploytags, false)
|
6
|
+
info "[deploytags] Skipping deploytags"
|
7
|
+
else
|
8
|
+
branch = fetch(:branch, false)
|
9
|
+
stage = fetch(:stage, false)
|
10
|
+
|
11
|
+
unless branch && stage
|
12
|
+
error 'capistrano-deploytags requires that :branch and :stage be defined'
|
13
|
+
raise 'define :branch and :stage'
|
14
|
+
end
|
15
|
+
|
16
|
+
strategy.git "fetch #{fetch(:git_remote, 'origin')}"
|
17
|
+
|
18
|
+
diff_output = capture :git, "diff #{branch} --shortstat"
|
19
|
+
|
20
|
+
unless diff_output.empty?
|
21
|
+
error "Whoa there, partner. Dirty trees can't deploy. Git yerself clean first"
|
22
|
+
raise 'Dirty git tree'
|
23
|
+
end
|
24
|
+
|
25
|
+
strategy.git "checkout #{branch}"
|
26
|
+
info "Pulling from #{branch}"
|
27
|
+
strategy.git "pull #{fetch(:git_remote, 'origin')} #{branch}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'add git tags for each successful deployment'
|
33
|
+
after :cleanup, :tagdeploy do
|
34
|
+
run_locally do
|
35
|
+
if ENV['NO_DEPLOYTAGS'] || fetch(:no_deploytags, false)
|
36
|
+
info "[deploytags] Skipping deploytags"
|
37
|
+
else
|
38
|
+
tag_name = CapistranoDeploytags::Helper.git_tag_for(fetch(:stage))
|
39
|
+
latest_revision = fetch(:current_revision)
|
40
|
+
commit_message = CapistranoDeploytags::Helper.commit_message(latest_revision, fetch(:stage))
|
41
|
+
|
42
|
+
strategy.git "tag -a #{tag_name} -m \"#{commit_message}\" #{latest_revision}"
|
43
|
+
strategy.git "push #{fetch(:git_remote, 'origin')} #{tag_name}"
|
44
|
+
|
45
|
+
info "[cap-deploy-tagger] Tagged #{latest_revision} with #{tag_name}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano-deploytags
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Karl Matthias
|
9
|
+
- Gavin Heavyside
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2014-
|
13
|
+
date: 2014-06-14 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: capistrano
|
@@ -18,7 +19,7 @@ dependencies:
|
|
18
19
|
requirements:
|
19
20
|
- - ! '>='
|
20
21
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
22
|
+
version: 3.2.0
|
22
23
|
type: :runtime
|
23
24
|
prerelease: false
|
24
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,16 +27,16 @@ dependencies:
|
|
26
27
|
requirements:
|
27
28
|
- - ! '>='
|
28
29
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
30
|
+
version: 3.2.0
|
30
31
|
- !ruby/object:Gem::Dependency
|
31
|
-
name:
|
32
|
+
name: rake
|
32
33
|
requirement: !ruby/object:Gem::Requirement
|
33
34
|
none: false
|
34
35
|
requirements:
|
35
36
|
- - ! '>='
|
36
37
|
- !ruby/object:Gem::Version
|
37
38
|
version: '0'
|
38
|
-
type: :
|
39
|
+
type: :development
|
39
40
|
prerelease: false
|
40
41
|
version_requirements: !ruby/object:Gem::Requirement
|
41
42
|
none: false
|
@@ -43,21 +44,40 @@ dependencies:
|
|
43
44
|
- - ! '>='
|
44
45
|
- !ruby/object:Gem::Version
|
45
46
|
version: '0'
|
46
|
-
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.0.0
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 3.0.0
|
63
|
+
description: ! ' Capistrano Deploytags is a simple plugin to Capistrano 3 that works
|
47
64
|
with your deployment framework to track your code releases. All you have to do is
|
48
|
-
require capistrano-deploytags and each deployment will add a new tag
|
49
|
-
pointing to the latest commit. This lets you easily see which
|
50
|
-
each environment, and allows you to figure out which code was
|
51
|
-
at any time in the past.
|
65
|
+
require capistrano-deploytags/capistrano and each deployment will add a new tag
|
66
|
+
for that deployment, pointing to the latest commit. This lets you easily see which
|
67
|
+
code is deployed on each environment, and allows you to figure out which code was
|
68
|
+
running in an environment at any time in the past.
|
52
69
|
|
53
70
|
'
|
54
|
-
email:
|
71
|
+
email:
|
72
|
+
- relistan@gmail.com
|
73
|
+
- gavin.heavyside@mydrivesolutions.com
|
55
74
|
executables: []
|
56
75
|
extensions: []
|
57
76
|
extra_rdoc_files: []
|
58
77
|
files:
|
59
78
|
- lib/capistrano-deploytags.rb
|
60
|
-
- lib/capistrano/
|
79
|
+
- lib/capistrano/deploytags.rb
|
80
|
+
- lib/capistrano/tasks/deploytags.rake
|
61
81
|
- README.md
|
62
82
|
- LICENSE
|
63
83
|
homepage: http://github.com/mydrive/capistrano-deploytags
|
@@ -1,104 +0,0 @@
|
|
1
|
-
module Capistrano
|
2
|
-
module DeployTags
|
3
|
-
def pending_git_changes?
|
4
|
-
# Do we have any changes vs HEAD on deployment branch?
|
5
|
-
`git fetch #{remote}`.tap do |output|
|
6
|
-
return !(`git diff #{branch} --shortstat`.strip.empty?) if exec_success?
|
7
|
-
raise "'git fetch #{remote}' failed:\n #{output}"
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def git_tag_for(stage)
|
12
|
-
"#{stage}-#{formatted_time}"
|
13
|
-
end
|
14
|
-
|
15
|
-
def formatted_time
|
16
|
-
Time.new.utc.strftime(fetch(:deploytag_time_format, "%Y.%m.%d-%H%M%S-utc"))
|
17
|
-
end
|
18
|
-
|
19
|
-
def safe_run(*args)
|
20
|
-
raise "#{args.join(" ")} failed!" unless system(*args)
|
21
|
-
end
|
22
|
-
|
23
|
-
def exec_success?
|
24
|
-
$?.success?
|
25
|
-
end
|
26
|
-
|
27
|
-
def validate_git_vars
|
28
|
-
unless exists?(:branch) && exists?(:stage)
|
29
|
-
logger.log Capistrano::Logger::IMPORTANT, 'Capistrano Deploytags requires that :branch and :stage be defined.'
|
30
|
-
raise 'define :branch and :stage'
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def git_tag?(tag)
|
35
|
-
!`git tag -l #{tag}`.strip.empty?
|
36
|
-
end
|
37
|
-
|
38
|
-
def has_remote?
|
39
|
-
!`git remote`.strip.empty?
|
40
|
-
end
|
41
|
-
|
42
|
-
def remote
|
43
|
-
exists?(:git_remote) ? git_remote : `git remote`.strip.split(/\n/).first
|
44
|
-
end
|
45
|
-
|
46
|
-
def commit_message(current_sha)
|
47
|
-
if exists?(:deploytag_commit_message)
|
48
|
-
deploytag_commit_message
|
49
|
-
else
|
50
|
-
tag_user = (ENV['USER'] || ENV['USERNAME'] || 'deployer').strip
|
51
|
-
"#{tag_user} deployed #{current_sha} to #{stage}"
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def self.load_into(configuration)
|
56
|
-
configuration.load do
|
57
|
-
before 'deploy', 'git:prepare_tree'
|
58
|
-
before 'deploy:migrations', 'git:prepare_tree'
|
59
|
-
after 'deploy', 'git:tagdeploy'
|
60
|
-
after 'deploy:migrations', 'git:tagdeploy'
|
61
|
-
|
62
|
-
desc 'prepare git tree so we can tag on successful deployment'
|
63
|
-
namespace :git do
|
64
|
-
task :prepare_tree, :except => { :no_release => true } do
|
65
|
-
next if fetch(:no_deploytags, false)
|
66
|
-
|
67
|
-
cdt.validate_git_vars
|
68
|
-
|
69
|
-
logger.log Capistrano::Logger::IMPORTANT, "Preparing to deploy HEAD from branch '#{branch}' to '#{stage}'"
|
70
|
-
|
71
|
-
if cdt.pending_git_changes?
|
72
|
-
logger.log Capistrano::Logger::IMPORTANT, "Whoa there, partner. Dirty trees can't deploy. Git yerself clean first."
|
73
|
-
raise 'Dirty git tree'
|
74
|
-
end
|
75
|
-
|
76
|
-
cdt.safe_run 'git', 'checkout', branch
|
77
|
-
logger.log Capistrano::Logger::IMPORTANT, "Pulling from #{branch}"
|
78
|
-
cdt.safe_run 'git', 'pull', cdt.remote, branch if cdt.has_remote?
|
79
|
-
end
|
80
|
-
|
81
|
-
desc 'add git tags for each successful deployment'
|
82
|
-
task :tagdeploy, :except => { :no_release => true } do
|
83
|
-
next if fetch(:no_deploytags, false)
|
84
|
-
|
85
|
-
cdt.validate_git_vars
|
86
|
-
|
87
|
-
current_sha = `git rev-parse #{branch} HEAD`.strip[0..8]
|
88
|
-
logger.log Capistrano::Logger::INFO, "Tagging #{current_sha} for deployment"
|
89
|
-
|
90
|
-
cdt.safe_run 'git', 'tag', '-a', cdt.git_tag_for(stage), '-m', cdt.commit_message(current_sha)
|
91
|
-
cdt.safe_run 'git', 'push', '--tags' if cdt.has_remote?
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
Capistrano.plugin :cdt, Capistrano::DeployTags
|
101
|
-
|
102
|
-
if Capistrano::Configuration.instance
|
103
|
-
Capistrano::DeployTags.load_into(Capistrano::Configuration.instance(:must_exist))
|
104
|
-
end
|