heroku_deployer 0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 738576c9402da6ea58a47a34b432a9d1a8447f17
4
+ data.tar.gz: 7175f54727b6e9adedd2dc4a57c100c9d600a926
5
+ SHA512:
6
+ metadata.gz: 95f00f9e747d02ababc1af63bd8065aed134cc95d023a44fb57340efad7945e184919efd44d71a0919e1edd53e6cbe362e583f4a20ecd91739127eddcfa28754
7
+ data.tar.gz: 3691d23c33927c4bc6ad34adce55c6c9f0c325b4246abf2964d7504eb311535ff59129b157fdc4f8ee3e9d25ed0669abb7ee391887fad9c945b3eeafa04b3d92
@@ -0,0 +1,28 @@
1
+ require 'octokit'
2
+
3
+ module Amitree
4
+ class GitClient
5
+ def initialize(repository, username, password)
6
+ @repository = repository
7
+ @client = Octokit::Client.new login: username, password: password
8
+ end
9
+
10
+ def commits_between(rev1, rev2)
11
+ result = @client.compare @repository, rev1, rev2
12
+ result.commits
13
+ end
14
+
15
+ def commit_messages_between(rev1, rev2)
16
+ commits_between(rev1, rev2).map(&:commit).map(&:message)
17
+ end
18
+
19
+ def stories_worked_on_between(rev1, rev2)
20
+ messages = commit_messages_between(rev1, rev2)
21
+ messages.map{|msg| msg.scan /(?<=#)\d+/}.flatten.uniq
22
+ end
23
+
24
+ def link_to(rev)
25
+ "https://github.com/#{@repository}/commit/#{rev}"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,83 @@
1
+ require 'heroku-api'
2
+ require 'heroku/new_api'
3
+ require 'rendezvous'
4
+
5
+ module Amitree
6
+ class HerokuClient
7
+ class Error < StandardError
8
+ end
9
+
10
+ def initialize(api_key, staging_app_name, production_app_name)
11
+ @heroku = Heroku::API.new(:api_key => api_key)
12
+ # We need to use the new API (not currently supported by the heroku-api gem) for deploy_to_production
13
+ @heroku_new = Heroku::NewAPI.new(:api_key => api_key)
14
+ @staging_app_name = staging_app_name
15
+ @production_app_name = production_app_name
16
+ @promoted_release_regexp = /Promote #{@staging_app_name} (v\d+)/
17
+ end
18
+
19
+ def current_production_release
20
+ get_releases(@production_app_name)[-1]
21
+ end
22
+
23
+ def last_promoted_production_release
24
+ get_releases(@production_app_name).reverse.detect{|release| promoted_from_staging?(release)} or raise Error.new "Can't find a production release that was promoted from staging!"
25
+ end
26
+
27
+ def staging_release_name(production_release)
28
+ unless production_release['descr'] =~ @promoted_release_regexp
29
+ raise Error.new "Production release was not promoted from staging: #{production_release['descr']}"
30
+ end
31
+ $1
32
+ end
33
+
34
+ def promoted_from_staging?(release)
35
+ release['descr'] =~ @promoted_release_regexp
36
+ end
37
+
38
+ def staging_releases_since(staging_release_name)
39
+ staging_releases = get_releases(@staging_app_name)
40
+ index = staging_releases.index { |release| release['name'] == staging_release_name }
41
+ if index.nil?
42
+ raise Error.new "Could not find staging release #{staging_release_name}"
43
+ end
44
+ staging_releases.slice(index+1, staging_releases.length)
45
+ end
46
+
47
+ def deploy_to_production(staging_release_name, options={})
48
+ slug = staging_slug(staging_release_name)
49
+ puts "Deploying slug to production: #{slug}"
50
+ unless options[:dry_run]
51
+ @heroku_new.post_release(@production_app_name, {'slug' => slug, 'description' => "Promote #{@staging_app_name} #{staging_release_name}"})
52
+ db_migrate_on_production
53
+ end
54
+ end
55
+
56
+ def staging_slug(staging_release_name)
57
+ unless staging_release_name =~ /\Av(\d+)\z/
58
+ raise Error.new "Unexpected release name: #{staging_release_name}"
59
+ end
60
+ result = @heroku_new.get_release(@staging_app_name, $1)
61
+ result.body['slug']['id'] || raise(Error.new("Could not find slug in API response: #{result.inspect}"))
62
+ end
63
+
64
+ def db_migrate_on_production
65
+ heroku_run(@production_app_name, 'rake db:migrate db:seed')
66
+ end
67
+
68
+ private
69
+ def get_releases(app_name)
70
+ @heroku.get_releases(app_name).body
71
+ end
72
+
73
+ def heroku_run(app_name, command)
74
+ puts "Running command on #{app_name}: #{command}..."
75
+ data = @heroku.post_ps(app_name, command, { attach: true }).body
76
+ read, write = IO.pipe
77
+ Rendezvous.start(url: data['rendezvous_url'], input: read)
78
+ read.close
79
+ write.close
80
+ puts "Done."
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,21 @@
1
+ require 'multi_json'
2
+
3
+ module Heroku
4
+ class NewAPI < API
5
+ def initialize(options={})
6
+ options[:headers] ||= {}
7
+ options[:headers]['Accept'] = 'application/vnd.heroku+json; version=3'
8
+ super(options)
9
+ end
10
+
11
+ # POST /apps/:app/releases/:release
12
+ def post_release(app, query={})
13
+ request(
14
+ :expects => 201,
15
+ :method => :post,
16
+ :path => "/apps/#{app}/releases",
17
+ :body => MultiJson.dump(query)
18
+ )
19
+ end
20
+ end
21
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: heroku_deployer
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Nick Wargnier
8
+ - Tony Novak
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-05-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '='
19
+ - !ruby/object:Gem::Version
20
+ version: 2.14.1
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '='
26
+ - !ruby/object:Gem::Version
27
+ version: 2.14.1
28
+ - !ruby/object:Gem::Dependency
29
+ name: octokit
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '='
33
+ - !ruby/object:Gem::Version
34
+ version: 2.7.1
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '='
40
+ - !ruby/object:Gem::Version
41
+ version: 2.7.1
42
+ - !ruby/object:Gem::Dependency
43
+ name: heroku-api
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '='
47
+ - !ruby/object:Gem::Version
48
+ version: 0.3.17
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '='
54
+ - !ruby/object:Gem::Version
55
+ version: 0.3.17
56
+ - !ruby/object:Gem::Dependency
57
+ name: rendezvous
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '='
61
+ - !ruby/object:Gem::Version
62
+ version: 0.0.2
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '='
68
+ - !ruby/object:Gem::Version
69
+ version: 0.0.2
70
+ - !ruby/object:Gem::Dependency
71
+ name: pivotal-tracker
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '='
75
+ - !ruby/object:Gem::Version
76
+ version: 0.5.12
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '='
82
+ - !ruby/object:Gem::Version
83
+ version: 0.5.12
84
+ description: Gem that handles automatic deployment of code to Heroku, integrating
85
+ with Pivotal Tracker and Git
86
+ email: engineering@amitree.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - lib/amitree/git_client.rb
92
+ - lib/amitree/heroku_client.rb
93
+ - lib/heroku/new_api.rb
94
+ homepage: http://rubygems.org/gems/heroku_deployer
95
+ licenses:
96
+ - MIT
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - "~>"
105
+ - !ruby/object:Gem::Version
106
+ version: '2.0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 2.2.2
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: Heroku Deployer
118
+ test_files: []