heroku_hatchet 7.3.3 → 7.4.0

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
  SHA256:
3
- metadata.gz: 38e2cd43133aeb405a133834284c026c0e4a1347e33f84e805ed7b9fd2674fc9
4
- data.tar.gz: b1f88b0a62250a4cb2d9e22a89fe101356c5360aa37d786a51faebb2fac23824
3
+ metadata.gz: 4e33ffcf73b42d412f81525fdce9b77baa34da4083a6662cb14ddb098a0535dc
4
+ data.tar.gz: 3d73f585c00dd74cd4733802af979ba75e2c04e4cb93118128fdaf6efe9bc53b
5
5
  SHA512:
6
- metadata.gz: b36428d7f0e5288ac434d3fa66c3bf70b067742f4e150ebc4208d2e1e9b23761c7fd94cee0c8713909e07c63845014b7b139dd86f82d0118a53978b0033a83f7
7
- data.tar.gz: 3250c42cdd66bfbcfc4b129a0cf4083b30b94308614bf5ae4c765ced438522e814a6205dde298b51132eb6057581329054fde9d7bbd49208dda2d9cf89bd3e8d
6
+ metadata.gz: f9ef93379dd21e7808f30d9a2ed6179a76aa12679d5a1129a1ed394682c3e046abcc6c8b87ae8d3112edc5ff77965f90d42550be6d09a49ed89b7ad7270fdf14
7
+ data.tar.gz: 6cd06944d64ca9ae96ed8b25744000de748a5235dc52fab838368b9afc75c28af6dc9c1432106a99f972b4044d94762ce573fcaef2fa91f062a68aad2000b05a
@@ -1,13 +1,22 @@
1
1
  name: Check Changelog
2
2
 
3
3
  on:
4
- pull_request:
5
- types: [opened, reopened, edited, synchronize]
4
+ pull_request:
5
+ types: [opened, reopened, edited, labeled, unlabeled, synchronize]
6
+
6
7
  jobs:
7
- build:
8
+ check-changelog:
8
9
  runs-on: ubuntu-latest
10
+ if: |
11
+ !contains(github.event.pull_request.body, '[skip changelog]') &&
12
+ !contains(github.event.pull_request.body, '[changelog skip]') &&
13
+ !contains(github.event.pull_request.body, '[skip ci]') &&
14
+ !contains(github.event.pull_request.labels.*.name, 'skip changelog') &&
15
+ !contains(github.event.pull_request.labels.*.name, 'dependencies') &&
16
+ !contains(github.event.pull_request.labels.*.name, 'automation')
9
17
  steps:
10
- - uses: actions/checkout@v1
11
- - name: Check that CHANGELOG is touched
12
- run: |
13
- cat $GITHUB_EVENT_PATH | jq .pull_request.title | grep -i '\[\(\(changelog skip\)\|\(ci skip\)\)\]' || git diff remotes/origin/${{ github.base_ref }} --name-only | grep CHANGELOG.md
18
+ - uses: actions/checkout@v3
19
+ - name: Check that CHANGELOG is touched
20
+ run: |
21
+ git fetch origin ${{ github.base_ref }} --depth 1 && \
22
+ git diff remotes/origin/${{ github.base_ref }} --name-only | grep CHANGELOG.md
@@ -0,0 +1,38 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ # Avoid duplicate builds on PRs.
5
+ branches:
6
+ - main
7
+ pull_request:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ test:
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ ruby-version: ["2.7", "3.0", "3.1"]
18
+ runs-on: ubuntu-22.04
19
+ env:
20
+ HATCHET_APP_LIMIT: 100
21
+ HATCHET_RETRIES: 3
22
+ HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }}
23
+ HEROKU_API_USER: ${{ secrets.HEROKU_API_USER }}
24
+ IS_RUNNING_ON_CI: 1
25
+ HATCHET_EXPENSIVE_MODE: 1
26
+ PARALLEL_SPLIT_TEST_PROCESSES: 25
27
+ steps:
28
+ - name: Checkout
29
+ uses: actions/checkout@v3
30
+ - name: Set up Ruby ${{ matrix.ruby-version }} and dependencies
31
+ uses: ruby/setup-ruby@v1
32
+ with:
33
+ ruby-version: ${{ matrix.ruby-version }}
34
+ bundler-cache: true
35
+ - name: Hatchet setup
36
+ run: bundle exec hatchet ci:setup
37
+ - name: Run test suite
38
+ run: bundle exec parallel_split_test spec/
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  ## HEAD
2
2
 
