heroku_rails_deploy 0.2.2 → 0.3.0.rc0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bc3e6f646b7ef7c41f69b59029b2c1fdee7cff1c
4
- data.tar.gz: 2f6e0b9b32170b947a47980f1d671118fd5ef3cb
3
+ metadata.gz: 1aac6bef63e2d84fc55be74e10b2b9493fe153fc
4
+ data.tar.gz: 4bdd7c820d0085cb0a0960490e98adbbef42174b
5
5
  SHA512:
6
- metadata.gz: 8dbf1c200f8e9647d867a5ece168149fa2c1999d23e42842262a1f1ef76b7ab57b1f4419af1ea49d5a0724cdf213d1aafe834dc3ed8515a7a9a801f6504f023f
7
- data.tar.gz: a6c5700adc7fd2b6e1b20567896a7dfaca655440978addd2bdada60aa0999c254d42fd1ea5416711a17b05cf56da213d305b1469e3e169ba2d5ecd10310196ff
6
+ metadata.gz: aa22e648f9627077fc5f870a733d624e81ff90868289f12fe204e49677a0e90b8478c21f12ae0785d107d9c18d85fafa013d71b57ec798d6ff0d2e59ae921383
7
+ data.tar.gz: fce74dc0b5268c7df9aeac1e1eb4c06b720e332f0f615917a56e146055a5488a5371aada7c4fc1f36f20b0f3a7f9972bdbdc1af2fdd970197370ced5fa8aeb65
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # heroku_rails_deploy
2
2
 
3
+ ## v0.3.0
4
+ - Add support for Avro schema registration during deployment.
5
+ - Refuse to deploy when there are uncommitted changes.
6
+
3
7
  ## v0.2.2
4
8
  - Fixes bug in getting branch name from executing system command
5
9
 
data/README.md CHANGED
@@ -3,8 +3,9 @@
3
3
  This gem provides a simple Heroku deploy script for Rails applications. Deploys
4
4
  following the following steps:
5
5
 
6
- 1. Push code to Heroku
7
- 2. If there are pending migrations, run them and restart the Heroku dynos
6
+ 1. Push updated Avro schemas to a schema registry
7
+ 2. Push code to Heroku
8
+ 3. If there are pending migrations, run them and restart the Heroku dynos
8
9
 
9
10
  ## Installation
10
11
 
@@ -42,6 +43,8 @@ $ bin/deploy --help
42
43
  Usage: deploy [options]
43
44
  -e, --environment ENVIRONMENT The environment to deploy to. Must be in production, staging (default production)
44
45
  -r, --revision REVISION The git revision to push. (default HEAD)
46
+ --register-avro-schemas Force the registration of Avro schemas when deploying to a non-production environment.
47
+ --skip-avro-schemas Skip the registration of Avro schemas when deploying to production.
45
48
  -h, --help Show this message
46
49
  ```
47
50
 
@@ -1,14 +1,16 @@
1
1
  require 'optparse'
2
2
  require 'shellwords'
3
3
  require 'yaml'
4
+ require 'english'
4
5
 
5
6
  module HerokuRailsDeploy
6
7
  class Deployer
7
8
  PRODUCTION_BRANCH_REGEX = /\A((master)|(release\/.+)|(hotfix\/.+))\z/
9
+ PRODUCTION = 'production'.freeze
8
10
 
9
11
  attr_reader :config_file, :args
10
12
 
11
- class Options < Struct.new(:environment, :revision)
13
+ class Options < Struct.new(:environment, :revision, :register_avro_schemas, :skip_avro_schemas)
12
14
  def self.create_default(app_registry)
13
15
  new(app_registry.keys.first, 'HEAD')
14
16
  end
@@ -41,6 +43,16 @@ module HerokuRailsDeploy
41
43
  'The git revision to push. (default HEAD)') do |revision|
42
44
  options.revision = revision
43
45
  end
46
+
47
+ parser.on('--register-avro-schemas',
48
+ 'Force the registration of Avro schemas when deploying to a non-production environment.') do |register_avro_schemas|
49
+ options.register_avro_schemas = register_avro_schemas
50
+ end
51
+
52
+ parser.on('--skip-avro-schemas',
53
+ 'Skip the registration of Avro schemas when deploying to production.') do |skip_avro_schemas|
54
+ options.skip_avro_schemas = skip_avro_schemas
55
+ end
44
56
  end.parse!(args)
45
57
 
46
58
  app_name = app_registry.fetch(options.environment) do
@@ -48,9 +60,24 @@ module HerokuRailsDeploy
48
60
  "Must be in #{app_registry.keys.join(', ')}")
49
61
  end
50
62
 
51
- raise 'Only master, release or hotfix branches can be deployed to production' if options.environment == 'production' && !production_branch?(options.revision)
63
+ raise 'Only master, release or hotfix branches can be deployed to production' if production?(options) && !production_branch?(options.revision)
64
+
65
+ no_uncommitted_changes!
66
+
67
+ puts "Deploying to Heroku app #{app_name} for environment #{options.environment}"
68
+
69
+ if !options.skip_avro_schemas && (production?(options) || options.register_avro_schemas)
70
+ puts 'Checking for pending Avro schemas'
71
+ pending_schemas = list_pending_schemas(app_name)
72
+ if pending_schemas.any?
73
+ puts 'Registering Avro schemas'
74
+ register_avro_schemas!(registry_url(app_name), pending_schemas)
75
+ else
76
+ puts 'No pending Avro schemas'
77
+ end
78
+ end
52
79
 
53
- puts "Pushing code to Heroku app #{app_name} for environment #{options.environment}"
80
+ puts 'Pushing code'
54
81
  push_code(app_name, options.revision)
55
82
 
56
83
  puts 'Checking for pending migrations'
@@ -64,18 +91,29 @@ module HerokuRailsDeploy
64
91
  end
65
92
  end
66
93
 
94
+ private
95
+
96
+ def production?(options)
97
+ options.environment == PRODUCTION
98
+ end
99
+
67
100
  def production_branch?(revision)
68
101
  git_branch_name(revision).match(PRODUCTION_BRANCH_REGEX)
69
102
  end
70
103
 
104
+ def no_uncommitted_changes!
105
+ uncommitted_changes = run_command!('git status --porcelain', quiet: true)
106
+ raise "There are uncommitted changes:\n#{uncommitted_changes}" unless uncommitted_changes.blank?
107
+ end
108
+
71
109
  def push_code(app_name, revision)
72
- run_command!("git push --force git@heroku.com:#{app_name}.git #{revision}:master")
110
+ run_command!("git push --force #{app_remote(app_name)} #{revision}:master")
73
111
  end
74
112
 
75
113
  def git_branch_name(revision)
76
- branch_name = `git rev-parse --abbrev-ref #{Shellwords.escape(revision)}`.strip
77
- raise "Unable to get branch for #{revision}" unless $?.to_i == 0
78
- branch_name
114
+ run_command!("git rev-parse --abbrev-ref #{Shellwords.escape(revision)}", quiet: true).strip
115
+ rescue
116
+ raise "Unable to get branch for #{revision}"
79
117
  end
