zilkey-auto_tagger 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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