Class: Amitree::HerokuClient
- Inherits:
-
Object
- Object
- Amitree::HerokuClient
show all
- Defined in:
- lib/amitree/heroku_client.rb
Defined Under Namespace
Classes: Error, PostDeploymentError
Instance Method Summary
collapse
Constructor Details
#initialize(api_key, staging_app_name, production_app_name) ⇒ HerokuClient
Returns a new instance of HerokuClient.
14
15
16
17
18
19
20
|
# File 'lib/amitree/heroku_client.rb', line 14
def initialize(api_key, staging_app_name, production_app_name)
@api_key = api_key
@heroku = PlatformAPI.connect(api_key)
@staging_app_name = staging_app_name
@production_app_name = production_app_name
@promoted_release_regexp = /Promote #{@staging_app_name} v(\d+)/
end
|
Instance Method Details
#current_production_release ⇒ Object
30
31
32
|
# File 'lib/amitree/heroku_client.rb', line 30
def current_production_release
get_releases(@production_app_name).to_a.last
end
|
#db_migrate_on_production(options = {}, attempts = 0) ⇒ Object
77
78
79
80
81
82
83
84
85
86
87
88
89
|
# File 'lib/amitree/heroku_client.rb', line 77
def db_migrate_on_production(options={}, attempts=0)
begin
tasks = Array(options[:rake_prepend]) + %w(db:migrate db:seed) + Array(options[:rake])
heroku_run @production_app_name, "rake #{tasks.join(' ')}"
rescue => e
if attempts < 2
db_migrate_on_production(options, attempts+1)
raise PostDeploymentError if attempts == 0
else
raise e
end
end
end
|
#deploy_to_production(staging_release, options = {}) ⇒ Object
59
60
61
62
63
64
65
66
67
|
# File 'lib/amitree/heroku_client.rb', line 59
def deploy_to_production(staging_release, options={})
staging_release_version = staging_release['version']
slug = staging_slug(staging_release_version)
puts "Deploying slug to production: #{slug}"
unless options[:dry_run]
@heroku.release.create(@production_app_name, {'slug' => slug, 'description' => "Promote #{@staging_app_name} v#{staging_release_version}"})
db_migrate_on_production(options)
end
end
|
#get_production_commit(release) ⇒ Object
26
27
28
|
# File 'lib/amitree/heroku_client.rb', line 26
def get_production_commit(release)
@heroku.slug.info(@production_app_name, release['slug']['id'])['commit']
end
|
#get_staging_commit(release) ⇒ Object
22
23
24
|
# File 'lib/amitree/heroku_client.rb', line 22
def get_staging_commit(release)
@heroku.slug.info(@staging_app_name, release['slug']['id'])['commit']
end
|
34
35
36
|
# File 'lib/amitree/heroku_client.rb', line 34
def last_promoted_production_release
get_releases(@production_app_name).to_a.reverse.detect{|release| promoted_from_staging?(release)} or raise Error.new "Can't find a production release that was promoted from staging!"
end
|
45
46
47
|
# File 'lib/amitree/heroku_client.rb', line 45
def promoted_from_staging?(release)
release['description'] =~ @promoted_release_regexp
end
|
#review_app_info(branch_name) ⇒ Object
95
96
97
98
99
100
101
102
103
104
|
# File 'lib/amitree/heroku_client.rb', line 95
def review_app_info(branch_name)
pipeline_id = @heroku.pipeline_coupling.info_by_app(@staging_app_name)['pipeline']['id']
review_apps = connection.get("https://api.heroku.com/pipelines/#{pipeline_id}/review-apps").body
review_apps
.select { |review_app| review_app['branch'] == branch_name }
.map { |review_app| { pr_number: review_app['pr_number'], endpoint: @heroku.app.info(review_app['app']['id'])['web_url'].chomp('/') } }
end
|
#staging_release_version(production_release) ⇒ Object
38
39
40
41
42
43
|
# File 'lib/amitree/heroku_client.rb', line 38
def staging_release_version(production_release)
unless production_release['description'] =~ @promoted_release_regexp
raise Error.new "Production release was not promoted from staging: #{production_release['description']}"
end
$1.to_i
end
|
#staging_releases_since(production_release) ⇒ Object
49
50
51
52
53
54
55
56
57
|
# File 'lib/amitree/heroku_client.rb', line 49
def staging_releases_since(production_release)
staging_release_version = self.staging_release_version(production_release)
staging_releases = get_releases(@staging_app_name).to_a
index = staging_releases.index { |release| release['version'] == staging_release_version }
if index.nil?
raise Error.new "Could not find staging release #{staging_release_version}"
end
staging_releases.slice(index+1, staging_releases.length)
end
|
#staging_slug(staging_release_version) ⇒ Object
69
70
71
72
73
74
75
|
# File 'lib/amitree/heroku_client.rb', line 69
def staging_slug(staging_release_version)
unless staging_release_version.is_a?(Fixnum)
raise Error.new "Unexpected release version: #{staging_release_version}"
end
result = @heroku.release.info(@staging_app_name, staging_release_version)
result['slug']['id'] || raise(Error.new("Could not find slug in API response: #{result.inspect}"))
end
|
#version(release) ⇒ Object
91
92
93
|
# File 'lib/amitree/heroku_client.rb', line 91
def version(release)
"v#{release['version']}"
end
|