zilkey-auto_tagger 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,3 +1,7 @@
1
+ # IMPORTANT NOTE
2
+
3
+ This gem is still in it's infancy, and lots of things might change. Since this creates and pushes tags to your git repository, please use with caution.
4
+
1
5
  # AutoTagger
2
6
 
3
7
  AutoTagger is a gem that helps you automatically create a date-stamped tag for each stage of your deployment, and deploy from the last tag from the previous environment.
@@ -45,21 +49,21 @@ Example `config/deploy.rb` file:
45
49
 
46
50
  require 'release_tagger'
47
51
 
48
- # The :stages variable is required
49
- set :stages, [:ci, :staging, :production]
52
+ # The :autotagger_stages variable is required
53
+ set :autotagger_stages, [:ci, :staging, :production]
50
54
 
51
55
  # The :working_directory variable is optional, and defaults to Dir.pwd
52
56
  # :working_directory can be an absolute or relative path
53
57
  set :working_directory, "../../"
54
58
 
55
59
  task :production do
56
- # In each of your environments that need auto-branch setting, you need to set :current_stage
57
- set :current_stage, :production
60
+ # In each of your environments that need auto-branch setting, you need to set :stage
61
+ set :stage, :production
58
62
  end
59
63
 
60
64
  task :staging do
61
- # If you do not set current_stage, it will not auto-set your branch
62
- # set :current_stage, :staging
65
+ # If you do not set stage, it will not auto-set your branch
66
+ # set :stage, :staging
63
67
  end
64
68
 
65
69
  # You need to add the before/ater callbacks yourself
@@ -68,7 +72,18 @@ Example `config/deploy.rb` file:
68
72
  after "deploy", "release_tagger:write_tag_to_shared"
69
73
  after "deploy", "release_tagger:print_latest_tags"
70
74
 
71
- ### `release_tagger:set_branch`
75
+ ### Cpistano-ext multistage support
76
+
77
+ If you use capistano-ext multistage, you can use auto_tagger.
78
+
79
+ set :autotagger_stages, [:ci, :staging, :production]
80
+ set :stages, [:staging, :production]
81
+ set :default_stage, :staging
82
+ require 'capistrano/ext/multistage'
83
+
84
+ When you deploy, autotagger will auto-detect your current stage.
85
+
86
+ ### release_tagger:set_branch
72
87
 
73
88
  This task sets the git branch to the latest tag from the previous stage. Assume you have the following tags in your git repository:
74
89
 
@@ -78,7 +93,7 @@ This task sets the git branch to the latest tag from the previous stage. Assume
78
93
 
79
94
  And the following stages in your capistrano file:
80
95
 
81
- set :stages, [:ci, :staging, :production]
96
+ set :autotagger_stages, [:ci, :staging, :production]
82
97
 
83
98
  The deployments would look like this:
84
99
 
@@ -96,19 +111,19 @@ If you add `before "deploy:update_code", "release_tagger:set_branch"`, you can j
96
111
 
97
112
  and the branch will be set for you automatically.
98
113
 
99
- ### `release_tagger:create_tag`
114
+ ### release_tagger:create_tag
100
115
 
101
116
  This cap task creates a new tag, based on the latest tag from the previous environment.
102
117
 
103
118
  If there is no tag from the previous stage, it creates a new tag from the latest commit in your _working directory_.
104
119
 
105
- ### `release_tagger:print_latest_tags`
120
+ ### release_tagger:print_latest_tags
106
121
 
107
122
  This task reads the git version from the text file in shared:
108
123
 
109
124
  cap staging release_tagger:read_tag_from_shared
110
125
 
111
- ### `release_tagger:print_latest_tags`
126
+ ### release_tagger:print_latest_tags
112
127
 
113
128
  This task takes the latest tag from each environment and prints it to the screen. You can add it to your deploy.rb like so:
114
129
 
@@ -125,9 +140,34 @@ This will produce output like:
125
140
  ** staging staging/20090331050908 8031807feb5f4f99dd83257cdc07081fa6080cba some commit message
126
141
  ** production production/20090331050917 8031807feb5f4f99dd83257cdc07081fa6080cba some commit message
127
142
 
