heroku_tool 0.9.2 → 0.9.4

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
  SHA256:
3
- metadata.gz: 4b5e399a4542b07992fbc0e896bf8b1f6fca73cb3abf66647c0c741e013ee910
4
- data.tar.gz: b06141618a185a433edbb74786d6ea572a0079220bf22f4f6724b87a86e8ac30
3
+ metadata.gz: 87a4838bb986b0cb1c7404a967443c0ad1015718a755733fb58b7bdfd78b4e1c
4
+ data.tar.gz: 5d8e1560f6211c8cee8006c74a7dc7f6b50994dbedd43d5dc0755d939ac0c1dd
5
5
  SHA512:
6
- metadata.gz: 54d7a075669af48e1a62a59cf077ce577114e565487b1997f0bad47edb2f26c74250a82ea9b501f058ef66ec4ec4157086ba3c96aaed66f163b24c70aa2b7096
7
- data.tar.gz: ea5187d7722b88eb0cf01065ae624f65effa27457257a3e6081b22294dbc3e893a0d3d74c0cff36cbd7a38c01c51a1b68db057688c9a1fc27789fab6c8dde047
6
+ metadata.gz: 6c5aac4e33eb719b8f2ccde8b8d6d7198323cbb42f92c7a711b020919b7b59ba022a7d9e92bfc41a8d0bf2ab41d348978fac25d48d84851494c7ef95b1c46312
7
+ data.tar.gz: ee4cfec74f3d1cf448eafb606d3ee9712c200bd17b86ba8a606e79a6bfb805d4b36e82bd2b220ca40039662dbadd2de535ca8b08eca3b03c424b203f6cbed0ba
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.9.4
4
+
5
+ - `heroku:db:from_dump` restores with parallel jobs: `--jobs`, default 4 (use `--jobs 1` for the old behaviour)
6
+ - `Configuration#skip_table_data` lists tables whose data `from_dump` leaves out (the tables are still created, empty); `--all-data` restores them anyway
7
+
8
+ ## v0.9.3
9
+
10
+ record the app revision using git describe, at the beginning of the process (in case of accidental branch switches)
11
+
12
+ ## v0.9.2
13
+
14
+ update and fix bugsnag deploy tracking
15
+
3
16
  ## v0.9.1
4
17
 
5
18
  support url in heroku targets
data/README.md CHANGED
@@ -93,6 +93,14 @@ Sync a database down from remote to local
93
93
 
94
94
  _FYI rake db:drop_all_tables is handy as it doesn't require you to disconnect any running processes from the database._
95
95
 
96
+ `from_dump` restores with 4 parallel jobs (`--jobs N` to change). To leave out the data of
97
+ large tables you don't need locally (an audit table, say), list them in your configuration;
98
+ the tables are still created, just empty, and `--all-data` restores everything:
99
+
100
+ def skip_table_data
101
+ %w[versions]
102
+ end
103
+
96
104
  Copy production db to staging
97
105
 
98
106
  thor heroku:sync:to staging -f production
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "open3"
4
+ require "shellwords"
4
5
 
5
6
  module HerokuTool
6
7
  class Commander
@@ -14,13 +15,21 @@ module HerokuTool
14
15
  @configuration = configuration
15
16
  end
16
17
 
18
+ # The deploy ref is resolved to a commit once, before anything else happens, and that commit is what gets
19
+ # described, pushed and recorded: checking out another branch (or fetching) while the deploy is running
20
+ # doesn't change what is deployed or how it is reported.
21
+ #
22
+ # @return [String, false] the revision (commit sha) that was deployed, or false if the deploy failed
17
23
  def deploy(deploy_ref, with_maintenance:)
18
- deploy_ref_description = deploy_ref_describe(deploy_ref)
24
+ revision = resolve_revision(deploy_ref)
25
+ return false unless revision
26
+
27
+ deploy_ref_description = deploy_ref_describe(revision)
19
28
  puts "Deploy #{deploy_ref_description} to #{target} with migrate=#{target.migrate_in_release_phase ? "(during release phase)" : migrate_outside_of_release_phase?} with_maintenance=#{with_maintenance} "
20
29
 
21
- output_to_be_deployed(deploy_ref)
30
+ output_to_be_deployed(revision)
22
31
  configuration.before_deploying(self, target, deploy_ref_description)
23
- successful_push = puts_and_system "git push -f #{target.git_remote} #{deploy_ref || target}^{}:#{target.heroku_target_ref}"
32
+ successful_push = puts_and_system "git push -f #{target.git_remote} #{revision}:#{target.heroku_target_ref}"
24
33
 
25
34
  return false unless successful_push
26
35
 
@@ -32,12 +41,22 @@ module HerokuTool
32
41
  app_revision_env_var = configuration.app_revision_env_var
33
42
  if app_revision_env_var && app_revision_env_var != "HEROKU_SLUG_COMMIT"
34
43
  # HEROKU_SLUG_COMMIT is automatically set by https://devcenter.heroku.com/articles/dyno-metadata
