hr_deploy 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/hr_deploy/config_handler.rb +15 -1
- data/lib/hr_deploy/deployer.rb +66 -1
- data/lib/hr_deploy/target.rb +2 -0
- data/lib/hr_deploy/tasks/enable_maintenance_task.rb +1 -0
- data/lib/hr_deploy/tasks/open_app_task.rb +81 -0
- data/lib/hr_deploy/tasks/push_code_task.rb +1 -0
- data/lib/hr_deploy/tasks/task.rb +15 -1
- data/lib/hr_deploy/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bce644d0caddde4560e698e8995029f32da4976d
|
4
|
+
data.tar.gz: aeb328b6b9cec1f7a210f95b4c9fb9b4b6069b3b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13eb8c7a328d864f9e8db2bb7827e4c59ccc0e5be946232c4131320c4fee275c472c37a89db5bf7be6f3b89bc32d700ff086dce86563e8eff0d19b81f7679d29
|
7
|
+
data.tar.gz: f8cca7377f6ffa1ad386a96acd9a859c1d76f8ddb1ba0ca1ac7fbf547c0b7e59bcfa5aee0041d8737f197ed741d26f8eb38830602b16a2c6b4fcb6660aadaed8
|
@@ -60,6 +60,13 @@ module HR_Deploy
|
|
60
60
|
# when you execute 'hr_deploy deploy' without arguments.
|
61
61
|
:default: true
|
62
62
|
|
63
|
+
# URL to open after deploy is complete. If a 503 (maintenance) or no
|
64
|
+
# response is returned for 5 seconds, URL will be retried for a total
|
65
|
+
# time of up to a minute. If this is set, user perceived downtime will
|
66
|
+
# be calculated. Wrap in quotes and provide the protocol, e.g. 'http://'
|
67
|
+
# or 'https://'. Optional, delete to skip opening the app after the deploy.
|
68
|
+
:app_url: 'http://app'
|
69
|
+
|
63
70
|
# Example of another target, feel free to delete or modify.
|
64
71
|
- :production:
|
65
72
|
:description: Production
|
@@ -236,6 +243,12 @@ module HR_Deploy
|
|
236
243
|
return false
|
237
244
|
end
|
238
245
|
|
246
|
+
when :app_url
|
247
|
+
unless value.instance_of?(String)
|
248
|
+
self.error = 'App URL should be a string'
|
249
|
+
return false
|
250
|
+
end
|
251
|
+
|
239
252
|
else
|
240
253
|
self.error = "Option unknown: #{option}"
|
241
254
|
return false
|
@@ -274,7 +287,8 @@ module HR_Deploy
|
|
274
287
|
backup_db: options[:backup_db],
|
275
288
|
maintenance: options[:maintenance],
|
276
289
|
default: options[:default],
|
277
|
-
s3_asset_sync: options[:s3_asset_sync]
|
290
|
+
s3_asset_sync: options[:s3_asset_sync],
|
291
|
+
app_url: options[:app_url])
|
278
292
|
else
|
279
293
|
# Only target name was given, 'options' hash is nil
|
280
294
|
HR_Deploy::Target.new(name: name)
|
data/lib/hr_deploy/deployer.rb
CHANGED
@@ -13,6 +13,7 @@ require 'hr_deploy/tasks/precompile_assets_task.rb'
|
|
13
13
|
require 'hr_deploy/tasks/push_code_task.rb'
|
14
14
|
require 'hr_deploy/tasks/migrate_db_task.rb'
|
15
15
|
require 'hr_deploy/tasks/restart_task.rb'
|
16
|
+
require 'hr_deploy/tasks/open_app_task.rb'
|
16
17
|
|
17
18
|
module HR_Deploy
|
18
19
|
|
@@ -196,6 +197,10 @@ module HR_Deploy
|
|
196
197
|
tasks_to_run << HR_Deploy::DisableMaintenanceTask.new(target: target, confirm: confirm, dry_run: dry_run)
|
197
198
|
end
|
198
199
|
|
200
|
+
if target.app_url
|
201
|
+
tasks_to_run << HR_Deploy::OpenAppTask.new(target: target, dry_run: dry_run)
|
202
|
+
end
|
203
|
+
|
199
204
|
if target.pinging_interaction?
|
200
205
|
tasks_to_run << HR_Deploy::EnablePingerTask.new(target: target, confirm: confirm, dry_run: dry_run)
|
201
206
|
end
|
@@ -249,14 +254,36 @@ module HR_Deploy
|
|
249
254
|
def deploy_succeeded
|
250
255
|
if dry_run
|
251
256
|
print_deploy_successful 'Dry run complete'
|
257
|
+
|
252
258
|
else
|
253
|
-
print_deploy_successful "Deploy complete in #{(Time.now - start_time)
|
259
|
+
print_deploy_successful "Deploy complete in #{human_time(Time.now - start_time)}"
|
260
|
+
|
261
|
+
downtime = calculate_downtime
|
262
|
+
print_deploy_successful "User perceived downtime was #{human_time(downtime)}" if downtime
|
254
263
|
end
|
255
264
|
|
256
265
|
# Execution is finished
|
257
266
|
exit 0
|
258
267
|
end
|
259
268
|
|
269
|
+
def calculate_downtime
|
270
|
+
open_app = finished_tasks.find { |task| task.class == HR_Deploy::OpenAppTask }
|
271
|
+
|
272
|
+
# Can't calculate user perceived downtime accurately if app was not opened
|
273
|
+
return nil unless open_app
|
274
|
+
|
275
|
+
enable_maintenance = finished_tasks.find { |task| task.class == HR_Deploy::EnableMaintenanceTask }
|
276
|
+
push_code = finished_tasks.find { |task| task.class == HR_Deploy::PushCodeTask }
|
277
|
+
|
278
|
+
if enable_maintenance
|
279
|
+
starting_time = enable_maintenance.start_time
|
280
|
+
else
|
281
|
+
starting_time = push_code.start_time
|
282
|
+
end
|
283
|
+
|
284
|
+
open_app.end_time - starting_time
|
285
|
+
end
|
286
|
+
|
260
287
|
def application_state(failed_task)
|
261
288
|
|
262
289
|
did_not_change = 'Application state did not change'
|
@@ -286,6 +313,8 @@ module HR_Deploy
|
|
286
313
|
unknown
|
287
314
|
when HR_Deploy::DisableMaintenanceTask
|
288
315
|
deployed
|
316
|
+
when HR_Deploy::OpenAppTask
|
317
|
+
deployed
|
289
318
|
when HR_Deploy::EnablePingerTask
|
290
319
|
deployed
|
291
320
|
when HR_Deploy::CleanNewAssetsTask
|
@@ -336,5 +365,41 @@ module HR_Deploy
|
|
336
365
|
def print_app_status(msg)
|
337
366
|
puts msg.yellow
|
338
367
|
end
|
368
|
+
|
369
|
+
def human_time(seconds)
|
370
|
+
seconds = seconds.round
|
371
|
+
minutes = seconds / 60
|
372
|
+
seconds = seconds % 60
|
373
|
+
|
374
|
+
minute_string = nil
|
375
|
+
second_string = nil
|
376
|
+
|
377
|
+
unless minutes == 0
|
378
|
+
if minutes == 1
|
379
|
+
minute_string = 'minute'
|
380
|
+
else
|
381
|
+
minute_string = 'minutes'
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
unless seconds == 0
|
386
|
+
if seconds == 1
|
387
|
+
second_string = 'second'
|
388
|
+
else
|
389
|
+
second_string = 'seconds'
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
result = ''
|
394
|
+
result += "#{minutes} #{minute_string} " unless minutes == 0
|
395
|
+
result += "#{seconds} #{second_string}" unless seconds == 0
|
396
|
+
result.strip!
|
397
|
+
|
398
|
+
if result == ''
|
399
|
+
'0 seconds'
|
400
|
+
else
|
401
|
+
result
|
402
|
+
end
|
403
|
+
end
|
339
404
|
end
|
340
405
|
end
|
data/lib/hr_deploy/target.rb
CHANGED
@@ -6,6 +6,7 @@ module HR_Deploy
|
|
6
6
|
attr_reader :new_relic_disable_pinger_url
|
7
7
|
attr_reader :new_relic_enable_pinger_url
|
8
8
|
attr_reader :description
|
9
|
+
attr_reader :app_url
|
9
10
|
|
10
11
|
def initialize(args)
|
11
12
|
|
@@ -14,6 +15,7 @@ module HR_Deploy
|
|
14
15
|
@new_relic_enable_pinger_url = args[:new_relic_enable_pinger_url]
|
15
16
|
@s3_asset_sync = args[:s3_asset_sync]
|
16
17
|
@default = args[:default]
|
18
|
+
@app_url = args[:app_url]
|
17
19
|
|
18
20
|
# Use name for description, if no description given
|
19
21
|
@description = args[:description] || name
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'hr_deploy/tasks/task'
|
2
|
+
require 'timeout'
|
3
|
+
require 'net/http'
|
4
|
+
|
5
|
+
module HR_Deploy
|
6
|
+
|
7
|
+
class OpenAppTask < HR_Deploy::Task
|
8
|
+
|
9
|
+
ONE_TRY_TIME = 5
|
10
|
+
TOTAL_TRY_TIME = 60
|
11
|
+
|
12
|
+
def run
|
13
|
+
print_stage 'Opening app...'
|
14
|
+
open_command = "heroku open --remote #{target.name}"
|
15
|
+
|
16
|
+
if dry_run?
|
17
|
+
execute_system_command(open_command)
|
18
|
+
self.success = true
|
19
|
+
return
|
20
|
+
end
|
21
|
+
|
22
|
+
ending_time = Time.now + HR_Deploy::OpenAppTask::TOTAL_TRY_TIME
|
23
|
+
|
24
|
+
until success == true || success == false
|
25
|
+
status = try_status
|
26
|
+
|
27
|
+
if status == :ok
|
28
|
+
execute_system_command(open_command)
|
29
|
+
set_end_time
|
30
|
+
self.success = true
|
31
|
+
|
32
|
+
elsif status == :fail || (status == :retry && Time.now > ending_time)
|
33
|
+
|
34
|
+
self.success = false
|
35
|
+
self.error = "Could not open app\n" +
|
36
|
+
"To open manually: #{open_command}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# :ok -> app returned a status other than 503 before timeout
|
44
|
+
# :retry -> app did not return a status before timeout or returned 503
|
45
|
+
# :fail -> an error occurred
|
46
|
+
def try_status
|
47
|
+
starting_time = Time.now
|
48
|
+
|
49
|
+
begin
|
50
|
+
Timeout::timeout(HR_Deploy::OpenAppTask::ONE_TRY_TIME) do
|
51
|
+
|
52
|
+
url = target.app_url
|
53
|
+
unless url.start_with?('https://') || url.start_with?('http://')
|
54
|
+
url = 'http://' + url
|
55
|
+
end
|
56
|
+
|
57
|
+
uri = URI.parse(url)
|
58
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
59
|
+
|
60
|
+
if url.start_with?('https://')
|
61
|
+
http.use_ssl = true
|
62
|
+
end
|
63
|
+
|
64
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
65
|
+
response = http.request(request)
|
66
|
+
|
67
|
+
if response.code == '503'
|
68
|
+
sleep(HR_Deploy::OpenAppTask::ONE_TRY_TIME - (starting_time - Time.now))
|
69
|
+
:retry
|
70
|
+
else
|
71
|
+
:ok
|
72
|
+
end
|
73
|
+
end
|
74
|
+
rescue Timeout::Error
|
75
|
+
:retry
|
76
|
+
rescue
|
77
|
+
:fail
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/hr_deploy/tasks/task.rb
CHANGED
@@ -6,6 +6,8 @@ module HR_Deploy
|
|
6
6
|
class Task
|
7
7
|
|
8
8
|
attr_reader :error
|
9
|
+
attr_reader :start_time
|
10
|
+
attr_reader :end_time
|
9
11
|
|
10
12
|
def initialize(args = {})
|
11
13
|
@target = args.fetch(:target, nil)
|
@@ -13,6 +15,8 @@ module HR_Deploy
|
|
13
15
|
@dry_run = args.fetch(:dry_run, false)
|
14
16
|
@success = nil
|
15
17
|
@error = nil
|
18
|
+
@start_time = nil
|
19
|
+
@end_time = nil
|
16
20
|
end
|
17
21
|
|
18
22
|
def successful?
|
@@ -28,8 +32,18 @@ module HR_Deploy
|
|
28
32
|
|
29
33
|
attr_reader :target
|
30
34
|
attr_writer :error
|
35
|
+
attr_writer :start_time
|
36
|
+
attr_writer :end_time
|
31
37
|
attr_accessor :success
|
32
38
|
|
39
|
+
def set_start_time
|
40
|
+
self.start_time = Time.now
|
41
|
+
end
|
42
|
+
|
43
|
+
def set_end_time
|
44
|
+
self.end_time = Time.now
|
45
|
+
end
|
46
|
+
|
33
47
|
def confirm?
|
34
48
|
!!@confirm
|
35
49
|
end
|
@@ -64,7 +78,7 @@ module HR_Deploy
|
|
64
78
|
|
65
79
|
def execute_system_command(cmd)
|
66
80
|
if dry_run?
|
67
|
-
puts
|
81
|
+
puts cmd
|
68
82
|
else
|
69
83
|
system(cmd)
|
70
84
|
end
|
data/lib/hr_deploy/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hr_deploy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dmitry Gubitskiy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Easily deploy your Rails apps to Heroku with one command, automatically
|
14
14
|
taking care of things such as checking current Heroku status, enabling maintenance
|
@@ -40,6 +40,7 @@ files:
|
|
40
40
|
- lib/hr_deploy/tasks/push_code_task.rb
|
41
41
|
- lib/hr_deploy/tasks/migrate_db_task.rb
|
42
42
|
- lib/hr_deploy/tasks/restart_task.rb
|
43
|
+
- lib/hr_deploy/tasks/open_app_task.rb
|
43
44
|
- lib/hr_deploy/version.rb
|
44
45
|
- bin/hr_deploy
|
45
46
|
homepage: https://github.com/enthrops/hr_deploy
|