3
+ ## 7.4.0
4
+
5
+ - Supports "basic" scaledown (https://github.com/heroku/hatchet/pull/193)
6
+ - Breaking: Support for Ruby 2.2 is soft removed going forward only Ruby versions on the currently released stack will be supported
7
+ - Bugfix: `heroku run` calls are now properly rate throttled and retried https://github.com/heroku/hatchet/pull/187
8
+
9
+ ## 7.3.4
10
+
11
+ - Memoize `Hatchet::App.default_buildpack` (https://github.com/heroku/hatchet/pull/183)
12
+ - Fix repository path lookup when custom Hatchet directory set (https://github.com/heroku/hatchet/issues/181)
13
+ - Handle additional variations of rate limit error messages (https://github.com/heroku/hatchet/pull/182)
14
+ - Add `HATCHET_DEFAULT_STACK` for configuring the default stack (https://github.com/heroku/hatchet/pull/184)
15
+ - Fix typo in the reaper `"Duplicate destroy attempted"` message (https://github.com/heroku/hatchet/pull/175)
16
+ - Set `init.defaultBranch` in ci:setup to suppress `git init` warning in Git 2.30+ (https://github.com/heroku/hatchet/issues/172)
17
+ - Switch `heroku ci:install_heroku` to the Heroku CLI standalone installer rather than the APT install method (https://github.com/heroku/hatchet/issues/171)
18
+
3
19
  ## 7.3.3
4
20
 
5
21
  - Quiet personal tokens (https://github.com/heroku/hatchet/pull/148)
@@ -344,7 +360,6 @@
344
360
 
345
361
  after_script: bundle exec rake hatchet:teardown_travis
346
362
 
347
-
348
363
  ## 0.1.1
349
364
 
350
365
  - Allow auto retries of pushes by setting environment variable `HATCHET_RETRIES=3`
data/README.md CHANGED
@@ -504,7 +504,7 @@ The `Hatchet::Runner.new` takes several arguments.
504
504
 
505
505
  ### Init options
506
506
 
507
- - stack (String): The stack you want to deploy to on Heroku.
507
+ - stack (String): The Heroku [stack](https://devcenter.heroku.com/articles/stack) to use for the app. If this is not set, the stack will be determined from `HATCHET_DEFAULT_STACK`, or else the Heroku platform's [default stack](https://devcenter.heroku.com/articles/stack#default-stack).
508
508
 
509
509
  ```ruby
510
510
  Hatchet::Runner.new("default_ruby", stack: "heroku-16").deploy do |app|
@@ -598,6 +598,7 @@ app.get_config("DEPLOY_TASKS") # => "run:bloop"
598
598
 
599
599
  - `app.set_lab()`: Enables the specified lab/feature on the app
600
600
  - `app.add_database()`: adds a database to the app, defaults to the "dev" database
601
+ - `app.update_stack()`: Change the app's stack to that specified (for example `"heroku-20"`). Will take effect on the next build.
601
602
  - `app.run()`: Runs a `heroku run bash` session with the arguments, covered above.
602
603
  - `app.run_multi()`: Runs a `heroku run bash` session in the background and yields the results. This requires the `run_multi` flag of the app to be set to `true`, which will charge your application (the `HATCHET_EXPENSIVE_MODE` env var must also be set to use this feature). Example above.
603
604
  - `app.create_app`: Can be used to manually create the app without deploying it (You probably want `setup!` though)
@@ -727,6 +728,7 @@ HATCHET_ALIVE_TTL_MINUTES=7
727
728
  - `HATCHET_APP_LIMIT`: The maximum number of **hatchet** apps that Hatchet will allow in the given account before running the reaper. For local execution, keep this low as you don't want your account dominated by hatchet apps. For CI, you want it to be much larger, 80-100 since it's not competing with non-hatchet apps. Your test runner account needs to be a dedicated account.
728
729
  - `HEROKU_API_KEY`: The API key of your test account user. If you run locally without this set, it will use your personal credentials.
729
730
  - `HEROKU_API_USER`: The email address of your user account. If you run locally without this set, it will use your personal credentials.
731
+ - `HATCHET_DEFAULT_STACK`: The default Heroku stack to be used when an explicit `stack` is not passed to `App.new`. If this is not set, apps will instead use Heroku platform's [default stack](https://devcenter.heroku.com/articles/stack#default-stack).
730
732
  - `HATCHET_RUN_MULTI`: If enabled, this will scale up deployed apps to "standard-1x" once deployed instead of running on the free tier. This enables the `run_multi` method capability, however scaling up is not free. WARNING: Setting this env var will incur charges to your Heroku account. We recommended never to enable this setting unless you work for Heroku. To use this you must also set `HATCHET_EXPENSIVE_MODE=1`
731
733
  - `HATCHET_EXPENSIVE_MODE`: This is intended to be a "safety" environment variable. If it is not set, Hatchet will prevent you from using the `run_multi: true` setting or the `HATCHET_RUN_MULTI` environment variables. There are still ways to incur charges without this feature, but unless you're absolutely confident your test setup will not leave "orphan" apps that are billing you, do not enable this setting. Even then, only set this value if you work for Heroku. To recap WARNING: setting this is expensive.
732
734
 
data/etc/ci_setup.rb CHANGED
@@ -30,6 +30,8 @@ run_cmd "bundle exec hatchet ci:install_heroku"
30
30
  run_cmd "bundle exec hatchet install"
31
31
  run_cmd "git config --get user.email > /dev/null || git config --global user.email #{ENV.fetch('HEROKU_API_USER').shellescape}"
32
32
  run_cmd "git config --get user.name > /dev/null || git config --global user.name 'BuildpackTester'"
33
+ # Suppress the `git init` warning in Git 2.30+ when no default branch name is set.
34
+ run_cmd "git config --global init.defaultBranch main"
33
35
 
34
36
  puts "== Done =="
35
37
 
data/etc/setup_heroku.sh CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
3
  set -euo pipefail
4
- curl --fail --retry 3 --retry-delay 1 --connect-timeout 3 --max-time 30 https://cli-assets.heroku.com/install-ubuntu.sh | sh
4
+ curl --fail --retry 3 --retry-delay 1 --connect-timeout 3 --max-time 30 https://cli-assets.heroku.com/install.sh | sh
data/lib/hatchet/app.rb CHANGED
@@ -49,7 +49,7 @@ module Hatchet
49
49
  DEFAULT_REPO_NAME = Object.new
50
50
 
51
51
  def initialize(repo_name = DEFAULT_REPO_NAME,
52
- stack: "",
52
+ stack: ENV["HATCHET_DEFAULT_STACK"],
53
53
  name: default_name,
54
54
  debug: nil,
55
55
  debugging: nil,
@@ -112,8 +112,9 @@ module Hatchet
112
112
  @directory
113
113
  end
114
114
 
115
+ @default_buildpack = nil
115
116
  def self.default_buildpack
116
- [HATCHET_BUILDPACK_BASE.call, HATCHET_BUILDPACK_BRANCH.call].join("#")
117
+ @default_buildpack ||= [HATCHET_BUILDPACK_BASE.call, HATCHET_BUILDPACK_BRANCH.call].join("#")
117
118
  end
118
119
 
119
120
  def allow_failure?
@@ -359,7 +360,7 @@ module Hatchet
359
360
 
360
361
  if @run_multi_is_setup
361
362
  @run_multi_array.map(&:join)
362
- platform_api.formation.update(name, "web", {"size" => "free"})
363
+ platform_api.formation.update(name, "web", {"size" => "basic"})
363
364
  end
364
365
 
365
366
  ensure
@@ -44,7 +44,7 @@ module Hatchet
44
44
 
45
45
  # use this method to turn "codetriage" into repos/rails3/codetriage
46
46
  def path_for_name(name)
47
- possible_paths = [repos[name.to_s], "repos/#{name}", name].compact
47
+ possible_paths = [repos[name.to_s], "#{repo_directory_path}/#{name}", name].compact
48
48
  path = possible_paths.detect do |path|
49
49
  !(Dir[path] && Dir[path].empty?)
50
50
  end
@@ -13,7 +13,7 @@ module Hatchet
13
13
  output = git_push_heroku_yall
14
14
  rescue FailedDeploy => e
15
15
  case e.output
16
- when /reached the API rate limit/, /429 Too Many Requests/
16
+ when /reached the API rate limit/, /429 Too Many Requests/, /HTTP 429/, /HTTP code = 429/
17
17
  throw(:throttle)
18
18
  else
19
19
  raise e unless @allow_failure
@@ -1,4 +1,39 @@
1
+ require 'open3'
2
+
1
3
  module Hatchet
4
+ class BashResult
5
+ attr_reader :stdout, :stderr, :status
6
+
7
+ def initialize(stdout:, stderr:, status:, set_global_status: false)
8
+ @stdout = stdout
9
+ @stderr = stderr
10
+ @status = status.respond_to?(:exitstatus) ? status.exitstatus : status.to_i
11
+ `exit #{@status}` if set_global_status
12
+ end
13
+
14
+ # @return [Boolean]
15
+ def success?
16
+ @status == 0
17
+ end
18
+
19
+ def failed?
20
+ !success?
21
+ end
22
+
23
+ # Testing helper methods
24
+ def include?(value)
25
+ stdout.include?(value)
26
+ end
27
+
28
+ def match?(value)
29
+ stdout.match?(value)
30
+ end
31
+
32
+ def match(value)
33
+ stdout.match(value)
34
+ end
35
+ end
36
+
2
37
  # Used for running Heroku commands
3
38
  #
4
39
  # Example:
@@ -28,18 +63,21 @@ module Hatchet
28
63
  @command = build_heroku_command(command, heroku || {})
29
64
  @retry_on_empty = retry_on_empty
30
65
  @stderr = stderr
31
- @output = ""
32
- @status = nil
66
+ @result = nil
33
67
  @empty_fail_count = 0
34
68
  end
35
69
 
70
+ def result
71
+ raise "You must run `call` on this object first" unless @result
72
+ @result
73
+ end
74
+
36
75
  def output
37
- raise "You must run `call` on this object first" unless @status
38
- @output
76
+ result.stdout
39
77
  end
40
78
 
41
79
  def status
42
- raise "You must run `call` on this object first" unless @status
80
+ result
43
81
  @status
44
82
  end
45
83
 
@@ -68,12 +106,13 @@ module Hatchet
68
106
  private def execute!
69
107
  ShellThrottle.new(platform_api: @app.platform_api).call do |throttle|
70
108
  run_shell!
71
- throw(:throttle) if output.match?(/reached the API rate limit/)
109
+ throw(:throttle) if @result.stderr.match?(/reached the API rate limit/)
72
110
  end
73
111
  end
74
112
 
75
113
  private def run_shell!
76
- @output = `#{@command}`
114
+ stdout, stderr, status = Open3.capture3(@command)
115
+ @result = BashResult.new(stdout: stdout, stderr: stderr, status: status, set_global_status: true)
77
116
  @status = $?
78
117
  end
79
118
 
@@ -170,14 +170,14 @@ module Hatchet
170
170
  body = e.response.body
171
171
  request_id = e.response.headers["Request-Id"]
172
172
  if body =~ /Couldn\'t find that app./
173
- io.puts "Duplicate destoy attempted #{name.inspect}: #{id}, status: 404, request_id: #{request_id}"
173
+ io.puts "Duplicate destroy attempted #{name.inspect}: #{id}, status: 404, request_id: #{request_id}"
174
174
  raise AlreadyDeletedError.new
175
175
  else
176
176
  raise e
177
177
  end
178
178
  rescue Excon::Error::Forbidden => e
179
179
  request_id = e.response.headers["Request-Id"]
180
- io.puts "Duplicate destoy attempted #{name.inspect}: #{id}, status: 403, request_id: #{request_id}"
180
+ io.puts "Duplicate destroy attempted #{name.inspect}: #{id}, status: 403, request_id: #{request_id}"
181
181
  raise AlreadyDeletedError.new
182
182
  end
183
183
 
@@ -1,13 +1,22 @@
1
1
  name: Check Changelog
2
2
 
3
3
  on:
4
- pull_request:
5
- types: [opened, reopened, edited, synchronize]
4
+ pull_request:
5
+ types: [opened, reopened, edited, labeled, unlabeled, synchronize]
6
+
6
7
  jobs:
7
- build:
8
+ check-changelog:
8
9
  runs-on: ubuntu-latest
10
+ if: |
11
+ !contains(github.event.pull_request.body, '[skip changelog]') &&
12
+ !contains(github.event.pull_request.body, '[changelog skip]') &&
13
+ !contains(github.event.pull_request.body, '[skip ci]') &&
14
+ !contains(github.event.pull_request.labels.*.name, 'skip changelog') &&
15
+ !contains(github.event.pull_request.labels.*.name, 'dependencies') &&
16
+ !contains(github.event.pull_request.labels.*.name, 'automation')
9
17
  steps:
10
- - uses: actions/checkout@v1
11
- - name: Check that CHANGELOG is touched
12
- run: |
13
- cat $GITHUB_EVENT_PATH | jq .pull_request.title | grep -i '\[\(\(changelog skip\)\|\(ci skip\)\)\]' || git diff remotes/origin/${{ github.base_ref }} --name-only | grep CHANGELOG.md
18
+ - uses: actions/checkout@v3
19
+ - name: Check that CHANGELOG is touched
20
+ run: |
21
+ git fetch origin ${{ github.base_ref }} --depth 1 && \
22
+ git diff remotes/origin/${{ github.base_ref }} --name-only | grep CHANGELOG.md
@@ -1,4 +1,4 @@
1
- version: 1
1
+ version: 2
2
2
  updates:
3
3
  - package-ecosystem: "bundler"
4
4
  directory: "/"
@@ -1,3 +1,3 @@
1
1
  module Hatchet
2
- VERSION = "7.3.3"
2
+ VERSION = "7.4.0"
3
3
  end
@@ -58,13 +58,30 @@ describe "AppTest" do
58
58
  expect(app.buildpacks.first).to match("https://github.com/heroku/heroku-buildpack-ruby")
59
59
  end
60
60
 
61
+ it "default_buildpack is only computed once" do
62
+ expect(Hatchet::App.default_buildpack.object_id).to eq(Hatchet::App.default_buildpack.object_id)
63
+ end
64
+
61
65
  it "create app with stack" do
62
- stack = "heroku-16"
66
+ stack = "heroku-18"
63
67
  app = Hatchet::App.new("default_ruby", stack: stack)
64
68
  app.create_app
65
69
  expect(app.platform_api.app.info(app.name)["build_stack"]["name"]).to eq(stack)
66
70
  end
67
71
 
72
+ it "create app with HATCHET_DEFAULT_STACK set" do
73
+ begin
74
+ original_default_stack = ENV["HATCHET_DEFAULT_STACK"]
75
+ default_stack = "heroku-18"
76
+ ENV["HATCHET_DEFAULT_STACK"] = default_stack
77
+ app = Hatchet::App.new("default_ruby")
78
+ app.create_app
79
+ expect(app.platform_api.app.info(app.name)["build_stack"]["name"]).to eq(default_stack)
80
+ ensure
81
+ ENV["HATCHET_DEFAULT_STACK"] = original_default_stack
82
+ end
83
+ end
84
+
68
85
  it "marks itself 'finished' when done in block mode" do
69
86
  app = Hatchet::Runner.new("default_ruby")
70
87
 
@@ -27,8 +27,10 @@ describe "CIFourTest" do
27
27
  end
28
28
 
29
29
  it "error with bad app" do
30
+ pending("upgrade rails 5 app to newer")
31
+
30
32
  expect {
31
- Hatchet::GitApp.new("rails5_ci_fails_no_database").run_ci { }
33
+ Hatchet::GitApp.new("rails5_ci_fails_no_database", stack: "heroku-18").run_ci { }
32
34
  }.to raise_error(/PG::ConnectionBad: could not connect to server/)
33
35
  end
34
36
 
@@ -41,7 +43,7 @@ describe "CIFourTest" do
41
43
  @before_deploy_dir_pwd = Dir.pwd
42
44
  end
43
45
 
44
- Hatchet::GitApp.new("rails5_ci_fails_no_database", allow_failure: true, before_deploy: before_deploy).run_ci do |test_run|
46
+ Hatchet::GitApp.new("rails5_ci_fails_no_database", stack: "heroku-18", allow_failure: true, before_deploy: before_deploy).run_ci do |test_run|
45
47
  expect(test_run.status).to eq(:errored)
46
48
  expect(@before_deploy_dir_pwd).to eq(Dir.pwd)
47
49
  expect(@before_deploy_called).to be_truthy
@@ -51,6 +53,8 @@ describe "CIFourTest" do
51
53
  end
52
54
 
53
55
  it "ci create app with stack" do
56
+ pending("upgrade rails 5 app to newer")
57
+
54
58
  app = Hatchet::GitApp.new("rails5_ruby_schema_format")
55
59
  app.run_ci do |test_run|
56
60
  expect(test_run.output).to match("Ruby buildpack tests completed successfully")
@@ -6,6 +6,10 @@ describe "ConfigTest" do
6
6
  expect(@config.path_for_name("rails3_mri_193")).to(eq("repo_fixtures/repos/rails3/rails3_mri_193"))
7
7
  end
8
8
 
9
+ it("config path for name with full repo name") do
10
+ expect(@config.path_for_name("rails3/rails3_mri_193")).to(eq("repo_fixtures/repos/rails3/rails3_mri_193"))
11
+ end
12
+
9
13
  it("config dirs") do
10
14
  { "repo_fixtures/repos/bundler/no_lockfile" => "https://github.com/sharpstone/no_lockfile.git", "repo_fixtures/repos/default/default_ruby" => "https://github.com/sharpstone/default_ruby.git", "repo_fixtures/repos/rails2/rails2blog" => "https://github.com/sharpstone/rails2blog.git", "repo_fixtures/repos/rails3/rails3_mri_193" => "https://github.com/sharpstone/rails3_mri_193.git" }.each do |key, value|
11
15
  assert_include(key, value, @config.dirs)
@@ -50,7 +50,7 @@ describe "HerokuRun" do
50
50
  run_obj = Hatchet::HerokuRun.new("ruby -v", app: @app, stderr: stderr)
51
51
 
52
52
  def run_obj.run_shell!
53
- @output = ""
53
+ @result = Hatchet::BashResult.new(stdout: "", stderr: "", status: 1)
54
54
  @status = Object.new
55
55
  end
56
56
 
@@ -65,7 +65,7 @@ describe "HerokuRun" do
65
65
  run_obj = Hatchet::HerokuRun.new("ruby -v", app: @app, stderr: stderr)
66
66
 
67
67
  def run_obj.run_shell!
68
- @output = "not empty"
68
+ @result = Hatchet::BashResult.new(stdout: "not empty", stderr: "", status: 1)
69
69
  @status = Object.new
70
70
  end
71
71
 
@@ -80,7 +80,7 @@ describe "HerokuRun" do
80
80
  run_obj = Hatchet::HerokuRun.new("ruby -v", app: @app, stderr: stderr, retry_on_empty: false)
81
81
 
82
82
  def run_obj.run_shell!
83
- @output = ""
83
+ @result = Hatchet::BashResult.new(stdout: "", stderr: "", status: 1)
84
84
  @status = Object.new
85
85
  end
86
86
 
@@ -90,6 +90,24 @@ describe "HerokuRun" do
90
90
  expect(stderr.string).to_not include("retrying the command.")
91
91
  end
92
92
 
93
+ it "retries work when message is delivered via stderr" do
94
+ stderr = StringIO.new
95
+ run_obj = Hatchet::HerokuRun.new("ruby -v", app: @app, stderr: stderr, retry_on_empty: false)
96
+
97
+ def run_obj.run_shell!
98
+ @throttle_retry_count ||= 0
99
+ @throttle_retry_count += 1
100
+ @command = "echo 'lol'" if @throttle_retry_count > 1
101
+
102
+ super
103
+ end
104
+
105
+ run_obj.instance_variable_set(:@command, "ruby -e 'STDERR.puts %Q{reached the API rate limit}'")
106
+ run_obj.call
107
+
108
+ expect(run_obj.instance_variable_get(:@throttle_retry_count)).to eq(2)
109
+ end
110
+
93
111
  it "retries 0 times on empty result when disabled via ENV var" do
94
112
  begin
95
113
  original_env = ENV["HATCHET_DISABLE_EMPTY_RUN_RETRY"]
@@ -98,7 +116,7 @@ describe "HerokuRun" do
98
116
  run_obj = Hatchet::HerokuRun.new("ruby -v", app: @app, stderr: stderr)
99
117
 
100
118
  def run_obj.run_shell!
101
- @output = ""
119
+ @result = Hatchet::BashResult.new(stdout: "", stderr: "", status: 1)
102
120
  @status = Object.new
103
121
  end
104
122
 
@@ -43,7 +43,7 @@ describe "ShellThrottle" do
43
43
  end
44
44
 
45
45
  describe "git push throttle" do
46
- it "rate throttles `git push` " do
46
+ it "rate throttles `git push` with output variation 1" do
47
47
  app = Hatchet::GitApp.new("default_ruby")
48
48
  def app.git_push_heroku_yall
49
49
  @_git_push_heroku_yall_call_count ||= 0
@@ -67,7 +67,7 @@ describe "ShellThrottle" do
67
67
  expect(app.what_is_git_push_heroku_yall_call_count).to be(2)
68
68
  end
69
69
 
70
- it "rate throttles `git push` with different output" do
70
+ it "rate throttles `git push` with output variation 2" do
71
71
  app = Hatchet::GitApp.new("default_ruby")
72
72
  def app.git_push_heroku_yall
73
73
  @_git_push_heroku_yall_call_count ||= 0
@@ -90,5 +90,53 @@ describe "ShellThrottle" do
90
90
 
91
91
  expect(app.what_is_git_push_heroku_yall_call_count).to be(2)
92
92
  end
93
+
94
+ it "rate throttles `git push` with output variation 3" do
95
+ app = Hatchet::GitApp.new("default_ruby")
96
+ def app.git_push_heroku_yall
97
+ @_git_push_heroku_yall_call_count ||= 0
98
+ @_git_push_heroku_yall_call_count += 1
99
+ if @_git_push_heroku_yall_call_count >= 2
100
+ "Success"
101
+ else
102
+ raise Hatchet::App::FailedDeployError.new(
103
+ self,
104
+ "message",
105
+ output: "error: RPC failed; HTTP 429 curl 22 The requested URL returned error: 429"
106
+ )
107
+ end
108
+ end
109
+
110
+ def app.sleep_called?; @sleep_called; end
111
+ def app.what_is_git_push_heroku_yall_call_count; @_git_push_heroku_yall_call_count; end
112
+
113
+ app.push_without_retry!
114
+
115
+ expect(app.what_is_git_push_heroku_yall_call_count).to be(2)
116
+ end
117
+
118
+ it "rate throttles `git push` with output variation 4" do
119
+ app = Hatchet::GitApp.new("default_ruby")
120
+ def app.git_push_heroku_yall
121
+ @_git_push_heroku_yall_call_count ||= 0
122
+ @_git_push_heroku_yall_call_count += 1
123
+ if @_git_push_heroku_yall_call_count >= 2
124
+ "Success"
125
+ else
126
+ raise Hatchet::App::FailedDeployError.new(
127
+ self,
128
+ "message",
129
+ output: "error: RPC failed; result=22, HTTP code = 429"
130
+ )
131
+ end
132
+ end
133
+
134
+ def app.sleep_called?; @sleep_called; end
135
+ def app.what_is_git_push_heroku_yall_call_count; @_git_push_heroku_yall_call_count; end
136
+
137
+ app.push_without_retry!
138
+
139
+ expect(app.what_is_git_push_heroku_yall_call_count).to be(2)
140
+ end
93
141
  end
94
142
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heroku_hatchet
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.3.3
4
+ version: 7.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Schneeman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-16 00:00:00.000000000 Z
11
+ date: 2023-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: platform-api
@@ -158,8 +158,8 @@ executables:
158
158
  extensions: []
159
159
  extra_rdoc_files: []
160
160
  files:
161
- - ".circleci/config.yml"
162
161
  - ".github/workflows/check_changelog.yml"
162
+ - ".github/workflows/ci.yml"
163
163
  - ".gitignore"
164
164
  - CHANGELOG.md
165
165
  - Gemfile
@@ -230,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
230
230
  - !ruby/object:Gem::Version
231
231
  version: '0'
232
232
  requirements: []
233
- rubygems_version: 3.1.4
233
+ rubygems_version: 3.3.26
234
234
  signing_key:
235
235
  specification_version: 4
236
236
  summary: Hatchet is a an integration testing library for developing Heroku buildpacks.
data/.circleci/config.yml DELETED
@@ -1,69 +0,0 @@
1
- version: 2
2
- references:
3
- unit: &unit
4
- run:
5
- name: Run test suite
6
- command: PARALLEL_SPLIT_TEST_PROCESSES=25 bundle exec parallel_split_test spec/
7
- environment:
8
- HATCHET_EXPENSIVE_MODE: 1 # !!!! WARNING !!!! ONLY RUN THIS IF YOU WORK FOR HEROKU !!!! WARNING !!!!
9
- restore: &restore
10
- restore_cache:
11
- keys:
12
- - v1_bundler_deps-{{ .Environment.CIRCLE_JOB }}
13
- save: &save
14
- save_cache:
15
- paths:
16
- - ./vendor/bundle
17
- key: v1_bundler_deps-{{ .Environment.CIRCLE_JOB }} # CIRCLE_JOB e.g. "ruby-2.5"
18
- hatchet_setup: &hatchet_setup
19
- run:
20
- name: Hatchet setup
21
- command: |
22
- bundle exec hatchet ci:setup
23
- bundle: &bundle
24
- run:
25
- name: install dependencies
26
- command: |
27
- bundle install --jobs=4 --retry=3 --path vendor/bundle
28
- bundle update
29
- bundle clean
30
-
31
- jobs:
32
- "ruby-2.2":
33
- docker:
34
- - image: circleci/ruby:2.2
35
- steps:
36
- - checkout
37
- - <<: *restore
38
- - <<: *bundle
39
- - <<: *hatchet_setup
40
- - <<: *unit
41
- - <<: *save
42
- "ruby-2.5":
43
- docker:
44
- - image: circleci/ruby:2.5
45
- steps:
46
- - checkout
47
- - <<: *restore
48
- - <<: *bundle
49
- - <<: *hatchet_setup
50
- - <<: *unit
51
- - <<: *save
52
- "ruby-2.7":
53
- docker:
54
- - image: circleci/ruby:2.7
55
- steps:
56
- - checkout
57
- - <<: *restore
58
- - <<: *bundle
59
- - <<: *hatchet_setup
60
- - <<: *unit
61
- - <<: *save
62
-
63
- workflows:
64
- version: 2
65
- build:
66
- jobs:
67
- - "ruby-2.2"
68
- - "ruby-2.5"
69
- - "ruby-2.7"