143
+ ## Running tests:
144
+
145
+ You must be able to ssh into your box via localhost (remote login). To make this easier, add your own key to your own account:
146
+
147
+ cat ~/.ssh/id_rsa.pub >>~/.ssh/authorized_keys
148
+
149
+ To ensure that this has worked, try this:
150
+
151
+ ssh localhost
152
+
153
+ If it asks you for a password, you've done something wrong.
154
+
155
+ To run the specs, execute:
156
+
157
+ spec spec/
158
+
159
+ To run the cucumber features, execute:
160
+
161
+ cucumber features/
162
+
128
163
  ## Acknowledgments
129
164
 
130
- Special thanks to Brian Takita for the original recipes, and to Mike Dalessio for his git fu.
165
+ Special thanks to
166
+
167
+ * Brian Takita for the original recipes
168
+ * Mike Dalessio for his git fu
169
+ * Chad Wooley for his feature ideas
170
+ * Tim Holahan for his QA
131
171
 
132
172
  ## Links
133
173
 
@@ -1,16 +1,16 @@
1
1
  class CapistranoHelper
2
2
 
3
- attr_reader :variables, :current_stage, :working_directory
3
+ attr_reader :variables, :stage, :working_directory
4
4
 
5
5
  def initialize(variables)
6
- @stage_manager = StageManager.new(variables[:stages])
6
+ @stage_manager = StageManager.new(variables[:autotagger_stages])
7
7
  @variables = variables
8
- @current_stage = variables[:current_stage]
8
+ @stage = variables[:stage]
9
9
  @working_directory = variables[:working_directory] || Dir.pwd
10
10
  end
11
11
 
12
12
  def previous_stage
13
- @stage_manager.previous_stage(current_stage)
13
+ @stage_manager.previous_stage(stage)
14
14
  end
15
15
 
16
16
  def branch
@@ -36,4 +36,4 @@ class CapistranoHelper
36
36
  entries
37
37
  end
38
38
 
39
- end
39
+ end
@@ -7,10 +7,9 @@ class Commander
7
7
  def execute!(path, cmd)
8
8
  system command_in_context(path, cmd)
9
9
  end
10
-
10
+
11
11
  def command_in_context(path, cmd)
12
12
  "cd #{path} && #{cmd}"
13
13
  end
14
14
  end
15
15
  end
16
-
@@ -13,7 +13,7 @@ class Repository
13
13
  elsif ! File.exists?(path)
14
14
  raise NoSuchPathError
15
15
  elsif ! File.exists?(File.join(path, ".git"))
16
- raise InvalidGitRepositoryError
16
+ raise InvalidGitRepositoryError
17
17
  else
18
18
  @path = path
19
19
  end
@@ -22,15 +22,15 @@ class Repository
22
22
  def ==(other)
23
23
  other.is_a?(Repository) && other.path == path
24
24
  end
25
-
25
+
26
26
  def tags
27
27
  @tags ||= Tag.new(self)
28
28
  end
29
-
29
+
30
30
  def commit_for(tag)
31
31
  Commander.execute(path, "git --no-pager log #{tag} --pretty=oneline -1")
32
32
  end
33
-
33
+
34
34
  def run(cmd)
35
35
  Commander.execute(path, cmd)
36
36
  end
@@ -38,5 +38,5 @@ class Repository
38
38
  def run!(cmd)
39
39
  Commander.execute!(path, cmd) || raise(GitCommandFailedError)
40
40
  end
41
-
41
+
42
42
  end
@@ -5,19 +5,19 @@ class StageManager
5
5
  "You must set the :stages variable to an array, like set :stages, [:ci, :demo]"
6
6
  end
7
7
  end
8
-
8
+
9
9
  attr_reader :stages
10
-
10
+
11
11
  def initialize(stages)
12
12
  raise NoStagesSpecifiedError unless stages && stages.is_a?(Array)
13
13
  @stages = stages
14
14
  end
15
-
16
- def previous_stage(current_stage)
17
- if current_stage
18
- index = stages.index(current_stage) - 1
19
- stages[index] if index > -1
15
+
16
+ def previous_stage(stage)
17
+ if stage
18
+ index = stages.index(stage) - 1
19
+ stages[index] if index > -1
20
20
  end