80
118
 
81
119
  def run_migrations(app_name)
@@ -91,28 +129,62 @@ module HerokuRailsDeploy
91
129
  end
92
130
 
93
131
  def run_heroku_command!(app_name, command)
94
- success = run_heroku_command(app_name, command)
95
- raise "Heroku command '#{command}' failed" unless success
132
+ run_heroku_command(app_name, command, validate: true)
133
+ rescue
134
+ raise "Heroku command '#{command}' failed"
96
135
  end
97
136
 
98
- def run_heroku_command(app_name, command)
137
+ def run_heroku_command(app_name, command, validate: nil)
99
138
  cli_command = "heroku #{command} --app #{app_name}"
100
139
  if command.start_with?('run ')
101
140
  # If we're running a shell command, return the underlying
102
141
  # shell command exit code
103
142
  cli_command << ' --exit-code'
104
143
  end
105
- run_command(cli_command)
144
+ run_command(cli_command, validate: validate)
145
+ end
146
+
147
+ def registry_url(app_name)
148
+ result = run_command!("heroku config -a #{app_name} | grep AVRO_SCHEMA_REGISTRY_URL:", quiet: true)
149
+ result.split.last
150
+ end
151
+
152
+ def register_avro_schemas!(registry_url, schemas)
153
+ cmd = "rake avro:register_schemas schemas=#{schemas.join(',')}"
154
+ run_command!("DEPLOYMENT_SCHEMA_REGISTRY_URL=#{registry_url} #{cmd}", print_command: cmd)
155
+ end
156
+
157
+ def list_pending_schemas(app_name)
158
+ changed_files(app_name).select { |filename| /\.avsc$/ =~ filename }
159
+ end
160
+
161
+ def changed_files(app_name)
162
+ run_command("git diff --name-only #{remote_commit(app_name)}..#{current_commit}", quiet: true).split("\n").map(&:strip)
163
+ end
164
+
165
+ def current_commit
166
+ run_command!("git log --pretty=format:'%H' -n 1", quiet: true)
167
+ end
168
+
169
+ def remote_commit(app_name)
170
+ run_command!("git ls-remote --heads #{app_remote(app_name)} master", quiet: true).split.first
171
+ end
172
+
173
+ def app_remote(app_name)
174
+ "git@heroku.com:#{app_name}.git"
106
175
  end
107
176
 
108
- def run_command!(command)
109
- success = run_command(command)
110
- raise "Command '#{command}' failed" unless success
177
+ def run_command!(command, print_command: nil, quiet: false)
178
+ run_command(command, print_command: print_command, quiet: quiet, validate: true)
111
179
  end
112
180
 
113
- def run_command(command)
114
- puts command
115
- Bundler.with_clean_env { system(command) }
181
+ def run_command(command, print_command: nil, validate: nil, quiet: false)
182
+ printed_command = print_command || command
183
+ puts printed_command unless quiet
184
+ output = Bundler.with_clean_env { `#{command}` }
185
+ exit_status = $CHILD_STATUS.exitstatus
186
+ raise "Command '#{printed_command}' failed" if validate && exit_status.nonzero?
187
+ output
116
188
  end
117
189
  end
118
190
  end
@@ -1,3 +1,3 @@
1
1
  module HerokuRailsDeploy
2
- VERSION = '0.2.2'.freeze
2
+ VERSION = '0.3.0.rc0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heroku_rails_deploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0.rc0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Salsify, Inc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-12 00:00:00.000000000 Z
11
+ date: 2017-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -151,12 +151,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
151
151
  version: '0'
152
152
  required_rubygems_version: !ruby/object:Gem::Requirement
153
153
  requirements:
154
- - - ">="
154
+ - - ">"
155
155
  - !ruby/object:Gem::Version
156
- version: '0'
156
+ version: 1.3.1
157
157
  requirements: []
158
158
  rubyforge_project:
159
- rubygems_version: 2.4.8
159
+ rubygems_version: 2.6.11
160
160
  signing_key:
161
161
  specification_version: 4
162
162
  summary: Simple deployment of Rails app to Heroku