capistrano-deploy-lock 1.0.1 → 1.0.2
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.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +26 -8
- data/capistrano-deploy-lock.gemspec +1 -1
- data/lib/capistrano/tasks/deploy-lock.rake +84 -109
- metadata +13 -18
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f14d67d1b1468ff40a1e2227e59daa326e39c271
|
4
|
+
data.tar.gz: c4e736a13150a1ca0b22b88b71fc322f267b6f26
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 216fcdfbd64f8704f9e3232f09ab98ec91d3e76a2edf70e45ef71ac7143628920bb073b0890d7ade54135884f6525357ad09ce0c49e2df7d16eef067f372377d
|
7
|
+
data.tar.gz: 7aaf7e4a12bda298f2c75c4a8445bc2cc4393e0fb1381926d90238581ee04af54a398cbb0e53cf72969e086ed05d6080d0553a9f0b5517fae867b09e17e82a0a
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2016 Maruf Hasan Bulbul
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Capistrano Deploy Lock
|
1
|
+
# Capistrano Deploy Lock 1.0.2
|
2
2
|
|
3
3
|
Deploy lock feature for Capistrano 3.4.x
|
4
4
|
|
@@ -27,18 +27,36 @@ Require in `Capfile` to use the default task:
|
|
27
27
|
require 'capistrano/deploy-lock'
|
28
28
|
```
|
29
29
|
|
30
|
-
Deploy with
|
30
|
+
Deploy with default configuration:
|
31
31
|
|
32
|
-
|
32
|
+
Just run normal capistrano command, deploy lock will work automatically.
|
33
|
+
|
34
|
+
$ cap production deploy
|
35
|
+
|
36
|
+
You will get the following tasks
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
|
38
|
+
```ruby
|
39
|
+
cap production deploy:with_lock # Deploy with custom lock
|
40
|
+
cap production deploy:lock # Lock manually (without deploy)
|
41
|
+
cap production deploy:unlock # Unlock manually
|
42
|
+
cap production deploy:unlock:force # Unlock forcefully
|
43
|
+
```
|
44
|
+
|
45
|
+
Configurable options (copy into deploy.rb), shown here with examples:
|
37
46
|
|
38
|
-
|
47
|
+
```ruby
|
48
|
+
# Deploy Lock File
|
49
|
+
# default value: File.join(shared_path, "deploy-lock.yml")
|
50
|
+
set :deploy_lock_file, -> { File.join(shared_path, "deploy-lock.yml") }
|
39
51
|
|
40
|
-
|
52
|
+
# Deploy Lock Roles
|
53
|
+
# default value: :app ; use array for multiple roles
|
54
|
+
set :deploy_lock_roles, -> { :app }
|
41
55
|
|
56
|
+
# Deploy lock expiry (in second)
|
57
|
+
# Default 15 minutes
|
58
|
+
set :default_lock_expiry, (15 * 60)
|
59
|
+
```
|
42
60
|
|
43
61
|
## Contributing
|
44
62
|
|
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "capistrano-deploy-lock"
|
7
|
-
spec.version = "1.0.
|
7
|
+
spec.version = "1.0.2"
|
8
8
|
spec.author = "Maruf Hasan Bulbul"
|
9
9
|
spec.email = "mhb.cse@gmail.com"
|
10
10
|
spec.summary = %q{Deploy lock feature for Capistrano 3.4.x}
|
@@ -1,6 +1,5 @@
|
|
1
1
|
set :deploy_lock_file, -> { File.join(shared_path, "deploy-lock.yml") }
|
2
2
|
set :deploy_lock_roles, -> { :app }
|
3
|
-
set :deploy_lock_rack_env, -> { fetch(:rails_env) == "development" ? "development" : "deployment" }
|
4
3
|
set :default_lock_expiry, (15 * 60)
|
5
4
|
set :deploy_lock, false
|
6
5
|
set :lock_message, nil
|
@@ -10,139 +9,115 @@ namespace :deploy do
|
|
10
9
|
|
11
10
|
desc "Deploy with a custom deploy lock"
|
12
11
|
task :with_lock do
|
13
|
-
|
14
|
-
|
15
|
-
invoke 'deploy:lock'
|
16
|
-
invoke 'deploy'
|
17
|
-
end
|
18
|
-
end
|
12
|
+
invoke 'deploy:lock'
|
13
|
+
invoke 'deploy'
|
19
14
|
end
|
20
15
|
|
21
16
|
desc "Set deploy lock with a custom lock message and expiry time"
|
22
17
|
task :lock do
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
while fetch(:lock_expiry).nil?
|
30
|
-
set :expire_after, ask('minutes of expiry', 'optional', echo: true)
|
31
|
-
expire_after = fetch(:expire_after)
|
18
|
+
set :custom_deploy_lock, true
|
19
|
+
set :lock_message, ask('lock message', '', echo: true)
|
20
|
+
|
21
|
+
while fetch(:lock_expiry).nil?
|
22
|
+
set :expire_after, ask('minutes of expiry', 'optional', echo: true)
|
23
|
+
expire_after = fetch(:expire_after)
|
32
24
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
end
|
25
|
+
if expire_after == "optional"
|
26
|
+
# Never expire an explicit lock if no time given
|
27
|
+
set :lock_expiry, false
|
28
|
+
puts colorize("Lock will never expire automatically.", color: 33)
|
29
|
+
else
|
30
|
+
unless expire_after.to_i == 0
|
31
|
+
set :lock_expiry, (Time.now + expire_after.to_i * 60).utc
|
32
|
+
puts colorize("Expire after #{fetch(:expire_after)} minutes", color: 33)
|
33
|
+
else
|
34
|
+
puts colorize("'#{expire_after}' is not valid input. Please try again.")
|
45
35
|
end
|
46
|
-
|
47
|
-
invoke 'deploy:create_lock'
|
48
36
|
end
|
49
37
|
end
|
38
|
+
|
39
|
+
invoke 'deploy:create_lock'
|
50
40
|
end
|
51
41
|
|
52
42
|
desc "Creates a lock file, so that futher deploys will be prevented"
|
53
|
-
task :create_lock do
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
next
|
59
|
-
end
|
43
|
+
task :create_lock do
|
44
|
+
if fetch(:deploy_lock)
|
45
|
+
puts colorize('Deploy lock already created.', color: 33)
|
46
|
+
next
|
47
|
+
end
|
60
48
|
|
61
|
-
|
62
|
-
|
63
|
-
|
49
|
+
if fetch(:lock_message).nil?
|
50
|
+
set :lock_message, "Deploying #{fetch(:branch)} branch in #{fetch(:rails_env)}"
|
51
|
+
end
|
64
52
|
|
65
|
-
|
66
|
-
|
67
|
-
|
53
|
+
if fetch(:lock_expiry).nil?
|
54
|
+
set :lock_expiry, (Time.now + fetch(:default_lock_expiry)).utc
|
55
|
+
end
|
68
56
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
57
|
+
deploy_lock_data = {
|
58
|
+
created_at: Time.now.utc,
|
59
|
+
username: ENV['USER'],
|
60
|
+
expire_at: fetch(:lock_expiry),
|
61
|
+
message: fetch(:lock_message).to_s,
|
62
|
+
custom: !!fetch(:custom_deploy_lock)
|
63
|
+
}
|
76
64
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
end
|
65
|
+
write_deploy_lock(deploy_lock_data)
|
66
|
+
|
67
|
+
set :deploy_lock, deploy_lock_data
|
81
68
|
end
|
82
69
|
|
83
70
|
desc "Checks for a deploy lock. If present, deploy is aborted and message is displayed. Any expired locks are deleted."
|
84
|
-
task :check_lock do
|
85
|
-
|
86
|
-
|
87
|
-
# Don't check the lock if we just created it
|
88
|
-
next if fetch(:deploy_lock)
|
71
|
+
task :check_lock do
|
72
|
+
# Don't check the lock if we just created it
|
73
|
+
next if fetch(:deploy_lock)
|
89
74
|
|
90
|
-
|
75
|
+
fetch_deploy_lock
|
91
76
|
|
92
|
-
|
93
|
-
|
77
|
+
# Return if no lock
|
78
|
+
next unless fetch(:deploy_lock)
|
94
79
|
|
95
|
-
|
80
|
+
deploy_lock = fetch(:deploy_lock)
|
96
81
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
82
|
+
if deploy_lock[:expire_at] && deploy_lock[:expire_at] < Time.now
|
83
|
+
remove_deploy_lock
|
84
|
+
next
|
85
|
+
end
|
101
86
|
|
102
|
-
|
103
|
-
|
87
|
+
# Check if lock is a custom lock
|
88
|
+
set :custom_deploy_lock, deploy_lock[:custom]
|
104
89
|
|
105
|
-
|
106
|
-
|
90
|
+
# Unexpired lock is present, so display the lock message
|
91
|
+
puts message(fetch(:application), fetch(:stage), deploy_lock)
|
107
92
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
end
|
115
|
-
puts
|
116
|
-
else
|
117
|
-
exit 1
|
118
|
-
end
|
93
|
+
# Don't raise exception if current user owns the lock, and lock has an expiry time.
|
94
|
+
# Just sleep for a few seconds so they have a chance to cancel the deploy with Ctrl-C
|
95
|
+
if deploy_lock[:expire_at] && deploy_lock[:username] == ENV['USER']
|
96
|
+
10.downto(1) do |i|
|
97
|
+
Kernel.print "\r\e[0;33mDeploy lock was created by you (#{ENV['USER']}). Continuing deploy in #{i}...\e[0m"
|
98
|
+
sleep 1
|
119
99
|
end
|
100
|
+
puts
|
101
|
+
else
|
102
|
+
exit 1
|
120
103
|
end
|
121
104
|
end
|
122
105
|
|
123
106
|
namespace :unlock do
|
124
107
|
desc "Unlocks the server for deployment"
|
125
108
|
task :default do
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
remove_deploy_lock
|
133
|
-
puts colorize("Deploy unlocked.", color: 32)
|
134
|
-
end
|
135
|
-
end
|
109
|
+
# Don't automatically remove custom deploy locks created by deploy:lock task
|
110
|
+
if fetch(:custom_deploy_lock)
|
111
|
+
puts colorize('Not removing custom deploy lock.', color: 33)
|
112
|
+
else
|
113
|
+
remove_deploy_lock
|
114
|
+
puts colorize("Deploy unlocked.", color: 32)
|
136
115
|
end
|
137
116
|
end
|
138
117
|
|
139
118
|
task :force do
|
140
|
-
|
141
|
-
|
142
|
-
remove_deploy_lock
|
143
|
-
puts colorize("Deploy unlocked.", color: 32)
|
144
|
-
end
|
145
|
-
end
|
119
|
+
remove_deploy_lock
|
120
|
+
puts colorize("Deploy unlocked.", color: 32)
|
146
121
|
end
|
147
122
|
end
|
148
123
|
|
@@ -170,26 +145,26 @@ def fetch_deploy_lock
|
|
170
145
|
# Check all matching servers for a deploy lock.
|
171
146
|
on roles(fetch(:deploy_lock_roles)).to_a, in: :parallel do |host|
|
172
147
|
if test("[ -f #{fetch(:deploy_lock_file)} ]")
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
set :deploy_lock, YAML.load(output)
|
179
|
-
next
|
180
|
-
end
|
148
|
+
output = capture "cat #{fetch(:deploy_lock_file)}"
|
149
|
+
set :deploy_lock, YAML.load(output)
|
150
|
+
else
|
151
|
+
# no deploy lock was found on server
|
152
|
+
next
|
181
153
|
end
|
182
154
|
end
|
183
155
|
end
|
184
156
|
end
|
185
157
|
|
186
158
|
def write_deploy_lock(deploy_lock)
|
187
|
-
|
188
|
-
|
159
|
+
on roles(fetch(:deploy_lock_roles)), in: :parallel do |host|
|
160
|
+
upload! StringIO.new(deploy_lock.to_yaml), fetch(:deploy_lock_file)
|
161
|
+
end
|
189
162
|
end
|
190
163
|
|
191
164
|
def remove_deploy_lock
|
192
|
-
|
165
|
+
on roles(fetch(:deploy_lock_roles)), in: :parallel do |host|
|
166
|
+
execute :rm, "-f", fetch(:deploy_lock_file)
|
167
|
+
end
|
193
168
|
set :deploy_lock, nil
|
194
169
|
set :deploy_lock_removed, true
|
195
170
|
end
|
metadata
CHANGED
@@ -1,46 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano-deploy-lock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Maruf Hasan Bulbul
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2016-
|
11
|
+
date: 2016-03-07 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: capistrano
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '3.4'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '3.4'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - ">="
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '10.0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - ">="
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '10.0'
|
46
41
|
description: Lock deploy when deployment is running or custom lock to prevent further
|
@@ -50,8 +45,9 @@ executables: []
|
|
50
45
|
extensions: []
|
51
46
|
extra_rdoc_files: []
|
52
47
|
files:
|
53
|
-
- .gitignore
|
48
|
+
- ".gitignore"
|
54
49
|
- Gemfile
|
50
|
+
- LICENSE
|
55
51
|
- README.md
|
56
52
|
- Rakefile
|
57
53
|
- capistrano-deploy-lock.gemspec
|
@@ -60,26 +56,25 @@ files:
|
|
60
56
|
- lib/capistrano/tasks/deploy-lock.rake
|
61
57
|
homepage: https://github.com/maruf-freelancer/capistrano-deploy-lock
|
62
58
|
licenses: []
|
59
|
+
metadata: {}
|
63
60
|
post_install_message:
|
64
61
|
rdoc_options: []
|
65
62
|
require_paths:
|
66
63
|
- lib
|
67
64
|
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
-
none: false
|
69
65
|
requirements:
|
70
|
-
- -
|
66
|
+
- - ">="
|
71
67
|
- !ruby/object:Gem::Version
|
72
68
|
version: 1.9.3
|
73
69
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
70
|
requirements:
|
76
|
-
- -
|
71
|
+
- - ">="
|
77
72
|
- !ruby/object:Gem::Version
|
78
73
|
version: '0'
|
79
74
|
requirements: []
|
80
75
|
rubyforge_project:
|
81
|
-
rubygems_version:
|
76
|
+
rubygems_version: 2.4.8
|
82
77
|
signing_key:
|
83
|
-
specification_version:
|
78
|
+
specification_version: 4
|
84
79
|
summary: Deploy lock feature for Capistrano 3.4.x
|
85
80
|
test_files: []
|