recap 1.1.3 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/recap/support/capistrano_extensions.rb +27 -1
- data/lib/recap/tasks/deploy.rb +21 -1
- data/lib/recap/version.rb +1 -1
- data/spec/tasks/deploy_spec.rb +29 -6
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 001ac16e3f6040b7229222dfabd8c945be2bb1b2
|
4
|
+
data.tar.gz: f07c98d248d99f45b774f57711c9769f5d32d2bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a47f44dcf16f289d474e456a9e6a1fc512e829fe9af591bc653e7b7b50261721d74e702cf4592a8293ffc434474313e90f2a82d031dc548a083aa45017bbf1f
|
7
|
+
data.tar.gz: eeb0c99b00c97f82c194b7fda771c6d44382e18ea41fc9114c712366e29dbb7b59ffb0d6bcfe63023566baa358b4a69ecff5bec83f2a66b27b5508bcc60d2a83
|
@@ -10,7 +10,7 @@ module Recap::Support::CapistranoExtensions
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def as_app_once(command, pwd = deploy_to)
|
13
|
-
sudo "su - #{application_user} -c 'cd #{pwd} && #{command}'", once
|
13
|
+
sudo "su - #{application_user} -c 'cd #{pwd} && #{command}'", :once => true
|
14
14
|
end
|
15
15
|
|
16
16
|
# Put a string into a file as the application user
|
@@ -87,5 +87,31 @@ module Recap::Support::CapistranoExtensions
|
|
87
87
|
force_full_deploy || changed_files.detect {|p| p[0, path.length] == path}
|
88
88
|
end
|
89
89
|
|
90
|
+
def claim_lock(message)
|
91
|
+
begin
|
92
|
+
sudo "[ ! -e #{deploy_lock_file} ] && echo '#{message}' > #{deploy_lock_file}"
|
93
|
+
rescue Exception => e
|
94
|
+
abort %{
|
95
|
+
Failed to claim lock: " + capture("cat #{deploy_lock_file}"
|
96
|
+
|
97
|
+
If you think this lock no longer applies, clear it using the `deploy:unlock` task
|
98
|
+
and try again.
|
99
|
+
}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def release_lock
|
104
|
+
sudo "rm -rf #{deploy_lock_file}"
|
105
|
+
end
|
106
|
+
|
107
|
+
def transaction_with_lock(message)
|
108
|
+
on_rollback { release_lock }
|
109
|
+
transaction do
|
110
|
+
claim_lock(message)
|
111
|
+
yield
|
112
|
+
release_lock
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
90
116
|
Capistrano::Configuration.send :include, self
|
91
117
|
end
|
data/lib/recap/tasks/deploy.rb
CHANGED
@@ -52,6 +52,13 @@ module Recap::Tasks::Deploy
|
|
52
52
|
# Force a complete deploy, even if no trigger files have changed
|
53
53
|
set(:force_full_deploy, false)
|
54
54
|
|
55
|
+
# A lock file is used to ensure deployments don't overlap
|
56
|
+
set(:deploy_lock_file) { "#{deploy_to}/.recap-lock"}
|
57
|
+
|
58
|
+
# The lock file is set to include a message that can be displayed
|
59
|
+
# if claiming the lock fails
|
60
|
+
set(:deploy_lock_message) { "Deployment in progress (started #{Time.now.to_s})" }
|
61
|
+
|
55
62
|
# To authenticate with github or other git servers, it is easier (and cleaner) to forward the
|
56
63
|
# deploying user's ssh key than manage keys on deployment servers.
|
57
64
|
ssh_options[:forward_agent] = true
|
@@ -87,7 +94,7 @@ module Recap::Tasks::Deploy
|
|
87
94
|
# tags the release and restarts the application.
|
88
95
|
desc "Deploy the latest application code"
|
89
96
|
task :default do
|
90
|
-
|
97
|
+
transaction_with_lock deploy_lock_message do
|
91
98
|
top.env.set
|
92
99
|
update_code
|
93
100
|
tag
|
@@ -148,5 +155,18 @@ module Recap::Tasks::Deploy
|
|
148
155
|
task :destroy do
|
149
156
|
sudo "rm -rf #{deploy_to}"
|
150
157
|
end
|
158
|
+
|
159
|
+
# As well as locking during each deployment, locks can manually be set with `deploy:lock`. To
|
160
|
+
# use a custom lock message, do `DEPLOY_LOCK_MESSAGE="My message" cap deploy:lock`. Locking
|
161
|
+
# prevents deployments, but not other tasks.
|
162
|
+
task :lock do
|
163
|
+
claim_lock ENV['DEPLOY_LOCK_MESSAGE'] || "Manually locked at #{Time.now}"
|
164
|
+
end
|
165
|
+
|
166
|
+
# To unlock a manually set lock, or a lock that has been left behind in error, the `deploy:unlock`
|
167
|
+
# task can be used.
|
168
|
+
task :unlock do
|
169
|
+
release_lock
|
170
|
+
end
|
151
171
|
end
|
152
172
|
end
|
data/lib/recap/version.rb
CHANGED
data/spec/tasks/deploy_spec.rb
CHANGED
@@ -161,6 +161,7 @@ describe Recap::Tasks::Deploy do
|
|
161
161
|
|
162
162
|
describe 'deploy' do
|
163
163
|
it 'runs env:set, deploy:update_code, deploy:tag and then deploy:restart tasks' do
|
164
|
+
namespace.stubs(:transaction_with_lock).yields
|
164
165
|
env = stub('env')
|
165
166
|
config.stubs(:env).returns(env)
|
166
167
|
env.expects('set')
|
@@ -170,20 +171,20 @@ describe Recap::Tasks::Deploy do
|
|
170
171
|
config.find_and_execute_task('deploy')
|
171
172
|
end
|
172
173
|
|
173
|
-
it 'calls deploy:update_code task within a transaction' do
|
174
|
-
namespace.stubs(:
|
174
|
+
it 'calls deploy:update_code task within a locked transaction' do
|
175
|
+
namespace.stubs(:transaction_with_lock)
|
175
176
|
namespace.expects(:update_code).never
|
176
177
|
config.find_and_execute_task('deploy')
|
177
178
|
end
|
178
179
|
|
179
|
-
it 'calls deploy:tag task within a transaction' do
|
180
|
-
namespace.stubs(:
|
180
|
+
it 'calls deploy:tag task within a locked transaction' do
|
181
|
+
namespace.stubs(:transaction_with_lock)
|
181
182
|
namespace.expects(:tag).never
|
182
183
|
config.find_and_execute_task('deploy')
|
183
184
|
end
|
184
185
|
|
185
186
|
it 'calls restart outside the transaction' do
|
186
|
-
namespace.stubs(:
|
187
|
+
namespace.stubs(:transaction_with_lock)
|
187
188
|
namespace.expects(:restart)
|
188
189
|
config.find_and_execute_task('deploy')
|
189
190
|
end
|
@@ -242,6 +243,28 @@ describe Recap::Tasks::Deploy do
|
|
242
243
|
end
|
243
244
|
end
|
244
245
|
|
246
|
+
describe 'deploy:lock' do
|
247
|
+
it 'locks deployments with the message DEPLOY_LOCK_MESSAGE if available' do
|
248
|
+
ENV.stubs("[]").with("DEPLOY_LOCK_MESSAGE").returns("custom-message")
|
249
|
+
namespace.expects(:claim_lock).with("custom-message")
|
250
|
+
namespace.find_and_execute_task('deploy:lock')
|
251
|
+
end
|
252
|
+
|
253
|
+
it 'locks deployments with a default message if no message provided' do
|
254
|
+
now = Time.now
|
255
|
+
Time.stubs(:now).returns(now)
|
256
|
+
namespace.expects(:claim_lock).with("Manually locked at #{Time.now}")
|
257
|
+
namespace.find_and_execute_task('deploy:lock')
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
describe 'deploy:unlock' do
|
262
|
+
it 'removes any existing locks' do
|
263
|
+
namespace.expects(:release_lock)
|
264
|
+
namespace.find_and_execute_task('deploy:unlock')
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
245
268
|
describe 'deploy:restart' do
|
246
269
|
it 'does nothing (but can be overidden by other recipes)' do
|
247
270
|
namespace.expects(:run).never
|
@@ -258,4 +281,4 @@ describe Recap::Tasks::Deploy do
|
|
258
281
|
end
|
259
282
|
end
|
260
283
|
end
|
261
|
-
end
|
284
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: recap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Ward
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-08-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capistrano
|
@@ -223,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
223
223
|
version: '0'
|
224
224
|
requirements: []
|
225
225
|
rubyforge_project:
|
226
|
-
rubygems_version: 2.0.
|
226
|
+
rubygems_version: 2.0.3
|
227
227
|
signing_key:
|
228
228
|
specification_version: 4
|
229
229
|
summary: GIT based deployment recipes for Capistrano
|