hr_deploy 0.0.6 → 0.0.7
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 +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
|