heroku_rails_deploy 0.2.2 → 0.3.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
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