21
21
  end
22
-
23
- end
22
+
23
+ end
@@ -1,21 +1,21 @@
1
1
  # git --no-pager log --pretty=oneline -1
2
2
  # git tag -a -m 'Successful continuous integration build on #{timestamp}' #{tag_name}"
3
3
  class Tag
4
-
4
+
5
5
  attr_reader :repository
6
-
6
+
7
7
  def initialize(repository)
8
8
  @repository = repository
9
9
  end
10
-
10
+
11
11
  def find_all
12
12
  repository.run("git tag").split("\n")
13
13
  end
14
-
14
+
15
15
  def fetch
16
16
  repository.run! "git fetch origin --tags"
17
17
  end
18
-
18
+
19
19
  def latest_from(stage)
20
20
  find_all.select{|tag| tag =~ /^#{stage}/}.sort.last
21
21
  end
@@ -23,7 +23,7 @@ class Tag
23
23
  def push
24
24
  repository.run! "git push origin --tags"
25
25
  end
26
-
26
+
27
27
  def create(stage, commit = nil)
28
28
  tag_name = name_for(stage)
29
29
  cmd = "git tag #{tag_name}"
@@ -31,11 +31,11 @@ class Tag
31
31
  repository.run! cmd
32
32
  tag_name
33
33
  end
34
-
34
+
35
35
  private
36
-
36
+
37
37
  def name_for(stage)
38
38
  "%s/%s" % [stage, Time.now.utc.strftime('%Y%m%d%H%M%S')]
39
39
  end
40
-
41
- end
40
+
41
+ end
@@ -3,7 +3,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "auto_ta
3
3
  Capistrano::Configuration.instance(:must_exist).load do
4
4
  namespace :release_tagger do
5
5
  desc %Q{
6
- Sets the branch to the latest tag from the previous stage.
6
+ Sets the branch to the latest tag from the previous stage.
7
7
  Use -Shead=true to set the branch to master, -Stag=<tag> to specify the tag explicitly.
8
8
  }
9
9
  task :set_branch do
@@ -40,16 +40,15 @@ Capistrano::Configuration.instance(:must_exist).load do
40
40
  end
41
41
  end
42
42
 
43
- desc %Q{Creates a tag using the current_stage variable}
43
+ desc %Q{Creates a tag using the stage variable}
44
44
  task :create_tag, :roles => :app do
45
- if variables[:current_stage]
46
- previous_tag = AutoTagger.new(StageManager.new(stages).previous_stage(current_stage), Dir.pwd).latest_tag
47
- tag_name = AutoTagger.new(variables[:current_stage], variables[:working_directory]).create_tag(previous_tag)
45
+ if variables[:stage]
46
+ previous_tag = AutoTagger.new(StageManager.new(autotagger_stages).previous_stage(stage), Dir.pwd).latest_tag
47
+ tag_name = AutoTagger.new(variables[:stage], variables[:working_directory]).create_tag(previous_tag)
48
48
  logger.info "AUTO TAGGER created tag #{tag_name} from #{previous_tag.inspect}"
49
49
  else
50
- logger.info "AUTO TAGGER WARNING: skipping auto-creation of tag. Please specify :current_stage to enable auto-creation of tags (like set :current_stage, :ci)."
50
+ logger.info "AUTO TAGGER WARNING: skipping auto-creation of tag. Please specify :stage to enable auto-creation of tags (like set :stage, :ci)."
51
51
  end
52
52
  end
53
53
  end
54
54
  end
55
-
@@ -1,6 +1,9 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
3
  describe AutoTagger do
4
+ before(:each) do
5
+ stub(Dir).pwd { File.join(File.dirname(__FILE__), '..', '..') }
6
+ end
4
7
 
5
8
  describe ".new" do
6
9
  it "blows up if you don't pass an stage" do
@@ -8,7 +11,7 @@ describe AutoTagger do
8
11
  AutoTagger.new(nil)
9
12
  end.should raise_error(AutoTagger::EnvironmentCannotBeBlankError)
10
13
  end
11
-
14
+
12
15
  it "sets the stage when it's passed" do
13
16
  AutoTagger.new("ci").stage.should == "ci"
14
17
  end
@@ -40,7 +43,7 @@ describe AutoTagger do
40
43
  mock(Commander).execute!("/foo", "git fetch origin --tags") {true}
41
44
  mock(Commander).execute!("/foo", "git tag ci/#{timestamp}") {true}
42
45
  mock(Commander).execute!("/foo", "git push origin --tags") {true}
43
-
46
+
44
47
  AutoTagger.new("ci", "/foo").create_tag
45
48
  end
46
49
 
@@ -53,17 +56,17 @@ describe AutoTagger do
53
56
  mock(Commander).execute!("/foo", "git fetch origin --tags") {true}
54
57
  mock(Commander).execute!("/foo", "git tag ci/#{timestamp} guid") {true}
55
58
  mock(Commander).execute!("/foo", "git push origin --tags") {true}
56
-
59
+
57
60
  AutoTagger.new("ci", "/foo").create_tag("guid")
58
61
  end
59
-
62
+
60
63
  it "returns the tag that was created" do
61
64
  time = Time.local(2001,1,1)
62
65
  mock(Time).now.once {time}
63
66
  timestamp = time.utc.strftime('%Y%m%d%H%M%S')
64
67
  mock(File).exists?(anything).twice { true }
65
68
  mock(Commander).execute!(anything, anything).times(any_times) {true}
66
-
69
+
67
70
  AutoTagger.new("ci", "/foo").create_tag.should == "ci/#{timestamp}"
68
71
  end
69
72
  end
@@ -74,9 +77,9 @@ describe AutoTagger do
74
77
 
75
78
  mock(Commander).execute!("/foo", "git fetch origin --tags") {true}
76
79
  mock(Commander).execute("/foo", "git tag") { "ci_01" }
77
-
80
+
78
81
  AutoTagger.new("ci", "/foo").latest_tag
79
82
  end
80
83
  end
81
-
84
+
82
85
  end
@@ -12,25 +12,25 @@ describe CapistranoHelper do
12
12
 
13
13
  describe "#variables" do
14
14
  it "returns all variables" do
15
- CapistranoHelper.new({:stages => [:bar]}).variables.should == {:stages => [:bar]}
15
+ CapistranoHelper.new({:autotagger_stages => [:bar]}).variables.should == {:autotagger_stages => [:bar]}
16
16
  end
17
17
  end
18
18
 
19
19
  describe "#working_directory" do
20
20
  it "returns the hashes' working directory value" do
21
- CapistranoHelper.new({:stages => [:bar], :working_directory => "/foo"}).working_directory.should == "/foo"
21
+ CapistranoHelper.new({:autotagger_stages => [:bar], :working_directory => "/foo"}).working_directory.should == "/foo"
22
22
  end
23
-
23
+
24
24
  it "defaults to Dir.pwd if it's not set, or it's nil" do
25
25
  mock(Dir).pwd { "/bar" }
26
- CapistranoHelper.new({:stages => [:bar]}).working_directory.should == "/bar"
26
+ CapistranoHelper.new({:autotagger_stages => [:bar]}).working_directory.should == "/bar"
27
27
  end
28
28
  end
29
29
 
30
- describe "#current_stage" do
30
+ describe "#stage" do
31
31
  it "returns the hashes' current stage value" do
32
- CapistranoHelper.new({:stages => [:bar], :current_stage => :bar}).current_stage.should == :bar
33
- CapistranoHelper.new({:stages => [:bar]}).current_stage.should be_nil
32
+ CapistranoHelper.new({:autotagger_stages => [:bar], :stage => :bar}).stage.should == :bar
33
+ CapistranoHelper.new({:autotagger_stages => [:bar]}).stage.should be_nil
34
34
  end
35
35
  end
36
36
 
@@ -45,7 +45,7 @@ describe CapistranoHelper do
45
45
 
46
46
  variables = {
47
47
  :working_directory => "/foo",
48
- :stages => [:ci, :staging, :production]
48
+ :autotagger_stages => [:ci, :staging, :production]
49
49
  }
50
50
  histories = CapistranoHelper.new(variables).release_tag_entries
51
51
  histories.length.should == 3
@@ -59,7 +59,7 @@ describe CapistranoHelper do
59
59
  describe "with :head and :branch specified" do
60
60
  it "returns master" do
61
61
  variables = {
62
- :stages => [:bar],
62
+ :autotagger_stages => [:bar],
63
63
  :head => nil,
64
64
  :branch => "foo"
65
65
  }
@@ -70,7 +70,7 @@ describe CapistranoHelper do
70
70
  describe "with :head specified, but no branch specified" do
71
71
  it "returns master" do
72
72
  variables = {
73
- :stages => [:bar],
73
+ :autotagger_stages => [:bar],
74
74
  :head => nil
75
75
  }
76
76
  CapistranoHelper.new(variables).branch.should == nil
@@ -80,7 +80,7 @@ describe CapistranoHelper do
80
80
  describe "with :branch specified" do
81
81
  it "returns the value of branch" do
82
82
  variables = {
83
- :stages => [:bar],
83
+ :autotagger_stages => [:bar],
84
84
  :branch => "foo"
85
85
  }
86
86
  CapistranoHelper.new(variables).branch.should == "foo"
@@ -90,8 +90,8 @@ describe CapistranoHelper do
90
90
  describe "with a previous stage with a tag" do
91
91
  it "returns the latest tag for the previous stage" do
92
92
  variables = {
93
- :stages => [:foo, :bar],
94
- :current_stage => :bar,
93
+ :autotagger_stages => [:foo, :bar],
94
+ :stage => :bar,
95
95
  :branch => "master",
96
96
  :working_directory => "/foo"
97
97
  }
@@ -105,8 +105,8 @@ describe CapistranoHelper do
105
105
  describe "with no branch and a previous stage with no tag" do
106
106
  it "returns nil" do
107
107
  variables = {
108
- :stages => [:foo, :bar],
109
- :current_stage => :bar,
108
+ :autotagger_stages => [:foo, :bar],
109
+ :stage => :bar,
110
110
  :working_directory => "/foo"
111
111
  }
112
112
  tagger = Object.new
@@ -119,8 +119,8 @@ describe CapistranoHelper do
119
119
  describe "with no branch and previous stage" do
120
120
  it "returns nil" do
121
121
  variables = {
122
- :stages => [:bar],
123
- :current_stage => :bar
122
+ :autotagger_stages => [:bar],
123
+ :stage => :bar
124
124
  }
125
125
  CapistranoHelper.new(variables).previous_stage.should be_nil
126
126
  CapistranoHelper.new(variables).branch.should == nil
@@ -7,7 +7,7 @@ describe Commander do
7
7
  Commander.execute("/foo", "ls")
8
8
  end
9
9
  end
10
-
10
+
11
11
  describe "system" do
12
12
  it "executes and doesn't return anything" do
13
13
  mock(Commander).system("cd /foo && ls")
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
3
  describe StageManager do
4
-
4
+
5
5
  describe ".new" do
6
6
  [nil, ""].each do |value|
7
7
  it "blows up if there are stages == #{value.inspect}" do
@@ -26,5 +26,5 @@ describe StageManager do
26
26
  end
27
27
  end
28
28
 
29
-
29
+
30
30
  end
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
3
  describe Tag do
4
-
4
+
5
5
  before(:each) do
6
6
  @repository = Object.new
7
7
  end
@@ -11,7 +11,7 @@ describe Tag do
11
11
  Tag.new(@repository).repository.should == @repository
12
12
  end
13
13
  end
14
-
14
+
15
15
  describe "#find_all" do
16
16
  it "returns an array of tags" do
17
17
  mock(@repository).run("git tag") { "ci_01\nci_02" }
@@ -23,7 +23,7 @@ describe Tag do
23
23
  Tag.new(@repository).find_all.should be_empty
24
24
  end
25
25
  end
26
-
26
+
27
27
  describe "#latest_from" do
28
28
  before do
29
29
  @tag = Tag.new(@repository)
@@ -61,6 +61,6 @@ describe Tag do
61
61
  mock(@repository).run!("git tag #{tag_name}")
62
62
  Tag.new(@repository).create("ci").should == tag_name
63
63
  end
64
- end
65
-
64
+ end
65
+
66
66
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zilkey-auto_tagger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Dean