shipit-engine 0.33.0 → 0.34.0
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 +4 -4
- data/README.md +13 -2
- data/app/assets/stylesheets/_pages/_deploy.scss +0 -2
- data/app/controllers/shipit/api/ccmenu_controller.rb +1 -1
- data/app/controllers/shipit/api/deploys_controller.rb +2 -0
- data/app/controllers/shipit/api/rollbacks_controller.rb +2 -1
- data/app/controllers/shipit/api/stacks_controller.rb +1 -0
- data/app/controllers/shipit/deploys_controller.rb +1 -1
- data/app/controllers/shipit/stacks_controller.rb +2 -2
- data/app/controllers/shipit/tasks_controller.rb +2 -2
- data/app/controllers/shipit/webhooks_controller.rb +23 -4
- data/app/helpers/shipit/shipit_helper.rb +0 -1
- data/app/jobs/shipit/deliver_hook_job.rb +1 -1
- data/app/jobs/shipit/github_sync_job.rb +13 -9
- data/app/jobs/shipit/update_github_last_deployed_ref_job.rb +1 -1
- data/app/models/shipit/anonymous_user.rb +6 -2
- data/app/models/shipit/check_run.rb +36 -0
- data/app/models/shipit/commit.rb +20 -9
- data/app/models/shipit/commit_checks.rb +13 -13
- data/app/models/shipit/commit_deployment.rb +3 -3
- data/app/models/shipit/commit_deployment_status.rb +3 -3
- data/app/models/shipit/deploy.rb +16 -11
- data/app/models/shipit/deploy_spec/lerna_discovery.rb +12 -4
- data/app/models/shipit/duration.rb +2 -0
- data/app/models/shipit/hook.rb +26 -2
- data/app/models/shipit/merge_request.rb +9 -7
- data/app/models/shipit/pull_request.rb +1 -1
- data/app/models/shipit/release_status.rb +1 -1
- data/app/models/shipit/repository.rb +9 -3
- data/app/models/shipit/review_stack.rb +16 -2
- data/app/models/shipit/stack.rb +59 -25
- data/app/models/shipit/status/group.rb +1 -1
- data/app/models/shipit/task.rb +6 -2
- data/app/models/shipit/task_execution_strategy/default.rb +4 -5
- data/app/models/shipit/team.rb +4 -2
- data/app/models/shipit/user.rb +4 -0
- data/app/models/shipit/webhooks/handlers/pull_request/review_stack_adapter.rb +1 -1
- data/app/models/shipit/webhooks/handlers/push_handler.rb +4 -1
- data/app/serializers/shipit/merge_request_serializer.rb +1 -1
- data/app/validators/subset_validator.rb +1 -1
- data/app/views/layouts/merge_status.html.erb +1 -1
- data/app/views/shipit/stacks/_banners.html.erb +2 -1
- data/app/views/shipit/stacks/new.html.erb +1 -1
- data/config/secrets.development.example.yml +24 -0
- data/config/secrets.development.shopify.yml +20 -9
- data/db/migrate/20210325194053_remove_stacks_branch_default.rb +5 -0
- data/db/migrate/20210504200438_add_github_updated_at_to_check_runs.rb +5 -0
- data/lib/shipit.rb +39 -15
- data/lib/shipit/command.rb +7 -6
- data/lib/shipit/commands.rb +9 -2
- data/lib/shipit/engine.rb +2 -0
- data/lib/shipit/flock.rb +8 -1
- data/lib/shipit/github_app.rb +7 -5
- data/lib/shipit/octokit_iterator.rb +3 -3
- data/lib/shipit/simple_message_verifier.rb +2 -2
- data/lib/shipit/stack_commands.rb +28 -4
- data/lib/shipit/task_commands.rb +6 -0
- data/lib/shipit/version.rb +1 -1
- data/lib/snippets/publish-lerna-independent-packages +35 -34
- data/lib/snippets/publish-lerna-independent-packages-legacy +39 -0
- data/test/controllers/api/ccmenu_controller_test.rb +1 -1
- data/test/controllers/api/deploys_controller_test.rb +17 -0
- data/test/controllers/api/stacks_controller_test.rb +21 -7
- data/test/controllers/webhooks_controller_test.rb +26 -11
- data/test/dummy/app/assets/config/manifest.js +3 -0
- data/test/dummy/config/application.rb +1 -1
- data/test/dummy/config/database.yml +9 -0
- data/test/dummy/config/environments/development.rb +1 -1
- data/test/dummy/config/secrets_double_github_app.yml +79 -0
- data/test/dummy/db/schema.rb +5 -4
- data/test/dummy/db/seeds.rb +1 -0
- data/test/fixtures/payloads/check_suite_master.json +2 -30
- data/test/fixtures/payloads/push_master.json +1 -1
- data/test/fixtures/payloads/push_not_master.json +1 -1
- data/test/fixtures/shipit/commits.yml +2 -2
- data/test/fixtures/shipit/hooks.yml +1 -0
- data/test/fixtures/shipit/tasks.yml +1 -1
- data/test/helpers/json_helper.rb +5 -1
- data/test/jobs/github_sync_job_test.rb +2 -1
- data/test/models/commit_deployment_status_test.rb +3 -3
- data/test/models/commits_test.rb +2 -0
- data/test/models/deploy_spec_test.rb +7 -0
- data/test/models/deploys_test.rb +18 -0
- data/test/models/hook_test.rb +30 -1
- data/test/models/merge_request_test.rb +19 -4
- data/test/models/shipit/check_run_test.rb +124 -5
- data/test/models/shipit/review_stack_test.rb +38 -6
- data/test/models/shipit/stacks_test.rb +42 -4
- data/test/models/shipit/webhooks/handlers/pull_request/review_stack_adapter_test.rb +24 -0
- data/test/models/tasks_test.rb +22 -0
- data/test/test_helper.rb +15 -0
- data/test/unit/anonymous_user_serializer_test.rb +1 -1
- data/test/unit/command_test.rb +5 -0
- data/test/unit/commit_serializer_test.rb +1 -1
- data/test/unit/deploy_commands_test.rb +70 -14
- data/test/unit/deploy_serializer_test.rb +1 -1
- data/test/unit/github_app_test.rb +2 -3
- data/test/unit/github_apps_test.rb +416 -0
- data/test/unit/shipit_deployment_checks_test.rb +77 -0
- data/test/unit/shipit_test.rb +14 -0
- data/test/unit/user_serializer_test.rb +1 -1
- metadata +202 -191
|
@@ -9,13 +9,130 @@ module Shipit
|
|
|
9
9
|
@check_run = shipit_check_runs(:second_pending_travis)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
test ".create_or_update_from_github! updates successfully" do
|
|
13
|
+
completed_at = Time.now
|
|
14
|
+
assert_difference -> { @commit.check_runs.count }, +1 do
|
|
15
|
+
@commit.check_runs.create_or_update_from_github!(
|
|
16
|
+
@stack.id,
|
|
17
|
+
github_check_run(conclusion: nil, completed_at: '2021-04-29T18:05:12Z')
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
assert_no_enqueued_jobs(only: RefreshCheckRunsJob) do
|
|
22
|
+
@commit.check_runs.create_or_update_from_github!(
|
|
23
|
+
@stack.id,
|
|
24
|
+
github_check_run(conclusion: 'success', completed_at: completed_at + 1.minute)
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
assert_equal 'success', @commit.check_runs.last.conclusion
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
test ".create_or_update_from_github! updates successfully using latest timestamp" do
|
|
32
|
+
completed_at = Time.now
|
|
33
|
+
assert_difference -> { @commit.check_runs.count }, +1 do
|
|
34
|
+
@commit.check_runs.create_or_update_from_github!(
|
|
35
|
+
@stack.id,
|
|
36
|
+
github_check_run(conclusion: 'success', completed_at: completed_at)
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
assert_enqueued_with(job: RefreshCheckRunsJob) do
|
|
41
|
+
@commit.check_runs.create_or_update_from_github!(
|
|
42
|
+
@stack.id,
|
|
43
|
+
github_check_run(conclusion: nil, completed_at: completed_at)
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# RefreshCheckRunsJob would enqueue if the timestamp was older/equivalent
|
|
48
|
+
assert_no_enqueued_jobs(only: RefreshCheckRunsJob) do
|
|
49
|
+
@commit.check_runs.create_or_update_from_github!(
|
|
50
|
+
@stack.id,
|
|
51
|
+
github_check_run(
|
|
52
|
+
conclusion: 'action_required',
|
|
53
|
+
completed_at: completed_at,
|
|
54
|
+
started_at: completed_at + 1.minute,
|
|
55
|
+
),
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
assert_equal 'action_required', @commit.check_runs.last.conclusion
|
|
60
|
+
end
|
|
61
|
+
|
|
12
62
|
test ".create_or_update_from_github! is idempotent" do
|
|
63
|
+
completed_at = Time.now
|
|
64
|
+
assert_difference -> { @commit.check_runs.count }, +1 do
|
|
65
|
+
@commit.check_runs.create_or_update_from_github!(@stack.id, github_check_run(completed_at: completed_at))
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
assert_no_difference -> { @commit.check_runs.count } do
|
|
69
|
+
assert_no_enqueued_jobs(only: RefreshCheckRunsJob) do
|
|
70
|
+
@commit.check_runs.create_or_update_from_github!(@stack.id, github_check_run(completed_at: completed_at))
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
test ".create_or_update_from_github! enqueues refresh and updates record when new statuses have stale timestamps" do
|
|
76
|
+
completed_at = Time.now
|
|
13
77
|
assert_difference -> { @commit.check_runs.count }, +1 do
|
|
14
|
-
@commit.check_runs.create_or_update_from_github!(
|
|
78
|
+
@commit.check_runs.create_or_update_from_github!(
|
|
79
|
+
@stack.id,
|
|
80
|
+
github_check_run(conclusion: 'success', completed_at: completed_at)
|
|
81
|
+
)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
assert_equal 'success', @commit.check_runs.last.conclusion
|
|
85
|
+
|
|
86
|
+
updated_conclusion = 'action_required'
|
|
87
|
+
updated_check_run = github_check_run(conclusion: updated_conclusion, completed_at: completed_at - 1.minute)
|
|
88
|
+
|
|
89
|
+
assert_no_difference -> { @commit.check_runs.count } do
|
|
90
|
+
assert_enqueued_with(job: RefreshCheckRunsJob) do
|
|
91
|
+
@commit.check_runs.create_or_update_from_github!(@stack.id, updated_check_run)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
assert_equal updated_conclusion, @commit.check_runs.last.conclusion
|
|
96
|
+
|
|
97
|
+
# If the refresh returns the same data, then the record should end up the same, but no refresh should be necessary
|
|
98
|
+
assert_no_difference -> { @commit.check_runs.count } do
|
|
99
|
+
assert_no_enqueued_jobs(only: RefreshCheckRunsJob) do
|
|
100
|
+
@commit.check_runs.create_or_update_from_github!(@stack.id, updated_check_run)
|
|
101
|
+
end
|
|
15
102
|
end
|
|
16
103
|
|
|
104
|
+
assert_equal updated_conclusion, @commit.check_runs.last.conclusion
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
test ".create_or_update_from_github! does not enqueues refresh when old statuses has no timestamp" do
|
|
108
|
+
completed_at = Time.now
|
|
109
|
+
assert_difference -> { @commit.check_runs.count }, +1 do
|
|
110
|
+
@commit.check_runs.create_or_update_from_github!(
|
|
111
|
+
@stack.id,
|
|
112
|
+
github_check_run(conclusion: 'success', completed_at: completed_at)
|
|
113
|
+
)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
@commit.check_runs.last.update!(github_updated_at: nil)
|
|
117
|
+
|
|
118
|
+
assert_no_difference -> { @commit.check_runs.count } do
|
|
119
|
+
assert_no_enqueued_jobs(only: RefreshCheckRunsJob) do
|
|
120
|
+
@commit.check_runs.create_or_update_from_github!(
|
|
121
|
+
@stack.id,
|
|
122
|
+
github_check_run(conclusion: nil, completed_at: completed_at - 1.minute)
|
|
123
|
+
)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
test ".create_or_update_from_github! enqueues refresh when new statuses have no timestamps" do
|
|
17
129
|
assert_no_difference -> { @commit.check_runs.count } do
|
|
18
|
-
|
|
130
|
+
assert_enqueued_with(job: RefreshCheckRunsJob, args: [stack_id: @stack.id]) do
|
|
131
|
+
@commit.check_runs.create_or_update_from_github!(
|
|
132
|
+
@stack.id,
|
|
133
|
+
github_check_run(conclusion: nil, completed_at: nil, started_at: nil)
|
|
134
|
+
)
|
|
135
|
+
end
|
|
19
136
|
end
|
|
20
137
|
end
|
|
21
138
|
|
|
@@ -36,16 +153,18 @@ module Shipit
|
|
|
36
153
|
|
|
37
154
|
private
|
|
38
155
|
|
|
39
|
-
def github_check_run
|
|
40
|
-
|
|
156
|
+
def github_check_run(conclusion: 'success', completed_at: Time.now, started_at: Time.now - 1.minute)
|
|
157
|
+
OpenStruct.new(
|
|
41
158
|
id: 424_242,
|
|
42
|
-
conclusion:
|
|
159
|
+
conclusion: conclusion,
|
|
43
160
|
output: OpenStruct.new(
|
|
44
161
|
description: 'This is a description',
|
|
45
162
|
),
|
|
46
163
|
name: 'Test Suite',
|
|
47
164
|
html_url: 'http://example.com/run',
|
|
48
165
|
details_url: 'http://example.com/details',
|
|
166
|
+
completed_at: completed_at,
|
|
167
|
+
started_at: started_at,
|
|
49
168
|
)
|
|
50
169
|
end
|
|
51
170
|
end
|
|
@@ -9,12 +9,20 @@ module Shipit
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
test "clearing stale caches" do
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
stale_stack = shipit_stacks(:archived_6hours_ago)
|
|
13
|
+
FileUtils.mkdir_p(stale_stack.base_path)
|
|
14
|
+
path = File.join(stale_stack.base_path, 'foo')
|
|
15
|
+
File.write(path, 'bar')
|
|
16
|
+
|
|
17
|
+
not_stale_stack = shipit_stacks(:archived_30minutes_ago)
|
|
18
|
+
FileUtils.mkdir_p(not_stale_stack.base_path)
|
|
19
|
+
path = File.join(not_stale_stack.base_path, 'foo')
|
|
20
|
+
File.write(path, 'bar')
|
|
21
|
+
|
|
22
|
+
ReviewStack.clear_stale_caches
|
|
23
|
+
|
|
24
|
+
refute File.exist?(stale_stack.base_path)
|
|
25
|
+
assert File.exist?(not_stale_stack.base_path)
|
|
18
26
|
end
|
|
19
27
|
|
|
20
28
|
test "creating a review stack emits a hook" do
|
|
@@ -55,5 +63,29 @@ module Shipit
|
|
|
55
63
|
assert_equal stack.env["WIP"], "true"
|
|
56
64
|
assert_equal stack.env["BUG"], "true"
|
|
57
65
|
end
|
|
66
|
+
|
|
67
|
+
test "#unarchive! triggers a GithubSync job" do
|
|
68
|
+
stack = shipit_stacks(:review_stack)
|
|
69
|
+
assert_no_enqueued_jobs(only: GithubSyncJob) do
|
|
70
|
+
stack.archive!(shipit_users(:codertocat))
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
assert_enqueued_with(job: GithubSyncJob, args: [stack_id: stack.id]) do
|
|
74
|
+
stack.unarchive!
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
test "#trigger_continuous_delivery does not enqueue deployment ref update job" do
|
|
79
|
+
Shipit.stubs(:update_latest_deployed_ref).returns(true)
|
|
80
|
+
@stack = shipit_stacks(:review_stack)
|
|
81
|
+
assert_no_enqueued_jobs(only: Shipit::UpdateGithubLastDeployedRefJob) do
|
|
82
|
+
task = @stack.trigger_continuous_delivery
|
|
83
|
+
task.update!(status: "running")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
assert_no_enqueued_jobs(only: Shipit::UpdateGithubLastDeployedRefJob) do
|
|
87
|
+
@stack.last_active_task.complete!
|
|
88
|
+
end
|
|
89
|
+
end
|
|
58
90
|
end
|
|
59
91
|
end
|
|
@@ -10,10 +10,20 @@ module Shipit
|
|
|
10
10
|
GithubHook.any_instance.stubs(:teardown!)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
test "branch defaults to
|
|
13
|
+
test "branch defaults to default branch name" do
|
|
14
14
|
@stack.branch = ""
|
|
15
|
+
Shipit.github.api.expects(:repo).with("shopify/shipit-engine").returns(
|
|
16
|
+
Struct.new(:default_branch).new('something')
|
|
17
|
+
)
|
|
15
18
|
assert @stack.save
|
|
16
|
-
assert_equal '
|
|
19
|
+
assert_equal 'something', @stack.branch
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
test "branch is blank when default cannot be determined" do
|
|
23
|
+
@stack.branch = ""
|
|
24
|
+
Shipit.github.api.expects(:repo).raises(Octokit::NotFound)
|
|
25
|
+
assert_not @stack.save
|
|
26
|
+
assert_nil @stack.branch
|
|
17
27
|
end
|
|
18
28
|
|
|
19
29
|
test "environment defaults to production" do
|
|
@@ -201,7 +211,7 @@ module Shipit
|
|
|
201
211
|
|
|
202
212
|
test "#create queues a GithubSyncJob" do
|
|
203
213
|
assert_enqueued_with(job: GithubSyncJob) do
|
|
204
|
-
Stack.create!(repository: shipit_repositories(:rails))
|
|
214
|
+
Stack.create!(repository: shipit_repositories(:rails), branch: 'main')
|
|
205
215
|
end
|
|
206
216
|
end
|
|
207
217
|
|
|
@@ -252,6 +262,7 @@ module Shipit
|
|
|
252
262
|
stack = Stack.create!(
|
|
253
263
|
repository: Repository.new(owner: "foo", name: "bar"),
|
|
254
264
|
environment: 'production',
|
|
265
|
+
branch: 'main',
|
|
255
266
|
)
|
|
256
267
|
commit = shipit_commits(:first)
|
|
257
268
|
stack.commits << commit
|
|
@@ -362,13 +373,24 @@ module Shipit
|
|
|
362
373
|
end
|
|
363
374
|
|
|
364
375
|
test "the git cache lock prevent concurrent access to the git cache" do
|
|
365
|
-
@stack.
|
|
376
|
+
second_stack = Shipit::Stack.find(@stack.id)
|
|
377
|
+
second_stack.acquire_git_cache_lock do
|
|
366
378
|
assert_raises Flock::TimeoutError do
|
|
367
379
|
@stack.acquire_git_cache_lock(timeout: 0.1) {}
|
|
368
380
|
end
|
|
369
381
|
end
|
|
370
382
|
end
|
|
371
383
|
|
|
384
|
+
test "the git cache lock is reentrant if called on the same Stack instance" do
|
|
385
|
+
called = false
|
|
386
|
+
@stack.acquire_git_cache_lock(timeout: 0.01) do
|
|
387
|
+
@stack.acquire_git_cache_lock(timeout: 0.01) do
|
|
388
|
+
called = true
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
assert called
|
|
392
|
+
end
|
|
393
|
+
|
|
372
394
|
test "the git cache lock is scoped to the stack" do
|
|
373
395
|
called = false
|
|
374
396
|
shipit_stacks(:cyclimse).acquire_git_cache_lock do
|
|
@@ -926,6 +948,22 @@ module Shipit
|
|
|
926
948
|
)
|
|
927
949
|
end
|
|
928
950
|
|
|
951
|
+
test "#unarchive! triggers a GithubSync job" do
|
|
952
|
+
assert_no_enqueued_jobs(only: GithubSyncJob) do
|
|
953
|
+
@stack.archive!(shipit_users(:codertocat))
|
|
954
|
+
end
|
|
955
|
+
|
|
956
|
+
assert_enqueued_with(job: GithubSyncJob, args: [stack_id: @stack.id]) do
|
|
957
|
+
@stack.unarchive!
|
|
958
|
+
end
|
|
959
|
+
end
|
|
960
|
+
|
|
961
|
+
test "#update that changes the branch name triggers a GithubSync job" do
|
|
962
|
+
assert_enqueued_with(job: GithubSyncJob, args: [stack_id: @stack.id]) do
|
|
963
|
+
@stack.update!(branch: 'test')
|
|
964
|
+
end
|
|
965
|
+
end
|
|
966
|
+
|
|
929
967
|
private
|
|
930
968
|
|
|
931
969
|
def generate_revert_commit(stack:, reverted_commit:, author: reverted_commit.author)
|
|
@@ -19,6 +19,30 @@ module Shipit
|
|
|
19
19
|
review_stack.unarchive!
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
test "unarchive! syncs with GitHub" do
|
|
23
|
+
stack = create_archived_stack
|
|
24
|
+
review_stack = Shipit::Webhooks::Handlers::PullRequest::ReviewStackAdapter.new(
|
|
25
|
+
params_for(stack),
|
|
26
|
+
scope: stack.repository.stacks
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
assert_enqueued_with(job: GithubSyncJob, args: [stack_id: stack.id]) do
|
|
30
|
+
review_stack.unarchive!
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
test "unarchive! schedules provisioning" do
|
|
35
|
+
stack = create_archived_stack
|
|
36
|
+
review_stack = Shipit::Webhooks::Handlers::PullRequest::ReviewStackAdapter.new(
|
|
37
|
+
params_for(stack),
|
|
38
|
+
scope: stack.repository.stacks
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
assert_changes -> { stack.reload.awaiting_provision }, from: false, to: true do
|
|
42
|
+
review_stack.unarchive!
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
22
46
|
test "archive! on an archived stack is a no-op" do
|
|
23
47
|
stack = create_archived_stack
|
|
24
48
|
review_stack = Shipit::Webhooks::Handlers::PullRequest::ReviewStackAdapter.new(
|
data/test/models/tasks_test.rb
CHANGED
|
@@ -88,5 +88,27 @@ module Shipit
|
|
|
88
88
|
task_with_zero_retries = shipit_tasks(:shipit_restart)
|
|
89
89
|
refute_predicate task_with_zero_retries, :retries_configured?
|
|
90
90
|
end
|
|
91
|
+
|
|
92
|
+
test ".due_for_rollup includes tasks in successful terminal states" do
|
|
93
|
+
task = shipit_tasks(:shipit)
|
|
94
|
+
task.update(
|
|
95
|
+
rolled_up: false,
|
|
96
|
+
created_at: (60 + 1).minutes.ago.to_s(:db),
|
|
97
|
+
status: "success",
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
assert_includes Shipit::Task.due_for_rollup, task
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
test ".due_for_rollup includes tasks in unsuccessful terminal states" do
|
|
104
|
+
task = shipit_tasks(:shipit)
|
|
105
|
+
task.update(
|
|
106
|
+
rolled_up: false,
|
|
107
|
+
created_at: (60 + 1).minutes.ago.to_s(:db),
|
|
108
|
+
status: "error",
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
assert_includes Shipit::Task.due_for_rollup, task
|
|
112
|
+
end
|
|
91
113
|
end
|
|
92
114
|
end
|
data/test/test_helper.rb
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
ENV["RAILS_ENV"] ||= "test"
|
|
3
3
|
|
|
4
|
+
if Warning.respond_to?(:[]=)
|
|
5
|
+
Warning[:deprecated] = true
|
|
6
|
+
end
|
|
7
|
+
|
|
4
8
|
require 'simplecov'
|
|
5
9
|
SimpleCov.start('rails') do
|
|
6
10
|
enable_coverage :branch
|
|
@@ -32,6 +36,17 @@ begin
|
|
|
32
36
|
rescue LoadError
|
|
33
37
|
end
|
|
34
38
|
|
|
39
|
+
# FIXME: We need to get rid of active_model_serializers
|
|
40
|
+
# This is a monkey patch for Ruby 2.7+ compatibility
|
|
41
|
+
module ActionController
|
|
42
|
+
module SerializationAssertions
|
|
43
|
+
def process(*, **)
|
|
44
|
+
@serializers = Hash.new(0)
|
|
45
|
+
super
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
35
50
|
module ActiveSupport
|
|
36
51
|
class TestCase
|
|
37
52
|
include PayloadsHelper
|
|
@@ -8,7 +8,7 @@ module Shipit
|
|
|
8
8
|
serializer = ActiveModel::Serializer.serializer_for(user)
|
|
9
9
|
assert_equal AnonymousUserSerializer, serializer
|
|
10
10
|
serialized = serializer.new(user).to_json
|
|
11
|
-
|
|
11
|
+
assert_json_document(serialized, "anonymous", true)
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
end
|
data/test/unit/command_test.rb
CHANGED
|
@@ -34,6 +34,11 @@ module Shipit
|
|
|
34
34
|
ENV['SHIPIT_TEST'] = previous
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
test "#env cast to strings except for `nil`" do
|
|
38
|
+
command = Command.new('echo foo', env: { 'SOME_PATH' => Pathname.new('/foo'), 'HOST' => nil }, chdir: '.')
|
|
39
|
+
assert_equal({ 'SOME_PATH' => '/foo', 'HOST' => nil }, command.env)
|
|
40
|
+
end
|
|
41
|
+
|
|
37
42
|
test "#timeout is 5 minutes by default" do
|
|
38
43
|
command = Command.new('cap $LANG deploy', env: { 'ENVIRONMENT' => 'production' }, chdir: '.')
|
|
39
44
|
assert_equal 5.minutes.to_i, command.timeout
|
|
@@ -10,7 +10,7 @@ module Shipit
|
|
|
10
10
|
assert_equal CommitSerializer, serializer
|
|
11
11
|
serialized = serializer.new(commit).to_json
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
assert_json_document(serialized, "author.name", commit.author.name)
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
end
|
|
@@ -4,8 +4,9 @@ require 'test_helper'
|
|
|
4
4
|
module Shipit
|
|
5
5
|
class DeployCommandsTest < ActiveSupport::TestCase
|
|
6
6
|
def setup
|
|
7
|
-
@stack = shipit_stacks(:shipit)
|
|
8
7
|
@deploy = shipit_deploys(:shipit_pending)
|
|
8
|
+
@stack = @deploy.stack
|
|
9
|
+
@stack.stubs(:clear_git_cache!)
|
|
9
10
|
@commands = DeployCommands.new(@deploy)
|
|
10
11
|
@deploy_spec = stub(
|
|
11
12
|
dependencies_steps!: ['bundle install --some-args'],
|
|
@@ -21,42 +22,97 @@ module Shipit
|
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
test "#fetch calls git fetch if repository cache already exist" do
|
|
24
|
-
|
|
25
|
+
@stack.git_path.stubs(:exist?).returns(true)
|
|
26
|
+
@stack.git_path.stubs(:empty?).returns(false)
|
|
27
|
+
|
|
25
28
|
command = @commands.fetch
|
|
29
|
+
|
|
26
30
|
assert_equal %w(git fetch origin --tags master), command.args
|
|
27
31
|
end
|
|
28
32
|
|
|
29
33
|
test "#fetch calls git fetch in git_path directory if repository cache already exist" do
|
|
30
|
-
|
|
34
|
+
@stack.git_path.stubs(:exist?).returns(true)
|
|
35
|
+
@stack.git_path.stubs(:empty?).returns(false)
|
|
36
|
+
|
|
31
37
|
command = @commands.fetch
|
|
32
|
-
|
|
38
|
+
|
|
39
|
+
assert_equal @stack.git_path.to_s, command.chdir
|
|
33
40
|
end
|
|
34
41
|
|
|
35
42
|
test "#fetch calls git clone if repository cache do not exist" do
|
|
36
|
-
|
|
43
|
+
@stack.git_path.stubs(:exist?).returns(false)
|
|
44
|
+
|
|
45
|
+
command = @commands.fetch
|
|
46
|
+
|
|
47
|
+
expected = %W(git clone --single-branch --recursive --branch master #{@stack.repo_git_url} #{@stack.git_path})
|
|
48
|
+
assert_equal expected, command.args.map(&:to_s)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
test "#fetch calls git clone if repository cache is empty" do
|
|
52
|
+
@stack.git_path.stubs(:exist?).returns(true)
|
|
53
|
+
@stack.git_path.stubs(:empty?).returns(true)
|
|
54
|
+
|
|
55
|
+
command = @commands.fetch
|
|
56
|
+
|
|
57
|
+
expected = %W(git clone --single-branch --recursive --branch master #{@stack.repo_git_url} #{@stack.git_path})
|
|
58
|
+
assert_equal expected, command.args
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
test "#fetch calls git clone if repository cache corrupt" do
|
|
62
|
+
@stack.git_path.stubs(:exist?).returns(true)
|
|
63
|
+
@stack.git_path.stubs(:empty?).returns(false)
|
|
64
|
+
StackCommands.any_instance.expects(:git_cmd_succeeds?)
|
|
65
|
+
.with(@stack.git_path)
|
|
66
|
+
.returns(false)
|
|
67
|
+
|
|
37
68
|
command = @commands.fetch
|
|
69
|
+
|
|
70
|
+
expected = %W(git clone --single-branch --recursive --branch master #{@stack.repo_git_url} #{@stack.git_path})
|
|
71
|
+
assert_equal expected, command.args
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
test "#fetch clears a corrupted git stash before cloning" do
|
|
75
|
+
@stack.expects(:clear_git_cache!)
|
|
76
|
+
@stack.git_path.stubs(:exist?).returns(true)
|
|
77
|
+
@stack.git_path.stubs(:empty?).returns(false)
|
|
78
|
+
StackCommands.any_instance.expects(:git_cmd_succeeds?)
|
|
79
|
+
.with(@stack.git_path)
|
|
80
|
+
.returns(false)
|
|
81
|
+
|
|
82
|
+
command = @commands.fetch
|
|
83
|
+
|
|
38
84
|
expected = %W(git clone --single-branch --recursive --branch master #{@stack.repo_git_url} #{@stack.git_path})
|
|
39
85
|
assert_equal expected, command.args
|
|
40
86
|
end
|
|
41
87
|
|
|
42
88
|
test "#fetch does not use --single-branch if git is outdated" do
|
|
43
|
-
|
|
89
|
+
@stack.git_path.stubs(:exist?).returns(false)
|
|
44
90
|
StackCommands.stubs(git_version: Gem::Version.new('1.7.2.30'))
|
|
91
|
+
|
|
45
92
|
command = @commands.fetch
|
|
93
|
+
|
|
46
94
|
expected = %W(git clone --recursive --branch master #{@stack.repo_git_url} #{@stack.git_path})
|
|
47
|
-
assert_equal expected, command.args
|
|
95
|
+
assert_equal expected, command.args.map(&:to_s)
|
|
48
96
|
end
|
|
49
97
|
|
|
50
98
|
test "#fetch calls git fetch in base_path directory if repository cache do not exist" do
|
|
51
|
-
|
|
99
|
+
@stack.git_path.stubs(:exist?).returns(false)
|
|
100
|
+
|
|
52
101
|
command = @commands.fetch
|
|
53
|
-
|
|
102
|
+
|
|
103
|
+
assert_equal @stack.deploys_path.to_s, command.chdir
|
|
54
104
|
end
|
|
55
105
|
|
|
56
106
|
test "#fetch merges Shipit.env in ENVIRONMENT" do
|
|
57
107
|
Shipit.stubs(:env).returns("SPECIFIC_CONFIG" => 5)
|
|
58
108
|
command = @commands.fetch
|
|
59
|
-
assert_equal 5, command.env["SPECIFIC_CONFIG"]
|
|
109
|
+
assert_equal '5', command.env["SPECIFIC_CONFIG"]
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
test "#env uses the correct Github token for a stack" do
|
|
113
|
+
Shipit.github(organization: 'shopify').stubs(:token).returns('aS3cr3Tt0kEn')
|
|
114
|
+
command = @commands.fetch
|
|
115
|
+
assert_equal 'aS3cr3Tt0kEn', command.env["GITHUB_TOKEN"]
|
|
60
116
|
end
|
|
61
117
|
|
|
62
118
|
test "#clone clones the repository cache into the working directory" do
|
|
@@ -65,15 +121,15 @@ module Shipit
|
|
|
65
121
|
clone_args = [
|
|
66
122
|
'git', 'clone', '--quiet',
|
|
67
123
|
'--local', '--origin', 'cache',
|
|
68
|
-
@stack.git_path, @deploy.working_directory
|
|
124
|
+
@stack.git_path.to_s, @deploy.working_directory,
|
|
69
125
|
]
|
|
70
126
|
assert_equal clone_args, commands.first.args
|
|
71
|
-
assert_equal ['git', 'remote', 'add', 'origin', @stack.repo_git_url], commands.second.args
|
|
127
|
+
assert_equal ['git', 'remote', 'add', 'origin', @stack.repo_git_url.to_s], commands.second.args
|
|
72
128
|
end
|
|
73
129
|
|
|
74
130
|
test "#clone clones the repository cache from the deploys_path" do
|
|
75
131
|
commands = @commands.clone
|
|
76
|
-
assert_equal @stack.deploys_path, commands.first.chdir
|
|
132
|
+
assert_equal @stack.deploys_path.to_s, commands.first.chdir
|
|
77
133
|
end
|
|
78
134
|
|
|
79
135
|
test "#checkout checks out the deployed commit" do
|
|
@@ -182,7 +238,7 @@ module Shipit
|
|
|
182
238
|
test "#install_dependencies merges Shipit.env in ENVIRONMENT" do
|
|
183
239
|
Shipit.stubs(:env).returns("SPECIFIC_CONFIG" => 5)
|
|
184
240
|
command = @commands.install_dependencies.first
|
|
185
|
-
assert_equal 5, command.env["SPECIFIC_CONFIG"]
|
|
241
|
+
assert_equal '5', command.env["SPECIFIC_CONFIG"]
|
|
186
242
|
end
|
|
187
243
|
|
|
188
244
|
test "#install_dependencies merges machine_env in ENVIRONMENT" do
|