whiskey_disk 0.5.4 → 0.6.0
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/CHANGELOG +129 -0
- data/README.markdown +21 -2
- data/VERSION +1 -1
- data/examples/deploy-local.yml +4 -0
- data/examples/deploy-multiple-remotes.yml +14 -0
- data/lib/whiskey_disk/config.rb +12 -1
- data/lib/whiskey_disk/rake.rb +6 -0
- data/lib/whiskey_disk.rb +42 -3
- data/spec/whiskey_disk/config_spec.rb +82 -11
- data/spec/whiskey_disk/rake_spec.rb +40 -6
- data/spec/whiskey_disk_spec.rb +147 -10
- data/whiskey_disk.gemspec +37 -36
- metadata +10 -8
- data/.gitignore +0 -1
data/CHANGELOG
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
|
2
|
+
0.6.0 / 2010-12-22
|
3
|
+
==================
|
4
|
+
|
5
|
+
* Version bump to 0.6.0
|
6
|
+
* Merge branch 'feature/multiple-domain-support' into develop
|
7
|
+
* adding a set of multi-domain examples
|
8
|
+
* adding a local deployment example
|
9
|
+
* updating output summary to be more readable
|
10
|
+
* updating README to document multi-domain deployments
|
11
|
+
* rake exit statuses reflect overall deployment/setup success
|
12
|
+
* adding WhiskeyDisk.success? method
|
13
|
+
* We now summarize runs, both local and remote.
|
14
|
+
* record results for local runs as well as remote ones
|
15
|
+
* now run SSH commands on multiple domains, serially, synchronously
|
16
|
+
* propagating changes allowed by normalizing 'domain' in config data
|
17
|
+
* normalize 'domain' values pulled from config files
|
18
|
+
* refactor config file writing in config spec
|
19
|
+
* WD.remote? now understands arrays of 'domain' entries in the config
|
20
|
+
* Merge branch 'release/0.5.4' into develop
|
21
|
+
* bump gemspec for 0.5.4 release
|
22
|
+
* Version bump to 0.5.4
|
23
|
+
* Removing Jeweler warning from Rakefile
|
24
|
+
* Merge branch 'feature/reduce-mocking-code-in-tests' into develop
|
25
|
+
* eliminating more stubbing specs from config_spec
|
26
|
+
* Removing more stub! calls from config specs
|
27
|
+
* removing YAML.load exception stub
|
28
|
+
* replacing some configuration_data stubs in config spec
|
29
|
+
* Remove CURRENT_FILE from config specs
|
30
|
+
* Removing CURRENT from config specs
|
31
|
+
* Removing more File.exists? stubs from config spec.
|
32
|
+
* Removing File.exists? stubs in config specs
|
33
|
+
* spec refactorings
|
34
|
+
* Removing has_config_repo? stubs from rake specs
|
35
|
+
* Using non-stubbed configuration in rake specs
|
36
|
+
* removing useless stub of :register_configuration
|
37
|
+
* And removing unneeded spec helper
|
38
|
+
* removing whiskey_disk config stubbing
|
39
|
+
* introducing use_config() spec helper
|
40
|
+
* Merge branch 'release/0.5.3' into develop
|
41
|
+
* updating gemspec for 0.5.3
|
42
|
+
* updating Contributors section of README
|
43
|
+
* Version bump to 0.5.3
|
44
|
+
* Merge branch 'feature/merge-pull-request-2' into develop
|
45
|
+
* Cosmetic and naming change in new config method
|
46
|
+
* fixing spec example description
|
47
|
+
* Reworking the config to append project name overrides to the env, since everything else is dependent thereupon
|
48
|
+
* tidying up the spec
|
49
|
+
* Allowing a manually specified project name in the bare config hash to be used as the parent project in the absence of one specified from the 'to' env setting
|
50
|
+
* Merge branch 'release/0.5.2' into develop
|
51
|
+
* updating gemspec for version 0.5.2
|
52
|
+
* Bumping version to 0.5.2
|
53
|
+
* Merge branch 'feature/ensure_target_needs_no_ruby' into develop
|
54
|
+
* Updating TODO list
|
55
|
+
* Updating README
|
56
|
+
* Merge branch 'feature/make_check_a_wd_option' into develop
|
57
|
+
* Updating TODO list
|
58
|
+
* Adding --check flag to wd command-line script
|
59
|
+
* Updating README with --check changes
|
60
|
+
* Merge branch 'feature/use_shallow_clone_on_setup' into develop
|
61
|
+
* Updating TODO list
|
62
|
+
* Adding lightning talk info to README
|
63
|
+
* Making shallow clones on initial setup
|
64
|
+
* Merge branch 'release/0.5.0' into develop
|
65
|
+
* updating gemspec for 0.5.0
|
66
|
+
* Version bump to 0.5.0
|
67
|
+
* Merge branch 'feature/alternate-hook-mechanism' into develop
|
68
|
+
* TODO list updates
|
69
|
+
* Make the rake test task do right by bacon
|
70
|
+
* Adding post_setup_script support
|
71
|
+
* Adding post_deploy_script support
|
72
|
+
* Reordering specs for post-setup/deployment tasks
|
73
|
+
* Updating README for post_*_script functionality
|
74
|
+
* TODO file updates
|
75
|
+
* Merge branch 'release/0.4.5' into develop
|
76
|
+
* new gemspec for 0.4.5 release
|
77
|
+
* Version bump to 0.4.5
|
78
|
+
* ENV settings now available to rake when searching for tasks
|
79
|
+
* Merge branch 'feature/refactor-methods' into develop
|
80
|
+
* refactoring common code for rake tasks
|
81
|
+
* further refactoring of clone_repository
|
82
|
+
* refactoring update checkout methods
|
83
|
+
* renaming conditional_clone
|
84
|
+
* Refactoring rake task code
|
85
|
+
* Merge branch 'release/0.4.4' into develop
|
86
|
+
* 0.4.4 gemspec
|
87
|
+
* Version bump to 0.4.4
|
88
|
+
* Merge branch 'feature/readme-updates' into develop
|
89
|
+
* TODO list tweakage
|
90
|
+
* README updates
|
91
|
+
* Merge branch 'release/0.4.3' into develop
|
92
|
+
* updating gemspec
|
93
|
+
* Version bump to 0.4.3
|
94
|
+
* Updating TODO
|
95
|
+
* Smarter setups
|
96
|
+
* TODO updates
|
97
|
+
* Version bump to 0.4.2
|
98
|
+
* Taking a different approach to rake task detection
|
99
|
+
* bumping gemspec
|
100
|
+
* Version bump to 0.4.1
|
101
|
+
* Fixing post_* hook edge case
|
102
|
+
* More README updates
|
103
|
+
* updating README
|
104
|
+
* updated gemspec
|
105
|
+
* adding staleness check docs to README
|
106
|
+
* Version bump to 0.4.0
|
107
|
+
* Make the staleness check actually work with bash.
|
108
|
+
* Adding "else" block to provide feedback when not stale
|
109
|
+
* More complete implementation of staleness checks
|
110
|
+
* Removing earlier abortive implementation of staleness checking
|
111
|
+
* Support for staleness checks
|
112
|
+
* Adding first pass at conditional staleness checks
|
113
|
+
* updating TODO list
|
114
|
+
* README note about post_* rake task dependencies
|
115
|
+
* updated gemspec
|
116
|
+
* Version bump to 0.3.1
|
117
|
+
* No longer require a Rakefile when --path isn't used
|
118
|
+
* We no longer do per-target config file overrides
|
119
|
+
* Don't run post_{setup,deploy} rake tasks without a deployed Rakefile
|
120
|
+
* use 'target' instead of 'environment' in README
|
121
|
+
* encoding < and >
|
122
|
+
* more README tweaks
|
123
|
+
* readme formatting tweak
|
124
|
+
* make sure README.markdown is displayed on install
|
125
|
+
* new and improved README
|
126
|
+
* adding a simple deploy.yml example to the README
|
127
|
+
* add link to live presentation to README
|
128
|
+
* adding a check flag for use with staleness checks
|
129
|
+
* english spike of staleness check in todo file
|
data/README.markdown
CHANGED
@@ -57,6 +57,12 @@ current local checkout.
|
|
57
57
|
do hands-free automated deployments whenever code is pushed to your
|
58
58
|
deployment branch of choice!
|
59
59
|
|
60
|
+
- You can deploy to multiple remote targets at once. Currently this is limited
|
61
|
+
to one-after-the-other synchronous deployments, but we're thinking about
|
62
|
+
doing them in parallel once we're happy with the stability of this (new)
|
63
|
+
feature.
|
64
|
+
|
65
|
+
|
60
66
|
### Assumptions ###
|
61
67
|
|
62
68
|
- your project is managed via git
|
@@ -100,7 +106,7 @@ As a rails plugin:
|
|
100
106
|
|
101
107
|
Known config file settings (if you're familiar with capistrano and vlad these should seem eerily familiar):
|
102
108
|
|
103
|
-
domain: host on which to deploy (
|
109
|
+
domain: host or list of hosts on which to deploy (these are ssh connect strings)
|
104
110
|
deploy_to: path to which to deploy main application
|
105
111
|
repository: git repo path for main application
|
106
112
|
branch: git branch to deploy from main application git repo (default: master)
|
@@ -116,7 +122,7 @@ Known config file settings (if you're familiar with capistrano and vlad these sh
|
|
116
122
|
A simple config/deploy.yml might look like:
|
117
123
|
|
118
124
|
qa:
|
119
|
-
domain: "ogc@
|
125
|
+
domain: "ogc@qa.ogtastic.com"
|
120
126
|
deploy_to: "/var/www/www.ogtastic.com"
|
121
127
|
repository: "git@ogtastic.com:www.ogtastic.com.git"
|
122
128
|
branch: "stable"
|
@@ -132,6 +138,19 @@ of deploy:setup
|
|
132
138
|
at the end of deploy:now
|
133
139
|
|
134
140
|
|
141
|
+
For deploying to multiple hosts, the config/deploy.yml might look like:
|
142
|
+
|
143
|
+
qa:
|
144
|
+
domain:
|
145
|
+
- "ogc@qa1.ogtastic.com"
|
146
|
+
- "ogc@qa2.ogtastic.com""
|
147
|
+
deploy_to: "/var/www/www.ogtastic.com"
|
148
|
+
repository: "git@ogtastic.com:www.ogtastic.com.git"
|
149
|
+
branch: "stable"
|
150
|
+
rake_env:
|
151
|
+
RAILS_ENV: 'production'
|
152
|
+
|
153
|
+
|
135
154
|
### post\_deploy\_script and post\_setup\_script ###
|
136
155
|
|
137
156
|
Whiskey\_disk provides rake task hooks (deploy:post\_setup and deploy:post\_deploy) to allow running custom
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
@@ -0,0 +1,14 @@
|
|
1
|
+
multi:
|
2
|
+
domain:
|
3
|
+
- "ogc@hoenir.websages.com"
|
4
|
+
- "ogc@nerthus.websages.com"
|
5
|
+
deploy_to: "/tmp/test-deployment/"
|
6
|
+
repository: "git@git.ogtastic.com:whiskey_disk.git"
|
7
|
+
branch: "develop"
|
8
|
+
badmulti:
|
9
|
+
domain:
|
10
|
+
- "ogc@hoenir.websages.com"
|
11
|
+
- "ogc@bogus.example.com"
|
12
|
+
deploy_to: "/tmp/test-deployment/"
|
13
|
+
repository: "git@git.ogtastic.com:whiskey_disk.git"
|
14
|
+
branch: "develop"
|
data/lib/whiskey_disk/config.rb
CHANGED
@@ -103,9 +103,20 @@ class WhiskeyDisk
|
|
103
103
|
override_project_name!(data)
|
104
104
|
{ project_name => data }
|
105
105
|
end
|
106
|
+
|
107
|
+
def normalize_domain(data)
|
108
|
+
data.each_pair do |project, project_data|
|
109
|
+
project_data.each_pair do |target, target_data|
|
110
|
+
if target_data['domain']
|
111
|
+
cleaned = [ target_data['domain'] ].flatten.delete_if { |m| m.nil? or m == '' }
|
112
|
+
target_data['domain'] = (cleaned.empty? ? nil : cleaned)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
106
117
|
|
107
118
|
def normalize_data(data)
|
108
|
-
add_project_scoping(add_environment_scoping(data.clone))
|
119
|
+
normalize_domain(add_project_scoping(add_environment_scoping(data.clone)))
|
109
120
|
end
|
110
121
|
|
111
122
|
def load_data
|
data/lib/whiskey_disk/rake.rb
CHANGED
@@ -13,6 +13,9 @@ namespace :deploy do
|
|
13
13
|
WhiskeyDisk.refresh_configuration if WhiskeyDisk.has_config_repo?
|
14
14
|
WhiskeyDisk.run_post_setup_hooks
|
15
15
|
WhiskeyDisk.flush
|
16
|
+
WhiskeyDisk.summarize
|
17
|
+
|
18
|
+
exit(1) unless WhiskeyDisk.success?
|
16
19
|
end
|
17
20
|
|
18
21
|
desc "Deploy now."
|
@@ -23,6 +26,9 @@ namespace :deploy do
|
|
23
26
|
WhiskeyDisk.refresh_configuration if WhiskeyDisk.has_config_repo?
|
24
27
|
WhiskeyDisk.run_post_deploy_hooks
|
25
28
|
WhiskeyDisk.flush
|
29
|
+
WhiskeyDisk.summarize
|
30
|
+
|
31
|
+
exit(1) unless WhiskeyDisk.success?
|
26
32
|
end
|
27
33
|
|
28
34
|
task :post_setup do
|
data/lib/whiskey_disk.rb
CHANGED
@@ -3,11 +3,13 @@ require File.expand_path(File.join(File.dirname(__FILE__), 'whiskey_disk', 'conf
|
|
3
3
|
class WhiskeyDisk
|
4
4
|
class << self
|
5
5
|
attr_writer :configuration
|
6
|
+
attr_reader :results
|
6
7
|
|
7
8
|
def reset
|
8
9
|
@configuration = nil
|
9
10
|
@buffer = nil
|
10
11
|
@staleness_checks = nil
|
12
|
+
@results = nil
|
11
13
|
end
|
12
14
|
|
13
15
|
def buffer
|
@@ -39,7 +41,7 @@ class WhiskeyDisk
|
|
39
41
|
end
|
40
42
|
|
41
43
|
def remote?
|
42
|
-
|
44
|
+
!! self[:domain]
|
43
45
|
end
|
44
46
|
|
45
47
|
def has_config_repo?
|
@@ -109,11 +111,48 @@ class WhiskeyDisk
|
|
109
111
|
|
110
112
|
def run(cmd)
|
111
113
|
needs(:domain)
|
112
|
-
|
114
|
+
self[:domain].each do |domain|
|
115
|
+
status = system('ssh', '-v', domain, "set -x; " + cmd)
|
116
|
+
record_result(domain, status)
|
117
|
+
end
|
113
118
|
end
|
114
119
|
|
115
120
|
def flush
|
116
|
-
|
121
|
+
return run(bundle) if remote?
|
122
|
+
record_result('local', system(bundle))
|
123
|
+
end
|
124
|
+
|
125
|
+
def record_result(domain, status)
|
126
|
+
@results ||= []
|
127
|
+
@results << { :domain => domain, :status => status }
|
128
|
+
end
|
129
|
+
|
130
|
+
def summarize
|
131
|
+
puts
|
132
|
+
puts "Results:"
|
133
|
+
if results and not results.empty?
|
134
|
+
successes = failures = total = 0
|
135
|
+
results.each do |result|
|
136
|
+
total += 1
|
137
|
+
if result[:status]
|
138
|
+
successes += 1
|
139
|
+
else
|
140
|
+
failures += 1
|
141
|
+
end
|
142
|
+
|
143
|
+
puts "#{result[:domain]} => #{result[:status] ? 'succeeded' : 'failed'}."
|
144
|
+
end
|
145
|
+
puts "Total: #{total} deployment#{total == 1 ? '' : 's'}, " +
|
146
|
+
"#{successes} success#{successes == 1 ? '' : 'es'}, " +
|
147
|
+
"#{failures} failure#{failures == 1 ? '' : 's'}."
|
148
|
+
else
|
149
|
+
puts "No deployments to report."
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def success?
|
154
|
+
return true if !results or results.empty?
|
155
|
+
results.all? {|result| result[:status] }
|
117
156
|
end
|
118
157
|
|
119
158
|
def if_file_present(path, cmd)
|
@@ -15,6 +15,10 @@ def build_temp_dir
|
|
15
15
|
Dir.mktmpdir
|
16
16
|
end
|
17
17
|
|
18
|
+
def write_config_file(data)
|
19
|
+
File.open(@config_file, 'w') { |f| f.puts YAML.dump(data) }
|
20
|
+
end
|
21
|
+
|
18
22
|
describe WhiskeyDisk::Config do
|
19
23
|
describe 'when computing the environment name' do
|
20
24
|
it 'should return false when there is no ENV["to"] setting' do
|
@@ -106,53 +110,53 @@ describe WhiskeyDisk::Config do
|
|
106
110
|
end
|
107
111
|
|
108
112
|
it 'should fail if the configuration file does not define data for this environment' do
|
109
|
-
|
113
|
+
write_config_file('foo' => { 'production' => { 'a' => 'b'} })
|
110
114
|
lambda { WhiskeyDisk::Config.fetch }.should.raise
|
111
115
|
end
|
112
116
|
|
113
117
|
it 'should return the configuration yaml file data for this environment as a hash' do
|
114
118
|
staging = { 'foo' => 'bar', 'repository' => 'xyzzy' }
|
115
|
-
|
119
|
+
write_config_file('foo' => { 'production' => { 'repository' => 'b'}, 'staging' => staging })
|
116
120
|
result = WhiskeyDisk::Config.fetch
|
117
121
|
staging.each_pair do |k,v|
|
118
122
|
result[k].should == v
|
119
123
|
end
|
120
124
|
end
|
121
|
-
|
125
|
+
|
122
126
|
it 'should not include configuration information for other environments in the returned hash' do
|
123
127
|
staging = { 'foo' => 'bar', 'baz' => 'xyzzy' }
|
124
|
-
|
128
|
+
write_config_file('production' => { 'repository' => 'c', 'a' => 'b'}, 'staging' => staging)
|
125
129
|
WhiskeyDisk::Config.fetch['a'].should.be.nil
|
126
130
|
end
|
127
131
|
|
128
132
|
it 'should include the environment in the hash' do
|
129
133
|
staging = { 'foo' => 'bar', 'baz' => 'xyzzy' }
|
130
|
-
|
134
|
+
write_config_file('foo' => { 'production' => { 'repository' => 'b'}, 'staging' => staging })
|
131
135
|
WhiskeyDisk::Config.fetch['environment'].should == 'staging'
|
132
136
|
end
|
133
137
|
|
134
138
|
it 'should not allow overriding the environment in the configuration file' do
|
135
139
|
staging = { 'foo' => 'bar', 'repository' => 'xyzzy', 'environment' => 'production' }
|
136
|
-
|
140
|
+
write_config_file('foo' => { 'production' => { 'repository' => 'b'}, 'staging' => staging })
|
137
141
|
WhiskeyDisk::Config.fetch['environment'].should == 'staging'
|
138
142
|
end
|
139
143
|
|
140
144
|
it 'should include the project handle in the hash' do
|
141
145
|
staging = { 'foo' => 'bar', 'repository' => 'xyzzy' }
|
142
|
-
|
146
|
+
write_config_file('foo' => { 'production' => { 'repository' => 'b'}, 'staging' => staging })
|
143
147
|
WhiskeyDisk::Config.fetch['project'].should == 'foo'
|
144
148
|
end
|
145
149
|
|
146
150
|
it 'should not allow overriding the project handle in the configuration file when a project root is specified' do
|
147
151
|
staging = { 'foo' => 'bar', 'repository' => 'xyzzy', 'project' => 'diskey_whisk' }
|
148
|
-
|
152
|
+
write_config_file('foo' => { 'production' => { 'repository' => 'b'}, 'staging' => staging })
|
149
153
|
WhiskeyDisk::Config.fetch['project'].should == 'foo'
|
150
154
|
end
|
151
155
|
|
152
156
|
it 'should allow overriding the project handle in the configuration file when a project root is not specified' do
|
153
157
|
ENV['to'] = @env = 'staging'
|
154
158
|
staging = { 'foo' => 'bar', 'repository' => 'xyzzy', 'project' => 'diskey_whisk' }
|
155
|
-
|
159
|
+
write_config_file('production' => { 'repository' => 'b'}, 'staging' => staging)
|
156
160
|
WhiskeyDisk::Config.fetch['project'].should == 'diskey_whisk'
|
157
161
|
end
|
158
162
|
end
|
@@ -198,16 +202,83 @@ describe WhiskeyDisk::Config do
|
|
198
202
|
end
|
199
203
|
|
200
204
|
it 'should return a normalized version of the un-YAMLized configuration data' do
|
201
|
-
|
205
|
+
write_config_file('repository' => 'x')
|
202
206
|
WhiskeyDisk::Config.load_data.should == { 'foo' => { 'bar' => { 'repository' => 'x' } } }
|
203
207
|
end
|
208
|
+
|
209
|
+
describe 'normalizing domains' do
|
210
|
+
before do
|
211
|
+
write_config_file(
|
212
|
+
'foo' => {
|
213
|
+
'bar' => { 'repository' => 'x', 'domain' => [ 'user@example.com', nil, 'foo@domain.com', '' ]},
|
214
|
+
'baz' => { 'repository' => 'x', 'domain' => [ 'bar@example.com', 'baz@domain.com' ]},
|
215
|
+
'xyz' => { 'repository' => 'x' },
|
216
|
+
'abc' => { 'repository' => 'x', 'domain' => 'what@example.com' },
|
217
|
+
'eee' => { 'repository' => 'x', 'domain' => '' }
|
218
|
+
},
|
219
|
+
'zyx' => {
|
220
|
+
'def' => { 'repository' => 'x', 'domain' => [ 'user@example.com', nil, 'foo@domain.com', '' ]},
|
221
|
+
'hij' => { 'repository' => 'x', 'domain' => [ 'bar@example.com', 'baz@domain.com' ]},
|
222
|
+
'xyz' => { 'repository' => 'x' },
|
223
|
+
'abc' => { 'repository' => 'x', 'domain' => 'what@example.com' },
|
224
|
+
'eee' => { 'repository' => 'x', 'domain' => '' }
|
225
|
+
}
|
226
|
+
)
|
227
|
+
end
|
228
|
+
|
229
|
+
describe 'and no domain has been specified' do
|
230
|
+
it 'should leave the domain as nil' do
|
231
|
+
WhiskeyDisk::Config.load_data['foo']['xyz']['domain'].should.be.nil
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'should handle nil domains across all projects and targets' do
|
235
|
+
WhiskeyDisk::Config.load_data['zyx']['xyz']['domain'].should.be.nil
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
describe 'and a single domain has been specified' do
|
240
|
+
it 'should return domain as nil if the specified domain was empty' do
|
241
|
+
WhiskeyDisk::Config.load_data['foo']['eee']['domain'].should.be.nil
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'should handle empty specified domains across all projects and targets' do
|
245
|
+
WhiskeyDisk::Config.load_data['zyx']['eee']['domain'].should.be.nil
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'should return domain as a single list of the specified domain if the specified domain was not empty' do
|
249
|
+
WhiskeyDisk::Config.load_data['foo']['abc']['domain'].should == ['what@example.com']
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'should handle single specified domains across all projects and targets' do
|
253
|
+
WhiskeyDisk::Config.load_data['zyx']['abc']['domain'].should == ['what@example.com']
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
describe 'and a list of domains was specified' do
|
258
|
+
it 'should return the list of domains' do
|
259
|
+
WhiskeyDisk::Config.load_data['foo']['baz']['domain'].should == [ 'bar@example.com', 'baz@domain.com' ]
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'should handle lists of domains across all projects and targets' do
|
263
|
+
WhiskeyDisk::Config.load_data['zyx']['hij']['domain'].should == [ 'bar@example.com', 'baz@domain.com' ]
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'should remove any blank or nil domains from the list' do
|
267
|
+
WhiskeyDisk::Config.load_data['foo']['bar']['domain'].should == ['user@example.com', 'foo@domain.com' ]
|
268
|
+
end
|
269
|
+
|
270
|
+
it 'should handle cleaning up blanks and nils across all projects and targets' do
|
271
|
+
WhiskeyDisk::Config.load_data['zyx']['def']['domain'].should == ['user@example.com', 'foo@domain.com' ]
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
204
275
|
end
|
205
276
|
|
206
277
|
describe 'normalizing YAML data from the configuration file' do
|
207
278
|
before do
|
208
279
|
ENV['to'] = @env = 'foo:staging'
|
209
280
|
|
210
|
-
@bare_data = { 'repository' => 'git://foo/bar.git', 'domain' => 'ogc@ogtastic.com' }
|
281
|
+
@bare_data = { 'repository' => 'git://foo/bar.git', 'domain' => ['ogc@ogtastic.com'] }
|
211
282
|
@env_data = { 'staging' => @bare_data }
|
212
283
|
@proj_data = { 'foo' => @env_data }
|
213
284
|
end
|
@@ -25,20 +25,23 @@ describe 'rake tasks' do
|
|
25
25
|
:update_configuration_repository_checkout,
|
26
26
|
:refresh_configuration,
|
27
27
|
:run_post_setup_hooks,
|
28
|
-
:flush
|
28
|
+
:flush,
|
29
|
+
:summarize
|
29
30
|
].each do |meth|
|
30
|
-
WhiskeyDisk.stub!(meth)
|
31
|
+
WhiskeyDisk.stub!(meth)
|
31
32
|
end
|
33
|
+
|
34
|
+
WhiskeyDisk.stub!(:success?).and_return(true)
|
32
35
|
end
|
33
36
|
|
34
37
|
it 'should make changes on the specified domain when a domain is specified' do
|
35
|
-
WhiskeyDisk.configuration = { 'domain' => 'some domain' }
|
38
|
+
WhiskeyDisk.configuration = { 'domain' => [ 'some domain' ] }
|
36
39
|
@rake["deploy:setup"].invoke
|
37
40
|
WhiskeyDisk.should.be.remote
|
38
41
|
end
|
39
42
|
|
40
43
|
it 'should make changes on the local system when no domain is specified' do
|
41
|
-
WhiskeyDisk.configuration = { 'domain' =>
|
44
|
+
WhiskeyDisk.configuration = { 'domain' => nil }
|
42
45
|
WhiskeyDisk.should.not.be.remote
|
43
46
|
end
|
44
47
|
|
@@ -126,6 +129,20 @@ describe 'rake tasks' do
|
|
126
129
|
WhiskeyDisk.should.receive(:flush)
|
127
130
|
@rake["deploy:setup"].invoke
|
128
131
|
end
|
132
|
+
|
133
|
+
it 'should summarize the results of the setup run' do
|
134
|
+
WhiskeyDisk.should.receive(:summarize)
|
135
|
+
@rake["deploy:setup"].invoke
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should not exit in error if all setup runs were successful' do
|
139
|
+
lambda { @rake["deploy:setup"].invoke }.should.not.raise(SystemExit)
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should exit in error if some setup run was unsuccessful' do
|
143
|
+
WhiskeyDisk.stub!(:success?).and_return(false)
|
144
|
+
lambda { @rake["deploy:setup"].invoke }.should.raise(SystemExit)
|
145
|
+
end
|
129
146
|
end
|
130
147
|
|
131
148
|
describe 'deploy:now' do
|
@@ -137,14 +154,17 @@ describe 'rake tasks' do
|
|
137
154
|
:update_configuration_repository_checkout,
|
138
155
|
:refresh_configuration,
|
139
156
|
:run_post_deploy_hooks,
|
140
|
-
:flush
|
157
|
+
:flush,
|
158
|
+
:summarize
|
141
159
|
].each do |meth|
|
142
160
|
WhiskeyDisk.stub!(meth)
|
143
161
|
end
|
162
|
+
|
163
|
+
WhiskeyDisk.stub!(:success?).and_return(true)
|
144
164
|
end
|
145
165
|
|
146
166
|
it 'should make changes on the specified domain when a domain is specified' do
|
147
|
-
WhiskeyDisk.configuration = { 'domain' => 'some domain'}
|
167
|
+
WhiskeyDisk.configuration = { 'domain' => [ 'some domain' ]}
|
148
168
|
@rake["deploy:now"].invoke
|
149
169
|
WhiskeyDisk.should.be.remote
|
150
170
|
end
|
@@ -202,6 +222,20 @@ describe 'rake tasks' do
|
|
202
222
|
WhiskeyDisk.should.receive(:flush)
|
203
223
|
@rake["deploy:now"].invoke
|
204
224
|
end
|
225
|
+
|
226
|
+
it 'should summarize the results of the deployment run' do
|
227
|
+
WhiskeyDisk.should.receive(:summarize)
|
228
|
+
@rake["deploy:now"].invoke
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'should not exit in error if all deployment runs were successful' do
|
232
|
+
lambda { @rake["deploy:now"].invoke }.should.not.raise(SystemExit)
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'should exit in error if some deployment run was unsuccessful' do
|
236
|
+
WhiskeyDisk.stub!(:success?).and_return(false)
|
237
|
+
lambda { @rake["deploy:now"].invoke }.should.raise(SystemExit)
|
238
|
+
end
|
205
239
|
end
|
206
240
|
|
207
241
|
describe 'deploy:post_setup' do
|
data/spec/whiskey_disk_spec.rb
CHANGED
@@ -2,6 +2,21 @@ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper.rb'))
|
|
2
2
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'whiskey_disk'))
|
3
3
|
require 'rake'
|
4
4
|
|
5
|
+
# WhiskeyDisk subclass that allows us to test in what order ssh commands are
|
6
|
+
# issued by WhiskeyDisk.run
|
7
|
+
class TestOrderedExecution < WhiskeyDisk
|
8
|
+
class << self
|
9
|
+
def commands
|
10
|
+
@commands
|
11
|
+
end
|
12
|
+
|
13
|
+
def system(*args)
|
14
|
+
@commands ||= []
|
15
|
+
@commands << args.join(' ')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
5
20
|
describe 'requiring the main library' do
|
6
21
|
before do
|
7
22
|
Rake.application = @rake = Rake::Application.new
|
@@ -36,19 +51,19 @@ describe 'WhiskeyDisk' do
|
|
36
51
|
lambda { WhiskeyDisk.remote?(:foo) }.should.raise(ArgumentError)
|
37
52
|
end
|
38
53
|
|
39
|
-
it 'should return true if the configuration includes a non-empty domain setting' do
|
40
|
-
@parameters['domain'] = 'smeghost'
|
41
|
-
WhiskeyDisk.remote?.should == true
|
42
|
-
end
|
43
|
-
|
44
54
|
it 'should return false if the configuration includes a nil domain setting' do
|
45
55
|
@parameters['domain'] = nil
|
46
56
|
WhiskeyDisk.remote?.should == false
|
47
57
|
end
|
58
|
+
|
59
|
+
it 'should return true if the configuration includes a non-empty domain setting' do
|
60
|
+
@parameters['domain'] = ['smeghost']
|
61
|
+
WhiskeyDisk.remote?.should == true
|
62
|
+
end
|
48
63
|
|
49
|
-
it 'should return
|
50
|
-
@parameters['domain'] = ''
|
51
|
-
WhiskeyDisk.remote?.should ==
|
64
|
+
it 'should return true if the configuration includes a multiple domain settings' do
|
65
|
+
@parameters['domain'] = ['smeghost', 'faphost']
|
66
|
+
WhiskeyDisk.remote?.should == true
|
52
67
|
end
|
53
68
|
end
|
54
69
|
|
@@ -532,6 +547,7 @@ describe 'WhiskeyDisk' do
|
|
532
547
|
|
533
548
|
describe 'when running locally' do
|
534
549
|
before do
|
550
|
+
WhiskeyDisk.reset
|
535
551
|
WhiskeyDisk.configuration = { 'deploy_to' => '/path/to/main/repo' }
|
536
552
|
WhiskeyDisk.stub!(:bundle).and_return('command string')
|
537
553
|
WhiskeyDisk.stub!(:system)
|
@@ -548,6 +564,18 @@ describe 'WhiskeyDisk' do
|
|
548
564
|
WhiskeyDisk.should.receive(:system).with('command string')
|
549
565
|
WhiskeyDisk.flush
|
550
566
|
end
|
567
|
+
|
568
|
+
it 'should record a failure result when the system command fails' do
|
569
|
+
WhiskeyDisk.stub!(:system).and_return(false)
|
570
|
+
WhiskeyDisk.flush
|
571
|
+
WhiskeyDisk.results.should == [ { :domain => 'local', :status => false } ]
|
572
|
+
end
|
573
|
+
|
574
|
+
it 'should record a success result when the system command succeeds' do
|
575
|
+
WhiskeyDisk.stub!(:system).and_return(true)
|
576
|
+
WhiskeyDisk.flush
|
577
|
+
WhiskeyDisk.results.should == [ { :domain => 'local', :status => true } ]
|
578
|
+
end
|
551
579
|
end
|
552
580
|
end
|
553
581
|
|
@@ -753,6 +781,7 @@ describe 'WhiskeyDisk' do
|
|
753
781
|
|
754
782
|
describe 'when running a command string remotely' do
|
755
783
|
before do
|
784
|
+
WhiskeyDisk.reset
|
756
785
|
@domain = 'ogc@ogtastic.com'
|
757
786
|
WhiskeyDisk.configuration = { 'domain' => @domain }
|
758
787
|
WhiskeyDisk.stub!(:system)
|
@@ -770,11 +799,119 @@ describe 'WhiskeyDisk' do
|
|
770
799
|
WhiskeyDisk.configuration = {}
|
771
800
|
lambda { WhiskeyDisk.run('ls') }.should.raise
|
772
801
|
end
|
773
|
-
|
802
|
+
|
774
803
|
it 'should pass the string to ssh with verbosity enabled' do
|
775
804
|
WhiskeyDisk.should.receive(:system).with('ssh', '-v', @domain, "set -x; ls")
|
776
805
|
WhiskeyDisk.run('ls')
|
777
806
|
end
|
807
|
+
|
808
|
+
describe 'and multiple domains are specified' do
|
809
|
+
before do
|
810
|
+
@domains = [ 'ogc@ogtastic.com', 'foo@example.com' ]
|
811
|
+
end
|
812
|
+
|
813
|
+
it 'should run the command via ssh on each domain in the order specified in the configuration file' do
|
814
|
+
TestOrderedExecution.configuration = { 'domain' => @domains }
|
815
|
+
TestOrderedExecution.run('ls')
|
816
|
+
TestOrderedExecution.commands.should == [
|
817
|
+
"ssh -v ogc@ogtastic.com set -x; ls",
|
818
|
+
"ssh -v foo@example.com set -x; ls"
|
819
|
+
]
|
820
|
+
end
|
821
|
+
|
822
|
+
it 'should not fail if an ssh command fails' do
|
823
|
+
WhiskeyDisk.configuration = { 'domain' => @domains }
|
824
|
+
WhiskeyDisk.stub!(:system).with('ssh', '-v', 'ogc@ogtastic.com', 'set -x; ls').and_return(false)
|
825
|
+
lambda { WhiskeyDisk.run('ls') }.should.not.raise(RuntimeError)
|
826
|
+
end
|
827
|
+
|
828
|
+
it 'should continue to run the remaining ssh commands when an ssh fails' do
|
829
|
+
WhiskeyDisk.configuration = { 'domain' => @domains }
|
830
|
+
WhiskeyDisk.stub!(:system).with('ssh', '-v', 'ogc@ogtastic.com', 'set -x; ls').and_return(false)
|
831
|
+
WhiskeyDisk.should.receive(:system).with('ssh', '-v', 'foo@example.com', 'set -x; ls')
|
832
|
+
WhiskeyDisk.run('ls')
|
833
|
+
end
|
834
|
+
|
835
|
+
it 'should record failure and success status for issued ssh commands' do
|
836
|
+
WhiskeyDisk.configuration = { 'domain' => @domains }
|
837
|
+
WhiskeyDisk.stub!(:system).with('ssh', '-v', 'ogc@ogtastic.com', 'set -x; ls').and_return(false)
|
838
|
+
WhiskeyDisk.stub!(:system).with('ssh', '-v', 'foo@example.com', 'set -x; ls').and_return(true)
|
839
|
+
WhiskeyDisk.run('ls')
|
840
|
+
WhiskeyDisk.results.should == [ { :domain => 'ogc@ogtastic.com', :status => false },
|
841
|
+
{ :domain => 'foo@example.com', :status => true} ]
|
842
|
+
end
|
843
|
+
end
|
844
|
+
end
|
845
|
+
|
846
|
+
describe 'determining if all the deployments succeeded' do
|
847
|
+
before do
|
848
|
+
WhiskeyDisk.reset
|
849
|
+
end
|
850
|
+
|
851
|
+
it 'should work without arguments' do
|
852
|
+
lambda { WhiskeyDisk.success? }.should.not.raise(ArgumentError)
|
853
|
+
end
|
854
|
+
|
855
|
+
it 'should not allow arguments' do
|
856
|
+
lambda { WhiskeyDisk.success?(:foo) }.should.raise(ArgumentError)
|
857
|
+
end
|
858
|
+
|
859
|
+
it 'should return true if there are no results recorded' do
|
860
|
+
WhiskeyDisk.success?.should.be.true
|
861
|
+
end
|
862
|
+
|
863
|
+
it 'should return true if all recorded results have true statuses' do
|
864
|
+
WhiskeyDisk.record_result('1', true)
|
865
|
+
WhiskeyDisk.record_result('2', true)
|
866
|
+
WhiskeyDisk.record_result('3', true)
|
867
|
+
WhiskeyDisk.success?.should.be.true
|
868
|
+
end
|
869
|
+
|
870
|
+
it 'should return false if any recorded result has a false status' do
|
871
|
+
WhiskeyDisk.record_result('1', true)
|
872
|
+
WhiskeyDisk.record_result('2', false)
|
873
|
+
WhiskeyDisk.record_result('3', true)
|
874
|
+
WhiskeyDisk.success?.should.be.false
|
875
|
+
end
|
876
|
+
end
|
877
|
+
|
878
|
+
describe 'summarizing the results of a run' do
|
879
|
+
before do
|
880
|
+
WhiskeyDisk.reset
|
881
|
+
WhiskeyDisk.stub!(:puts)
|
882
|
+
end
|
883
|
+
|
884
|
+
it 'should work without arguments' do
|
885
|
+
lambda { WhiskeyDisk.summarize }.should.not.raise(ArgumentError)
|
886
|
+
end
|
887
|
+
|
888
|
+
it 'should not allow arguments' do
|
889
|
+
lambda { WhiskeyDisk.summarize(:foo) }.should.raise(ArgumentError)
|
890
|
+
end
|
891
|
+
|
892
|
+
it 'should output a no runs message when no results are recorded' do
|
893
|
+
WhiskeyDisk.should.receive(:puts).with('No deployments to report.')
|
894
|
+
WhiskeyDisk.summarize
|
895
|
+
end
|
896
|
+
|
897
|
+
describe 'and there are results recorded' do
|
898
|
+
before do
|
899
|
+
WhiskeyDisk.record_result('foo@bar.com', false)
|
900
|
+
WhiskeyDisk.record_result('ogc@ogtastic.com', true)
|
901
|
+
WhiskeyDisk.record_result('user@example.com', true)
|
902
|
+
end
|
903
|
+
|
904
|
+
it 'should output a status line for each recorded deployment run' do
|
905
|
+
WhiskeyDisk.should.receive(:puts).with('foo@bar.com => failed.')
|
906
|
+
WhiskeyDisk.should.receive(:puts).with('ogc@ogtastic.com => succeeded.')
|
907
|
+
WhiskeyDisk.should.receive(:puts).with('user@example.com => succeeded.')
|
908
|
+
WhiskeyDisk.summarize
|
909
|
+
end
|
910
|
+
|
911
|
+
it 'should output a summary line including the total runs, count of failures and count of successes.' do
|
912
|
+
WhiskeyDisk.should.receive(:puts).with('Total: 3 deployments, 2 successes, 1 failure.')
|
913
|
+
WhiskeyDisk.summarize
|
914
|
+
end
|
915
|
+
end
|
778
916
|
end
|
779
917
|
end
|
780
|
-
|
data/whiskey_disk.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{whiskey_disk}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.6.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Rick Bradley"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-12-22}
|
13
13
|
s.default_executable = %q{wd}
|
14
14
|
s.description = %q{Opinionated gem for doing fast git-based server deployments.}
|
15
15
|
s.email = %q{rick@rickbradley.com}
|
@@ -18,46 +18,47 @@ Gem::Specification.new do |s|
|
|
18
18
|
"README.markdown"
|
19
19
|
]
|
20
20
|
s.files = [
|
21
|
-
"
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
21
|
+
"CHANGELOG",
|
22
|
+
"MIT-LICENSE",
|
23
|
+
"README.markdown",
|
24
|
+
"Rakefile",
|
25
|
+
"TODO.txt",
|
26
|
+
"VERSION",
|
27
|
+
"WHY.txt",
|
28
|
+
"bin/wd",
|
29
|
+
"examples/deploy-local.yml",
|
30
|
+
"examples/deploy-multiple-remotes.yml",
|
31
|
+
"examples/deploy-staging.yml",
|
32
|
+
"examples/deploy.rake",
|
33
|
+
"examples/deploy.yml",
|
34
|
+
"init.rb",
|
35
|
+
"install.rb",
|
36
|
+
"lib/whiskey_disk.rb",
|
37
|
+
"lib/whiskey_disk/config.rb",
|
38
|
+
"lib/whiskey_disk/rake.rb",
|
39
|
+
"spec/.bacon",
|
40
|
+
"spec/init_spec.rb",
|
41
|
+
"spec/install_spec.rb",
|
42
|
+
"spec/spec_helper.rb",
|
43
|
+
"spec/wd_command_spec.rb",
|
44
|
+
"spec/whiskey_disk/config_spec.rb",
|
45
|
+
"spec/whiskey_disk/rake_spec.rb",
|
46
|
+
"spec/whiskey_disk_spec.rb",
|
47
|
+
"tasks/deploy.rake",
|
48
|
+
"whiskey_disk.gemspec"
|
47
49
|
]
|
48
50
|
s.homepage = %q{http://github.com/flogic/whiskey_disk}
|
49
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
50
51
|
s.require_paths = ["lib"]
|
51
52
|
s.rubygems_version = %q{1.3.7}
|
52
53
|
s.summary = %q{embarrassingly fast deployments.}
|
53
54
|
s.test_files = [
|
54
55
|
"spec/init_spec.rb",
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
56
|
+
"spec/install_spec.rb",
|
57
|
+
"spec/spec_helper.rb",
|
58
|
+
"spec/wd_command_spec.rb",
|
59
|
+
"spec/whiskey_disk/config_spec.rb",
|
60
|
+
"spec/whiskey_disk/rake_spec.rb",
|
61
|
+
"spec/whiskey_disk_spec.rb"
|
61
62
|
]
|
62
63
|
|
63
64
|
if s.respond_to? :specification_version then
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: whiskey_disk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 6
|
9
|
+
- 0
|
10
|
+
version: 0.6.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Rick Bradley
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-12-22 00:00:00 -05:00
|
19
19
|
default_executable: wd
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -41,7 +41,7 @@ extensions: []
|
|
41
41
|
extra_rdoc_files:
|
42
42
|
- README.markdown
|
43
43
|
files:
|
44
|
-
-
|
44
|
+
- CHANGELOG
|
45
45
|
- MIT-LICENSE
|
46
46
|
- README.markdown
|
47
47
|
- Rakefile
|
@@ -49,6 +49,8 @@ files:
|
|
49
49
|
- VERSION
|
50
50
|
- WHY.txt
|
51
51
|
- bin/wd
|
52
|
+
- examples/deploy-local.yml
|
53
|
+
- examples/deploy-multiple-remotes.yml
|
52
54
|
- examples/deploy-staging.yml
|
53
55
|
- examples/deploy.rake
|
54
56
|
- examples/deploy.yml
|
@@ -72,8 +74,8 @@ homepage: http://github.com/flogic/whiskey_disk
|
|
72
74
|
licenses: []
|
73
75
|
|
74
76
|
post_install_message:
|
75
|
-
rdoc_options:
|
76
|
-
|
77
|
+
rdoc_options: []
|
78
|
+
|
77
79
|
require_paths:
|
78
80
|
- lib
|
79
81
|
required_ruby_version: !ruby/object:Gem::Requirement
|
data/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
pkg/
|