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 +4 -4
- data/.github/workflows/check_changelog.yml +16 -7
- data/.github/workflows/ci.yml +38 -0
- data/CHANGELOG.md +16 -1
- data/README.md +3 -1
- data/etc/ci_setup.rb +2 -0
- data/etc/setup_heroku.sh +1 -1
- data/lib/hatchet/app.rb +4 -3
- data/lib/hatchet/config.rb +1 -1
- data/lib/hatchet/git_app.rb +1 -1
- data/lib/hatchet/heroku_run.rb +46 -7
- data/lib/hatchet/reaper.rb +2 -2
- data/lib/hatchet/templates/check_changelog.erb +16 -7
- data/lib/hatchet/templates/dependabot.erb +1 -1
- data/lib/hatchet/version.rb +1 -1
- data/spec/hatchet/app_spec.rb +18 -1
- data/spec/hatchet/ci_spec.rb +6 -2
- data/spec/hatchet/config_spec.rb +4 -0
- data/spec/unit/heroku_run_spec.rb +22 -4
- data/spec/unit/shell_throttle_spec.rb +50 -2
- metadata +4 -4
- data/.circleci/config.yml +0 -69
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e33ffcf73b42d412f81525fdce9b77baa34da4083a6662cb14ddb098a0535dc
|
4
|
+
data.tar.gz: 3d73f585c00dd74cd4733802af979ba75e2c04e4cb93118128fdaf6efe9bc53b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9ef93379dd21e7808f30d9a2ed6179a76aa12679d5a1129a1ed394682c3e046abcc6c8b87ae8d3112edc5ff77965f90d42550be6d09a49ed89b7ad7270fdf14
|
7
|
+
data.tar.gz: 6cd06944d64ca9ae96ed8b25744000de748a5235dc52fab838368b9afc75c28af6dc9c1432106a99f972b4044d94762ce573fcaef2fa91f062a68aad2000b05a
|
@@ -1,13 +1,22 @@
|
|
1
1
|
name: Check Changelog
|
2
2
|
|
3
3
|
on:
|
4
|
-
|
5
|
-
|
4
|
+
pull_request:
|
5
|
+
types: [opened, reopened, edited, labeled, unlabeled, synchronize]
|
6
|
+
|
6
7
|
jobs:
|
7
|
-
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
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
|
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" => "
|
363
|
+
platform_api.formation.update(name, "web", {"size" => "basic"})
|
363
364
|
end
|
364
365
|
|
365
366
|
ensure
|
data/lib/hatchet/config.rb
CHANGED
@@ -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], "
|
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
|
data/lib/hatchet/git_app.rb
CHANGED
@@ -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
|
data/lib/hatchet/heroku_run.rb
CHANGED
@@ -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
|
-
@
|
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
|
-
|
38
|
-
@output
|
76
|
+
result.stdout
|
39
77
|
end
|
40
78
|
|
41
79
|
def status
|
42
|
-
|
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
|
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
|
-
|
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
|
|
data/lib/hatchet/reaper.rb
CHANGED
@@ -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
|
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
|
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
|
-
|
5
|
-
|
4
|
+
pull_request:
|
5
|
+
types: [opened, reopened, edited, labeled, unlabeled, synchronize]
|
6
|
+
|
6
7
|
jobs:
|
7
|
-
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
data/lib/hatchet/version.rb
CHANGED
data/spec/hatchet/app_spec.rb
CHANGED
@@ -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-
|
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
|
|
data/spec/hatchet/ci_spec.rb
CHANGED
@@ -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")
|
data/spec/hatchet/config_spec.rb
CHANGED
@@ -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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
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.
|
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:
|
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.
|
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"
|