35
- puts_and_system %{heroku config:set #{app_revision_env_var}=$(git describe --always #{deploy_ref}) -a #{target.heroku_app}}
44
+ puts_and_system "heroku config:set #{app_revision_env_var}=#{Shellwords.escape(deploy_ref_description)} -a #{target.heroku_app}"
36
45
  end
37
46
 
38
47
  maintenance_off if with_maintenance
39
48
  configuration.after_deploying(self, target, deploy_ref_description)
40
- true
49
+ revision
50
+ end
51
+
52
+ # @return [String, nil] the sha of the commit that deploy_ref (or the target's deploy_ref) points at right now
53
+ def resolve_revision(deploy_ref = nil)
54
+ deploy_ref ||= target.deploy_ref
55
+ revision = `git rev-parse --verify --quiet #{deploy_ref}^{commit}`.strip
56
+ return revision unless revision.empty?
57
+
58
+ puts "❌ Can't resolve '#{deploy_ref}' to a commit"
59
+ nil
41
60
  end
42
61
 
43
62
  def maintenance_on
@@ -55,7 +74,7 @@ module HerokuTool
55
74
  end
56
75
 
57
76
  def deploy_ref_describe(deploy_ref = nil)
58
- `git describe #{deploy_ref || target.deploy_ref}`.strip
77
+ `git describe --always #{deploy_ref || target.deploy_ref}`.strip
59
78
  end
60
79
 
61
80
  def output_to_be_deployed(since_deploy_ref = nil)
@@ -36,6 +36,12 @@ module HerokuTool
36
36
  end
37
37
  end
38
38
 
39
+ # tables whose data heroku:db:from_dump leaves out (the tables are still created, empty),
40
+ # e.g. %w[versions] for a large audit table you don't need locally
41
+ def skip_table_data
42
+ []
43
+ end
44
+
39
45
  def after_sync_down(instance)
40
46
  # could add source ?
41
47
  instance.puts_and_system "rails db:migrate"
@@ -135,9 +135,9 @@ class Heroku < Thor
135
135
  check_deploy_ref(deploy_ref)
136
136
  with_maintenance = options[:maintenance].nil? && migrate_outside_of_release_phase? || options[:maintenance] || false
137
137
  deploy_ref ||= target.deploy_ref
138
- success = commander.deploy(deploy_ref, with_maintenance: with_maintenance)
139
- if success
140
- deploy_tracking(target_name, deploy_ref)
138
+ deployed_revision = commander.deploy(deploy_ref, with_maintenance: with_maintenance)
139
+ if deployed_revision
140
+ deploy_tracking(target_name, deployed_revision)
141
141
  else
142
142
  exit(-1)
143
143
  end
@@ -318,15 +318,35 @@ class Heroku < Thor
318
318
  desc "from_dump --from SOURCE_TARGET", "make the db the same as the last target dump from SOURCE_TARGET"
319
319
 
320
320
  method_option :just_restore, default: false, desc: "Just do restore without post-actions", type: :boolean
321
+ method_option :all_data, default: false, desc: "Also restore the data of the tables in Configuration#skip_table_data", type: :boolean
322
+ method_option :jobs, default: 4, desc: "Number of parallel pg_restore jobs", type: :numeric
321
323
 
322
324
  def from_dump
323
325
  invoke "warn", [], from: options[:from]
324
326
  source = lookup_heroku(options[:from])
325
327
  db_config = ::HerokuTool::DbConfiguration.new
326
- puts_and_system "pg_restore --verbose --clean --no-acl --no-owner -h localhost #{db_config.user_arg} -d #{db_config.database} #{source.dump_filename}"
328
+ puts_and_system "pg_restore --verbose --clean --no-acl --no-owner -j #{options[:jobs]} #{restore_list_arg(source)}-h localhost #{db_config.user_arg} -d #{db_config.database} #{source.dump_filename}"
327
329
  configuration.after_sync_down(self) unless options[:just_restore]
328
330
  end
329
331
 
332
+ no_commands do
333
+ # @return [String] "-L <list> " naming a copy of the dump's table of contents with the
334
+ # data of Configuration#skip_table_data commented out, or "" when nothing is skipped
335
+ def restore_list_arg(source)
336
+ tables = options[:all_data] ? [] : configuration.skip_table_data
337
+ return "" if tables.empty?
338
+
339
+ toc, status = Open3.capture2("pg_restore", "-l", source.dump_filename)
340
+ raise Thor::Error, "pg_restore -l #{source.dump_filename} failed" unless status.success?
341
+
342
+ patterns = tables.map { |table| / TABLE DATA public #{Regexp.escape(table)} / }
343
+ list = toc.lines.map { |line| (patterns.any? { |pattern| line.match?(pattern) }) ? ";#{line}" : line }
344
+ list_filename = "#{source.dump_filename}.list"
345
+ File.write(list_filename, list.join)
346
+ "-L #{list_filename} "
347
+ end
348
+ end
349
+
330
350
  desc "dump_to_tmp", "dump to tmp directory"
331
351
  method_option(:from, type: :string, default: "local", desc: "heroku target (defaults to local)", required: false, aliases: "f")
332
352
 
@@ -1,3 +1,3 @@
1
1
  module HerokuTool
2
- VERSION = "0.9.2"
2
+ VERSION = "0.9.4"
3
3
  end
@@ -37,6 +37,10 @@ class Heroku
37
37
  # instance.puts_and_system "rake dev:dev_data"
38
38
  # end
39
39
  #
40
+ # def skip_table_data
41
+ # %w[versions]
42
+ # end
43
+ #
40
44
  # def after_sync_to(instance, target)
41
45
  # super
42
46
  # instance.puts_and_system %(heroku run rake dev:staging_data -a #{target.heroku_app})
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heroku_tool
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Diggins
@@ -173,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
173
  - !ruby/object:Gem::Version
174
174
  version: '0'
175
175
  requirements: []
176
- rubygems_version: 4.0.11
176
+ rubygems_version: 3.6.9
177
177
  specification_version: 4
178
178
  summary: Tool for configurable one-shot deployment and db managment with heroku and
179
179
  rails