shipit-engine 0.20.1 → 0.21.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 +5 -5
- data/README.md +43 -6
- data/app/assets/stylesheets/_base/_base.scss +4 -0
- data/app/assets/stylesheets/_pages/_commits.scss +3 -1
- data/app/assets/stylesheets/_pages/_deploy.scss +4 -2
- data/app/controllers/concerns/shipit/authentication.rb +1 -1
- data/app/controllers/shipit/api/base_controller.rb +6 -1
- data/app/controllers/shipit/api/pull_requests_controller.rb +1 -1
- data/app/controllers/shipit/commit_checks_controller.rb +1 -1
- data/app/controllers/shipit/shipit_controller.rb +1 -5
- data/app/controllers/shipit/stacks_controller.rb +2 -0
- data/app/controllers/shipit/tasks_controller.rb +1 -1
- data/app/controllers/shipit/webhooks_controller.rb +2 -2
- data/app/helpers/shipit/deploys_helper.rb +9 -0
- data/app/helpers/shipit/shipit_helper.rb +17 -15
- data/app/helpers/shipit/stacks_helper.rb +6 -1
- data/app/jobs/shipit/destroy_stack_job.rb +4 -2
- data/app/jobs/shipit/fetch_deployed_revision_job.rb +1 -1
- data/app/jobs/shipit/github_sync_job.rb +1 -1
- data/app/jobs/shipit/merge_pull_requests_job.rb +3 -3
- data/app/jobs/shipit/perform_task_job.rb +3 -0
- data/app/jobs/shipit/purge_old_deliveries_job.rb +1 -0
- data/app/models/shipit/api_client.rb +1 -1
- data/app/models/shipit/commit.rb +29 -6
- data/app/models/shipit/commit_deployment.rb +1 -1
- data/app/models/shipit/commit_deployment_status.rb +1 -1
- data/app/models/shipit/deploy_spec.rb +19 -2
- data/app/models/shipit/deploy_spec/bundler_discovery.rb +1 -10
- data/app/models/shipit/deploy_spec/file_system.rb +6 -0
- data/app/models/shipit/deploy_spec/kubernetes_discovery.rb +1 -1
- data/app/models/shipit/deploy_spec/lerna_discovery.rb +85 -0
- data/app/models/shipit/deploy_spec/npm_discovery.rb +103 -5
- data/app/models/shipit/deploy_spec/pypi_discovery.rb +4 -2
- data/app/models/shipit/deploy_spec/rubygems_discovery.rb +4 -2
- data/app/models/shipit/duration.rb +1 -1
- data/app/models/shipit/github_status.rb +1 -1
- data/app/models/shipit/hook.rb +4 -5
- data/app/models/shipit/output_chunk.rb +1 -1
- data/app/models/shipit/pull_request.rb +36 -15
- data/app/models/shipit/stack.rb +15 -9
- data/app/models/shipit/status/common.rb +4 -0
- data/app/models/shipit/status/group.rb +4 -0
- data/app/models/shipit/task.rb +20 -8
- data/app/models/shipit/task_definition.rb +2 -2
- data/app/models/shipit/undeployed_commit.rb +13 -2
- data/app/models/shipit/user.rb +1 -1
- data/app/serializers/shipit/pull_request_serializer.rb +1 -1
- data/app/serializers/shipit/tail_task_serializer.rb +1 -1
- data/app/views/shipit/ccmenu/project.xml.builder +9 -8
- data/app/views/shipit/deploys/_deploy.html.erb +3 -2
- data/app/views/shipit/stacks/_banners.html.erb +4 -1
- data/app/views/shipit/stacks/settings.html.erb +4 -0
- data/app/views/shipit/statuses/_group.html.erb +1 -1
- data/app/views/shipit/statuses/_status.html.erb +1 -1
- data/app/views/shipit/tasks/_task.html.erb +1 -2
- data/config/locales/en.yml +2 -0
- data/config/secrets.development.example.yml +0 -4
- data/config/secrets.development.shopify.yml +1 -5
- data/db/migrate/20170904103242_reindex_deliveries.rb +7 -0
- data/db/migrate/20171120161420_add_base_info_to_pull_request.rb +7 -0
- data/db/migrate/20180202220850_add_aborted_by_to_tasks.rb +5 -0
- data/lib/shipit.rb +15 -23
- data/lib/shipit/command.rb +11 -3
- data/lib/shipit/engine.rb +0 -4
- data/lib/shipit/stack_commands.rb +3 -1
- data/lib/shipit/version.rb +1 -1
- data/lib/snippets/assert-lerna-fixed-version-tag +21 -0
- data/lib/snippets/assert-lerna-independent-version-tags +28 -0
- data/lib/snippets/generate-local-npmrc +19 -0
- data/lib/snippets/misconfigured-npm-publish-config +8 -0
- data/lib/snippets/publish-lerna-independent-packages +39 -0
- data/lib/snippets/push-to-heroku +5 -5
- data/lib/tasks/cron.rake +1 -1
- data/lib/tasks/dev.rake +1 -1
- data/test/controllers/api/deploys_controller_test.rb +19 -0
- data/test/controllers/api/stacks_controller_test.rb +1 -1
- data/test/controllers/github_authentication_controller_test.rb +1 -1
- data/test/controllers/stacks_controller_test.rb +10 -0
- data/test/controllers/tasks_controller_test.rb +2 -0
- data/test/controllers/webhooks_controller_test.rb +0 -7
- data/test/dummy/config/secrets.yml +0 -2
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +5 -3
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/fixtures/shipit/commits.yml +53 -0
- data/test/fixtures/shipit/pull_requests.yml +52 -0
- data/test/fixtures/shipit/stacks.yml +35 -0
- data/test/fixtures/shipit/statuses.yml +27 -0
- data/test/fixtures/shipit/tasks.yml +14 -0
- data/test/helpers/queries_helper.rb +1 -1
- data/test/jobs/merge_pull_requests_job_test.rb +19 -2
- data/test/jobs/perform_task_job_test.rb +26 -2
- data/test/models/commits_test.rb +55 -6
- data/test/models/deploy_spec_test.rb +288 -52
- data/test/models/deploys_test.rb +7 -7
- data/test/models/hook_test.rb +4 -3
- data/test/models/pull_request_test.rb +78 -24
- data/test/models/stacks_test.rb +21 -17
- data/test/models/status/group_test.rb +6 -0
- data/test/models/undeployed_commits_test.rb +9 -0
- data/test/models/users_test.rb +2 -2
- data/test/test_helper.rb +1 -1
- metadata +211 -222
- data/app/assets/javascripts/shipit_bs.js.coffee +0 -2
- data/app/assets/stylesheets/shipit_bs.scss +0 -22
- data/app/views/bootstrap/shipit/missing_settings.html.erb +0 -97
- data/app/views/bootstrap/shipit/stacks/new.html.erb +0 -44
- data/app/views/layouts/shipit_bootstrap.html.erb +0 -44
- data/lib/shipit/template_renderer_extension.rb +0 -16
|
@@ -87,3 +87,55 @@ shipit_pending_merged:
|
|
|
87
87
|
mergeable: null
|
|
88
88
|
additions: 23
|
|
89
89
|
deletions: 43
|
|
90
|
+
|
|
91
|
+
shipit_mergeable_pending_ci:
|
|
92
|
+
stack: shipit
|
|
93
|
+
number: 67
|
|
94
|
+
title: Super duper nice feature
|
|
95
|
+
merge_status: pending
|
|
96
|
+
merge_requested_at: <%= 5.minute.ago.to_s(:db) %>
|
|
97
|
+
revalidated_at: <%= 5.minute.ago.to_s(:db) %>
|
|
98
|
+
merge_requested_by: walrus
|
|
99
|
+
github_id: 424244242424241
|
|
100
|
+
api_url: https://api.github.com/repos/shopify/shipit-engine/pulls/67
|
|
101
|
+
state: open
|
|
102
|
+
branch: feature-67
|
|
103
|
+
head_id: 4
|
|
104
|
+
mergeable: true
|
|
105
|
+
additions: 23
|
|
106
|
+
deletions: 43
|
|
107
|
+
|
|
108
|
+
shipit_pending_expired:
|
|
109
|
+
stack: shipit
|
|
110
|
+
number: 68
|
|
111
|
+
title: Noice !
|
|
112
|
+
merge_status: pending
|
|
113
|
+
merge_requested_at: <%= 50.minute.ago.to_s(:db) %>
|
|
114
|
+
revalidated_at: <%= 25.minute.ago.to_s(:db) %>
|
|
115
|
+
merge_requested_by: walrus
|
|
116
|
+
github_id: 48484848484848
|
|
117
|
+
api_url: https://api.github.com/repos/shopify/shipit-engine/pulls/68
|
|
118
|
+
state: open
|
|
119
|
+
branch: feature-68
|
|
120
|
+
head_id: 8
|
|
121
|
+
mergeable: true
|
|
122
|
+
additions: 23
|
|
123
|
+
deletions: 43
|
|
124
|
+
|
|
125
|
+
cyclimse_pending_merged:
|
|
126
|
+
id: 99
|
|
127
|
+
stack: cyclimse
|
|
128
|
+
number: 66
|
|
129
|
+
merge_status: merged
|
|
130
|
+
merge_requested_by: walrus
|
|
131
|
+
merge_requested_at: <%= 3.minute.ago.to_s(:db) %>
|
|
132
|
+
merged_at: <%= 2.minute.ago.to_s(:db) %>
|
|
133
|
+
revalidated_at: <%= 3.minute.ago.to_s(:db) %>
|
|
134
|
+
github_id: 43243243243232
|
|
135
|
+
api_url: https://api.github.com/repos/shopify/cyclimse/pulls/66
|
|
136
|
+
state: closed
|
|
137
|
+
branch: feature-64
|
|
138
|
+
head_id: 8
|
|
139
|
+
mergeable: null
|
|
140
|
+
additions: 23
|
|
141
|
+
deletions: 43
|
|
@@ -123,3 +123,38 @@ undeployed_stack:
|
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
updated_at: <%= 8.days.ago.to_s(:db) %>
|
|
126
|
+
|
|
127
|
+
soc:
|
|
128
|
+
repo_owner: "shopify"
|
|
129
|
+
repo_name: "soc"
|
|
130
|
+
environment: "production"
|
|
131
|
+
branch: master
|
|
132
|
+
tasks_count: 0
|
|
133
|
+
undeployed_commits_count: 2
|
|
134
|
+
cached_deploy_spec: >
|
|
135
|
+
{
|
|
136
|
+
"machine": {"environment": {}},
|
|
137
|
+
"review": {
|
|
138
|
+
"checklist": ["foo", "bar", "baz"],
|
|
139
|
+
"monitoring": [
|
|
140
|
+
{"image": "https://example.com/monitor.png", "width": 200, "height": 300}
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
"dependencies": {"override": []},
|
|
144
|
+
"deploy": {"override": null},
|
|
145
|
+
"rollback": {"override": ["echo 'Rollback!'"]},
|
|
146
|
+
"fetch": ["echo '42'"],
|
|
147
|
+
"tasks": {
|
|
148
|
+
"restart": {
|
|
149
|
+
"action": "Restart application",
|
|
150
|
+
"description": "Restart app and job servers",
|
|
151
|
+
"steps": [
|
|
152
|
+
"cap $ENVIRONMENT deploy:restart"
|
|
153
|
+
]
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
"ci": {
|
|
157
|
+
"blocking": ["soc/compliance"]
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
updated_at: <%= 8.days.ago.to_s(:db) %>
|
|
@@ -98,3 +98,30 @@ shipit_pending_pr_success_travis:
|
|
|
98
98
|
created_at: <%= 9.days.ago.to_s(:db) %>
|
|
99
99
|
state: success
|
|
100
100
|
target_url: "http://www.example.com"
|
|
101
|
+
|
|
102
|
+
soc_first:
|
|
103
|
+
stack: soc
|
|
104
|
+
commit_id: 101 # soc_first
|
|
105
|
+
description: Woops
|
|
106
|
+
context: soc/compliance
|
|
107
|
+
created_at: <%= 9.days.ago.to_s(:db) %>
|
|
108
|
+
state: failure
|
|
109
|
+
target_url: "http://www.example.com"
|
|
110
|
+
|
|
111
|
+
soc_second:
|
|
112
|
+
stack: soc
|
|
113
|
+
commit_id: 102 # soc_second
|
|
114
|
+
description: All good
|
|
115
|
+
context: soc/compliance
|
|
116
|
+
created_at: <%= 7.days.ago.to_s(:db) %>
|
|
117
|
+
state: success
|
|
118
|
+
target_url: "http://www.example.com"
|
|
119
|
+
|
|
120
|
+
soc_third:
|
|
121
|
+
stack: soc
|
|
122
|
+
commit_id: 103 # soc_third
|
|
123
|
+
description: All good
|
|
124
|
+
context: soc/compliance
|
|
125
|
+
created_at: <%= 7.days.ago.to_s(:db) %>
|
|
126
|
+
state: success
|
|
127
|
+
target_url: "http://www.example.com"
|
|
@@ -120,3 +120,17 @@ shipit_rollback:
|
|
|
120
120
|
created_at: <%= (60 - 8).minutes.ago.to_s(:db) %>
|
|
121
121
|
started_at: <%= (60 - 8).minutes.ago.to_s(:db) %>
|
|
122
122
|
ended_at: <%= (60 - 7).minutes.ago.to_s(:db) %>
|
|
123
|
+
|
|
124
|
+
soc_deploy:
|
|
125
|
+
id: 9
|
|
126
|
+
user: walrus
|
|
127
|
+
since_commit_id: 101 # soc_first
|
|
128
|
+
until_commit_id: 101 # soc_first
|
|
129
|
+
type: Shipit::Deploy
|
|
130
|
+
stack: soc
|
|
131
|
+
status: success
|
|
132
|
+
additions: 1
|
|
133
|
+
deletions: 1
|
|
134
|
+
created_at: <%= (60 - 1).minutes.ago.to_s(:db) %>
|
|
135
|
+
started_at: <%= (60 - 1).minutes.ago.to_s(:db) %>
|
|
136
|
+
ended_at: <%= (60 - 3).minutes.ago.to_s(:db) %>
|
|
@@ -50,7 +50,7 @@ module QueriesHelper
|
|
|
50
50
|
|
|
51
51
|
# FIXME: this seems bad. we should probably have a better way to indicate
|
|
52
52
|
# the query was cached
|
|
53
|
-
return if
|
|
53
|
+
return if values[:name] == 'CACHE' || ignore.any? { |x| x =~ sql }
|
|
54
54
|
log << sql
|
|
55
55
|
end
|
|
56
56
|
end
|
|
@@ -11,6 +11,8 @@ module Shipit
|
|
|
11
11
|
@not_ready_pr = shipit_pull_requests(:shipit_pending_not_mergeable_yet)
|
|
12
12
|
@closed_pr = shipit_pull_requests(:shipit_pending_closed)
|
|
13
13
|
@merged_pr = shipit_pull_requests(:shipit_pending_merged)
|
|
14
|
+
@expired_pr = shipit_pull_requests(:shipit_pending_expired)
|
|
15
|
+
@mergable_pending_ci = shipit_pull_requests(:shipit_mergeable_pending_ci)
|
|
14
16
|
end
|
|
15
17
|
|
|
16
18
|
test "#perform rejects unmergeable PRs and merge the others" do
|
|
@@ -50,6 +52,13 @@ module Shipit
|
|
|
50
52
|
assert_predicate @pending_pr.reload, :pending?
|
|
51
53
|
end
|
|
52
54
|
|
|
55
|
+
test "#perform revalidate PRs but do not attempt to merge any if the stack doesn't allow merges" do
|
|
56
|
+
PullRequest.any_instance.stubs(:refresh!)
|
|
57
|
+
@stack.update!(lock_reason: 'Maintenance')
|
|
58
|
+
@job.perform(@stack)
|
|
59
|
+
assert_predicate @expired_pr.reload, :revalidating?
|
|
60
|
+
end
|
|
61
|
+
|
|
53
62
|
test "#perform schedules a new job if the first PR in the queue is not mergeable yet" do
|
|
54
63
|
PullRequest.any_instance.stubs(:refresh!)
|
|
55
64
|
|
|
@@ -67,11 +76,19 @@ module Shipit
|
|
|
67
76
|
assert_predicate @closed_pr.reload, :canceled?
|
|
68
77
|
end
|
|
69
78
|
|
|
70
|
-
test "#perform
|
|
79
|
+
test "#perform cancels merge requests for manually merged PRs" do
|
|
80
|
+
@pending_pr.cancel!
|
|
81
|
+
PullRequest.any_instance.stubs(:refresh!)
|
|
82
|
+
@job.perform(@stack)
|
|
83
|
+
assert_predicate @merged_pr.reload, :canceled?
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
test "#perform does not reject pull requests with pending statuses" do
|
|
71
87
|
@pending_pr.cancel!
|
|
72
88
|
PullRequest.any_instance.stubs(:refresh!)
|
|
73
89
|
@job.perform(@stack)
|
|
74
|
-
|
|
90
|
+
refute_predicate @mergable_pending_ci.reload, :rejected?
|
|
91
|
+
refute_predicate @mergable_pending_ci.reload, :merged?
|
|
75
92
|
end
|
|
76
93
|
end
|
|
77
94
|
end
|
|
@@ -67,15 +67,39 @@ module Shipit
|
|
|
67
67
|
@job.perform(@deploy)
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
test "mark deploy as error
|
|
71
|
-
Command.any_instance.expects(:stream!).at_least_once.raises(Command::
|
|
70
|
+
test "mark deploy as error an unexpected exception is raised" do
|
|
71
|
+
Command.any_instance.expects(:stream!).at_least_once.raises(Command::Denied)
|
|
72
72
|
|
|
73
73
|
@job.perform(@deploy)
|
|
74
74
|
|
|
75
75
|
assert_equal 'failed', @deploy.reload.status
|
|
76
|
+
assert_includes @deploy.chunk_output, 'Denied'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
test "mark deploy as timedout if a command timeout" do
|
|
80
|
+
Command.any_instance.expects(:stream!).at_least_once.raises(Command::TimedOut)
|
|
81
|
+
|
|
82
|
+
@job.perform(@deploy)
|
|
83
|
+
|
|
84
|
+
assert_equal 'timedout', @deploy.reload.status
|
|
76
85
|
assert_includes @deploy.chunk_output, 'TimedOut'
|
|
77
86
|
end
|
|
78
87
|
|
|
88
|
+
test "mark deploy as timedout if a command exit in one of the codes in Shipit.timeout_exit_codes" do
|
|
89
|
+
previous_exit_codes = Shipit.timeout_exit_codes
|
|
90
|
+
begin
|
|
91
|
+
Shipit.timeout_exit_codes = [70].freeze
|
|
92
|
+
|
|
93
|
+
Command.any_instance.expects(:stream!).at_least_once.raises(Command::Failed.new('Blah', 70))
|
|
94
|
+
|
|
95
|
+
@job.perform(@deploy)
|
|
96
|
+
|
|
97
|
+
assert_equal 'timedout', @deploy.reload.status
|
|
98
|
+
ensure
|
|
99
|
+
Shipit.timeout_exit_codes = previous_exit_codes
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
79
103
|
test "records stack support for rollbacks and fetching deployed revision" do
|
|
80
104
|
@job.stubs(:capture!)
|
|
81
105
|
@commands = stub(:commands)
|
data/test/models/commits_test.rb
CHANGED
|
@@ -148,8 +148,8 @@ module Shipit
|
|
|
148
148
|
author: walrus,
|
|
149
149
|
committer: walrus,
|
|
150
150
|
sha: "ab12",
|
|
151
|
-
authored_at:
|
|
152
|
-
committed_at:
|
|
151
|
+
authored_at: Time.now,
|
|
152
|
+
committed_at: Time.now,
|
|
153
153
|
message: "more fish!",
|
|
154
154
|
)
|
|
155
155
|
end
|
|
@@ -176,8 +176,8 @@ module Shipit
|
|
|
176
176
|
author: walrus,
|
|
177
177
|
committer: walrus,
|
|
178
178
|
sha: "ab12",
|
|
179
|
-
authored_at:
|
|
180
|
-
committed_at:
|
|
179
|
+
authored_at: Time.now,
|
|
180
|
+
committed_at: Time.now,
|
|
181
181
|
message: "more fish!",
|
|
182
182
|
)
|
|
183
183
|
@stack.reload
|
|
@@ -217,8 +217,8 @@ module Shipit
|
|
|
217
217
|
author: walrus,
|
|
218
218
|
committer: walrus,
|
|
219
219
|
sha: "ab12",
|
|
220
|
-
authored_at:
|
|
221
|
-
committed_at:
|
|
220
|
+
authored_at: Time.now,
|
|
221
|
+
committed_at: Time.now,
|
|
222
222
|
message: "more fish!",
|
|
223
223
|
)
|
|
224
224
|
stack.reload
|
|
@@ -306,6 +306,37 @@ module Shipit
|
|
|
306
306
|
refute_predicate commit, :deployable?
|
|
307
307
|
end
|
|
308
308
|
|
|
309
|
+
test "#deployable? is false if a blocking status is missing on a previous undeployed commit" do
|
|
310
|
+
blocking_commit = shipit_commits(:soc_second)
|
|
311
|
+
blocking_commit.statuses.delete_all
|
|
312
|
+
|
|
313
|
+
assert_predicate blocking_commit, :pending?
|
|
314
|
+
assert_predicate blocking_commit, :blocking?
|
|
315
|
+
|
|
316
|
+
commit = shipit_commits(:soc_third)
|
|
317
|
+
refute_predicate commit, :deployable?
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
test "#deployable? is false if a blocking status is failing on a previous undeployed commit" do
|
|
321
|
+
blocking_commit = shipit_commits(:soc_second)
|
|
322
|
+
blocking_commit.statuses.update_all(state: 'failure')
|
|
323
|
+
|
|
324
|
+
assert_predicate blocking_commit, :failure?
|
|
325
|
+
assert_predicate blocking_commit, :blocking?
|
|
326
|
+
|
|
327
|
+
commit = shipit_commits(:soc_third)
|
|
328
|
+
refute_predicate commit, :deployable?
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
test "#deployable? is true if no blocking status is failing or missing on a previous undeployed commit" do
|
|
332
|
+
blocking_commit = shipit_commits(:soc_second)
|
|
333
|
+
assert_predicate blocking_commit, :success?
|
|
334
|
+
refute_predicate blocking_commit, :blocking?
|
|
335
|
+
|
|
336
|
+
commit = shipit_commits(:soc_third)
|
|
337
|
+
assert_predicate commit, :deployable?
|
|
338
|
+
end
|
|
339
|
+
|
|
309
340
|
expected_webhook_transitions = { # we expect deployable_status to fire on these transitions, and not on any others
|
|
310
341
|
'unknown' => %w(pending success failure error),
|
|
311
342
|
'pending' => %w(success failure error),
|
|
@@ -551,6 +582,24 @@ module Shipit
|
|
|
551
582
|
assert revert.revert_of?(commit)
|
|
552
583
|
end
|
|
553
584
|
|
|
585
|
+
test "deploy_requested_at defaults to commit created_at" do
|
|
586
|
+
assert_equal @commit.deploy_requested_at, @commit.created_at
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
test "when merged via the queue, deploy_requested_at is merge_requested_at" do
|
|
590
|
+
commit = shipit_commits(:cyclimse_merged)
|
|
591
|
+
assert_predicate commit, :pull_request?
|
|
592
|
+
assert_equal commit.pull_request, shipit_pull_requests(:cyclimse_pending_merged)
|
|
593
|
+
assert_equal commit.deploy_requested_at, commit.pull_request.merge_requested_at
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
test "when merged manually after being queued, deploy_requested_at is created_at" do
|
|
597
|
+
pr = shipit_pull_requests(:cyclimse_pending_merged)
|
|
598
|
+
pr.cancel!
|
|
599
|
+
commit = shipit_commits(:cyclimse_merged)
|
|
600
|
+
assert_equal commit.deploy_requested_at, commit.created_at
|
|
601
|
+
end
|
|
602
|
+
|
|
554
603
|
private
|
|
555
604
|
|
|
556
605
|
def expect_event(stack)
|
|
@@ -284,11 +284,16 @@ module Shipit
|
|
|
284
284
|
'require' => [],
|
|
285
285
|
'ignore' => [],
|
|
286
286
|
'revalidate_after' => nil,
|
|
287
|
+
'max_divergence' => {
|
|
288
|
+
'commits' => nil,
|
|
289
|
+
'age' => nil,
|
|
290
|
+
},
|
|
287
291
|
},
|
|
288
292
|
'ci' => {
|
|
289
293
|
'hide' => [],
|
|
290
294
|
'allow_failures' => [],
|
|
291
295
|
'require' => [],
|
|
296
|
+
'blocking' => [],
|
|
292
297
|
},
|
|
293
298
|
'machine' => {'environment' => {}, 'directory' => nil, 'cleanup' => true},
|
|
294
299
|
'review' => {'checklist' => [], 'monitoring' => [], 'checks' => []},
|
|
@@ -318,59 +323,19 @@ module Shipit
|
|
|
318
323
|
assert_equal 'SAFETY_DISABLED', variable_definition.name
|
|
319
324
|
end
|
|
320
325
|
|
|
321
|
-
test "task definitions prepend bundle exec by default" do
|
|
322
|
-
@spec.expects(:load_config).returns('tasks' => {'restart' => {'steps' => %w(foo)}})
|
|
323
|
-
@spec.expects(:bundler?).returns(true).at_least_once
|
|
324
|
-
assert_deprecated(/Automatically prepending `bundle exec`/) do
|
|
325
|
-
definition = @spec.find_task_definition('restart')
|
|
326
|
-
assert_equal ['bundle exec foo'], definition.steps
|
|
327
|
-
end
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
test "task definitions prepend bundle exec if enabled" do
|
|
331
|
-
Shipit.expects(:automatically_prepend_bundle_exec).returns(true).at_least_once
|
|
326
|
+
test "task definitions don't prepend bundle exec by default" do
|
|
332
327
|
@spec.expects(:load_config).returns('tasks' => {'restart' => {'steps' => %w(foo)}})
|
|
333
|
-
@spec.expects(:bundler?).returns(true).at_least_once
|
|
334
328
|
definition = @spec.find_task_definition('restart')
|
|
335
|
-
|
|
336
|
-
assert_equal ['bundle exec foo'], definition.steps
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
test "task definitions do not prepend bundle exec if disabled" do
|
|
340
|
-
Shipit.expects(:automatically_prepend_bundle_exec).returns(false).at_least_once
|
|
341
|
-
@spec.expects(:load_config).returns('tasks' => {'restart' => {'steps' => %w(foo)}})
|
|
342
|
-
definition = @spec.find_task_definition('restart')
|
|
343
|
-
|
|
344
329
|
assert_equal ['foo'], definition.steps
|
|
345
330
|
end
|
|
346
331
|
|
|
347
|
-
test "task definitions
|
|
348
|
-
Shipit.expects(:automatically_prepend_bundle_exec).returns(true).at_least_once
|
|
349
|
-
@spec.expects(:load_config).returns('tasks' => {'restart' => {'steps' => ['bundle exec foo']}})
|
|
350
|
-
@spec.stubs(:bundler?).returns(true)
|
|
351
|
-
definition = @spec.find_task_definition('restart')
|
|
352
|
-
|
|
353
|
-
assert_equal ['bundle exec foo'], definition.steps
|
|
354
|
-
end
|
|
355
|
-
|
|
356
|
-
test "task definitions do not prepend bundle exec if depedency step is overridden" do
|
|
357
|
-
@spec.expects(:load_config).returns(
|
|
358
|
-
'dependencies' => {'override' => []},
|
|
359
|
-
'tasks' => {'restart' => {'steps' => %w(foo)}},
|
|
360
|
-
)
|
|
361
|
-
@spec.expects(:bundler?).returns(true).at_least_once
|
|
362
|
-
definition = @spec.find_task_definition('restart')
|
|
363
|
-
|
|
364
|
-
assert_equal ['foo'], definition.steps
|
|
365
|
-
end
|
|
366
|
-
|
|
367
|
-
test "task definitions prepend bundle exec before serialization" do
|
|
332
|
+
test "task definitions don't bundle exec before serialization" do
|
|
368
333
|
@spec.expects(:discover_task_definitions).returns('restart' => {'steps' => %w(foo)})
|
|
369
334
|
@spec.expects(:bundler?).returns(true).at_least_once
|
|
370
335
|
|
|
371
336
|
cached_spec = DeploySpec.load(DeploySpec.dump(@spec))
|
|
372
337
|
definition = cached_spec.find_task_definition('restart')
|
|
373
|
-
assert_equal ['
|
|
338
|
+
assert_equal ['foo'], definition.steps
|
|
374
339
|
end
|
|
375
340
|
|
|
376
341
|
test "#task_definitions returns kubernetes commands as well as comands from the config" do
|
|
@@ -455,6 +420,16 @@ module Shipit
|
|
|
455
420
|
assert_equal %w(ci/circleci ci/jenkins), @spec.hidden_statuses
|
|
456
421
|
end
|
|
457
422
|
|
|
423
|
+
test "#required_statuses automatically includes #blocking_statuses" do
|
|
424
|
+
@spec.expects(:load_config).returns(
|
|
425
|
+
'ci' => {
|
|
426
|
+
'require' => %w(ci/circleci),
|
|
427
|
+
'blocking' => %w(soc/compliance),
|
|
428
|
+
},
|
|
429
|
+
)
|
|
430
|
+
assert_equal %w(ci/circleci soc/compliance), @spec.required_statuses
|
|
431
|
+
end
|
|
432
|
+
|
|
458
433
|
test "pull_request_ignored_statuses defaults to the union of ci.hide and ci.allow_failures" do
|
|
459
434
|
@spec.expects(:load_config).returns(
|
|
460
435
|
'ci' => {
|
|
@@ -573,26 +548,43 @@ module Shipit
|
|
|
573
548
|
assert_equal ['fake gem task'], @spec.deploy_steps
|
|
574
549
|
end
|
|
575
550
|
|
|
551
|
+
test 'lerna monorepos take priority over solo npm deploys' do
|
|
552
|
+
@spec.expects(:discover_npm_package).never
|
|
553
|
+
@spec.stubs(:discover_lerna_packages).returns(['fake monorepo task']).once
|
|
554
|
+
|
|
555
|
+
assert_equal ['fake monorepo task'], @spec.deploy_steps
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
test '#lerna? is false if there is no lerna.json' do
|
|
559
|
+
@spec.expects(:lerna_json).returns(Shipit::Engine.root.join("tmp-#{SecureRandom.hex}"))
|
|
560
|
+
refute @spec.lerna?
|
|
561
|
+
end
|
|
562
|
+
|
|
576
563
|
test '#npm? is false if there is no package.json' do
|
|
577
564
|
@spec.expects(:package_json).returns(Shipit::Engine.root.join("tmp-#{SecureRandom.hex}"))
|
|
578
565
|
refute @spec.npm?
|
|
579
566
|
end
|
|
580
567
|
|
|
581
|
-
test '#npm? is
|
|
568
|
+
test '#npm? is true if npm package is public' do
|
|
582
569
|
file = Pathname.new('/tmp/fake_package.json')
|
|
583
|
-
file.write('{"private":
|
|
570
|
+
file.write('{"private": false}')
|
|
584
571
|
|
|
585
572
|
@spec.expects(:package_json).returns(file)
|
|
586
|
-
|
|
573
|
+
|
|
574
|
+
assert @spec.npm?
|
|
587
575
|
end
|
|
588
576
|
|
|
589
|
-
test '#npm? is
|
|
577
|
+
test '#npm? is false if npm package is private' do
|
|
590
578
|
file = Pathname.new('/tmp/fake_package.json')
|
|
591
|
-
file.write('{"private":
|
|
579
|
+
file.write('{"private": true}')
|
|
592
580
|
|
|
593
581
|
@spec.expects(:package_json).returns(file)
|
|
582
|
+
refute @spec.npm?
|
|
583
|
+
end
|
|
594
584
|
|
|
595
|
-
|
|
585
|
+
test 'lerna monorepos have a checklist' do
|
|
586
|
+
@spec.stubs(:lerna?).returns(true).at_least_once
|
|
587
|
+
assert_match(/lerna publish --skip-npm/, @spec.review_checklist[0])
|
|
596
588
|
end
|
|
597
589
|
|
|
598
590
|
test 'npm packages have a checklist' do
|
|
@@ -600,14 +592,223 @@ module Shipit
|
|
|
600
592
|
assert_match(/npm version/, @spec.review_checklist[0])
|
|
601
593
|
end
|
|
602
594
|
|
|
595
|
+
test '#lerna_version returns the monorepo root version number' do
|
|
596
|
+
file = Pathname.new('/tmp/fake_lerna.json')
|
|
597
|
+
file.write('{"version": "1.0.0-beta.1"}')
|
|
598
|
+
|
|
599
|
+
@spec.expects(:lerna_json).returns(file)
|
|
600
|
+
assert_equal '1.0.0-beta.1', @spec.lerna_version
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
test '#package_version returns the version number' do
|
|
604
|
+
file = Pathname.new('/tmp/fake_package.json')
|
|
605
|
+
file.write('{"version": "1.0.0-beta.1"}')
|
|
606
|
+
|
|
607
|
+
@spec.expects(:package_json).returns(file)
|
|
608
|
+
assert_equal '1.0.0-beta.1', @spec.package_version
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
test '#dist_tag returns "latest" if the version does not contains a standard pre-release tag' do
|
|
612
|
+
assert_equal 'latest', @spec.dist_tag('1.0.0')
|
|
613
|
+
assert_equal 'latest', @spec.dist_tag('1.0.0-shopifyv4')
|
|
614
|
+
end
|
|
615
|
+
|
|
616
|
+
test '#dist_tag returns "next" if the version contains a pre-release tag' do
|
|
617
|
+
assert_equal 'next', @spec.dist_tag('1.0.0-alpha.1')
|
|
618
|
+
assert_equal 'next', @spec.dist_tag('1.0.0-beta')
|
|
619
|
+
assert_equal 'next', @spec.dist_tag('1.0.0-rc.3')
|
|
620
|
+
assert_equal 'next', @spec.dist_tag('1.0.0-next')
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
test '#dependencies_steps returns lerna setup if a `lerna.json` is present' do
|
|
624
|
+
@spec.expects(:lerna?).returns(true).at_least_once
|
|
625
|
+
assert_equal ['npm install --no-progress', 'node_modules/.bin/lerna bootstrap'], @spec.dependencies_steps
|
|
626
|
+
end
|
|
627
|
+
|
|
603
628
|
test '#dependencies_steps returns `npm install` if a `package.json` is present' do
|
|
604
629
|
@spec.expects(:npm?).returns(true).at_least_once
|
|
605
630
|
assert_equal ['npm install --no-progress'], @spec.dependencies_steps
|
|
606
631
|
end
|
|
607
632
|
|
|
633
|
+
test '#publish_lerna_packages checks if independent version tags exist, and then invokes lerna deploy script' do
|
|
634
|
+
@spec.stubs(:lerna?).returns(true)
|
|
635
|
+
@spec.stubs(:lerna_version).returns('independent')
|
|
636
|
+
assert_equal 'assert-lerna-independent-version-tags', @spec.deploy_steps[0]
|
|
637
|
+
assert_equal 'publish-lerna-independent-packages', @spec.deploy_steps[1]
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
test '#publish_lerna_packages checks if fixed version tag exists, and then invokes lerna deploy script' do
|
|
641
|
+
@spec.stubs(:lerna?).returns(true)
|
|
642
|
+
@spec.stubs(:lerna_version).returns('1.0.0')
|
|
643
|
+
assert_equal 'assert-lerna-fixed-version-tag', @spec.deploy_steps[0]
|
|
644
|
+
assert_equal 'node_modules/.bin/lerna publish --yes --skip-git --repo-version 1.0.0 --force-publish=* --npm-tag latest', @spec.deploy_steps[1]
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
test '#enforce_publish_config? is false when Shipit.enforce_publish_config is nil' do
|
|
648
|
+
Shipit.stubs(:enforce_publish_config).returns(nil)
|
|
649
|
+
refute @spec.enforce_publish_config?
|
|
650
|
+
end
|
|
651
|
+
|
|
652
|
+
test '#enforce_publish_config? is false when Shipit.enforce_publish_config is 0' do
|
|
653
|
+
Shipit.stubs(:enforce_publish_config).returns('0')
|
|
654
|
+
refute @spec.enforce_publish_config?
|
|
655
|
+
end
|
|
656
|
+
|
|
657
|
+
test '#enforce_publish_config? is true when Shipit.enforce_publish_config is 1' do
|
|
658
|
+
Shipit.stubs(:enforce_publish_config).returns('1')
|
|
659
|
+
assert @spec.enforce_publish_config?
|
|
660
|
+
end
|
|
661
|
+
|
|
662
|
+
test '#valid_publish_config? is false when enforce_publish_config? is true and publishConfig is missing from package.json' do
|
|
663
|
+
Shipit.stubs(:private_npm_registry).returns('some_private_registry')
|
|
664
|
+
@spec.stubs(:enforce_publish_config?).returns(true)
|
|
665
|
+
@spec.stubs(:publish_config_access).returns('restricted')
|
|
666
|
+
|
|
667
|
+
package_json = Pathname.new('/tmp/fake_package.json')
|
|
668
|
+
package_json.write('{"name": "foo"}')
|
|
669
|
+
|
|
670
|
+
@spec.expects(:package_json).returns(package_json)
|
|
671
|
+
refute @spec.valid_publish_config?
|
|
672
|
+
end
|
|
673
|
+
|
|
674
|
+
test '#valid_publish_config? is true when enforce_publish_config? is true and publishConfig.access is public' do
|
|
675
|
+
Shipit.stubs(:private_npm_registry).returns('some_private_registry')
|
|
676
|
+
@spec.stubs(:enforce_publish_config?).returns(true)
|
|
677
|
+
@spec.stubs(:publish_config_access).returns('public')
|
|
678
|
+
@spec.stubs(:publish_config).returns('something')
|
|
679
|
+
|
|
680
|
+
assert @spec.valid_publish_config?
|
|
681
|
+
end
|
|
682
|
+
|
|
683
|
+
test '#valid_publish_config? is true when shipit does not enforce a publishConfig' do
|
|
684
|
+
@spec.stubs(:lerna_version).returns('1.0.0')
|
|
685
|
+
assert @spec.valid_publish_config?
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
test '#publish_config returns publishConfig from package.json' do
|
|
689
|
+
package_json = Pathname.new('/tmp/fake_package.json')
|
|
690
|
+
package_json.write('{"publishConfig": "foo"}')
|
|
691
|
+
|
|
692
|
+
@spec.expects(:package_json).returns(package_json)
|
|
693
|
+
assert_equal "foo", @spec.publish_config
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
test '#valid_publish_config_access? is false when publishConfig.access is invalid' do
|
|
697
|
+
@spec.stubs(:publish_config_access).returns('foo')
|
|
698
|
+
refute @spec.valid_publish_config_access?
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
test '#valid_publish_config_access? is true when publishConfig.access is public or restricted' do
|
|
702
|
+
@spec.stubs(:publish_config_access).returns('public')
|
|
703
|
+
assert @spec.valid_publish_config_access?
|
|
704
|
+
|
|
705
|
+
@spec.stubs(:publish_config_access).returns('restricted')
|
|
706
|
+
assert @spec.valid_publish_config_access?
|
|
707
|
+
end
|
|
708
|
+
|
|
709
|
+
test '#publish_config_access is restricted when enforce_publish_config? is true and publishConfig is missing' do
|
|
710
|
+
package_json = Pathname.new('/tmp/fake_package.json')
|
|
711
|
+
package_json.write('{"name": "@shopify/foo"}')
|
|
712
|
+
|
|
713
|
+
@spec.stubs(:enforce_publish_config?).returns(true)
|
|
714
|
+
@spec.expects(:package_json).returns(package_json)
|
|
715
|
+
assert_equal 'restricted', @spec.publish_config_access
|
|
716
|
+
end
|
|
717
|
+
|
|
718
|
+
test '#publish_config_access is public when enforce_publish_config? is false and publishConfig is missing' do
|
|
719
|
+
package_json = Pathname.new('/tmp/fake_package.json')
|
|
720
|
+
package_json.write('{"name": "@shopify/foo"}')
|
|
721
|
+
|
|
722
|
+
@spec.stubs(:enforce_publish_config?).returns(false)
|
|
723
|
+
@spec.expects(:package_json).returns(package_json)
|
|
724
|
+
assert_equal 'public', @spec.publish_config_access
|
|
725
|
+
end
|
|
726
|
+
|
|
727
|
+
test '#publish_config_access returns publishConfig.access from package.json when enforce_publish_config? is true' do
|
|
728
|
+
package_json = Pathname.new('/tmp/fake_package.json')
|
|
729
|
+
package_json.write('{
|
|
730
|
+
"name": "@shopify/foo",
|
|
731
|
+
"publishConfig": {
|
|
732
|
+
"access": "foo"
|
|
733
|
+
}
|
|
734
|
+
}')
|
|
735
|
+
|
|
736
|
+
@spec.stubs(:enforce_publish_config?).returns(false)
|
|
737
|
+
@spec.expects(:package_json).returns(package_json)
|
|
738
|
+
assert_equal 'foo', @spec.publish_config_access
|
|
739
|
+
end
|
|
740
|
+
|
|
741
|
+
test "#scoped_package? is false when Shipit.npm_org_scope is not set and the package is private" do
|
|
742
|
+
Shipit.stubs(:npm_org_scope).returns(nil)
|
|
743
|
+
@spec.stubs(:publish_config_access).returns('restricted')
|
|
744
|
+
refute @spec.scoped_package?
|
|
745
|
+
end
|
|
746
|
+
|
|
747
|
+
test "#scoped_package? is true when Shipit.npm_org_scope is set and package_name starts with scope and the package is private" do
|
|
748
|
+
Shipit.stubs(:npm_org_scope).returns('@shopify')
|
|
749
|
+
@spec.stubs(:publish_config_access).returns('restricted')
|
|
750
|
+
@spec.stubs(:package_name).returns('@shopify/polaris')
|
|
751
|
+
assert @spec.scoped_package?
|
|
752
|
+
end
|
|
753
|
+
|
|
754
|
+
test "#private_scoped_package? is false when private packages are not scoped" do
|
|
755
|
+
@spec.stubs(:scoped_package?).returns(false)
|
|
756
|
+
@spec.stubs(:publish_config_access).returns("restricted")
|
|
757
|
+
refute @spec.private_scoped_package?
|
|
758
|
+
end
|
|
759
|
+
|
|
760
|
+
test "#private_scoped_package? is true when private packages are scoped" do
|
|
761
|
+
@spec.stubs(:scoped_package?).returns(true)
|
|
762
|
+
@spec.stubs(:publish_config_access).returns("restricted")
|
|
763
|
+
assert @spec.private_scoped_package?
|
|
764
|
+
end
|
|
765
|
+
|
|
608
766
|
test '#publish_npm_package checks if version tag exists, and then invokes npm deploy script' do
|
|
609
767
|
@spec.stubs(:npm?).returns(true)
|
|
610
|
-
|
|
768
|
+
@spec.stubs(:package_version).returns('1.0.0')
|
|
769
|
+
@spec.stubs(:valid_publish_config?).returns(true)
|
|
770
|
+
@spec.stubs(:publish_config_access).returns('restricted')
|
|
771
|
+
@spec.stubs(:registry).returns("@private:registry=some_private_registry")
|
|
772
|
+
assert_equal ['assert-npm-version-tag', 'npm publish --tag latest --access restricted'], @spec.deploy_steps
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
test '#npmrc_contents returns a scoped private package configuration when the package is scoped and private' do
|
|
776
|
+
registry = "@shopify:registry=some_private_registry"
|
|
777
|
+
Shipit.stubs(:npm_org_scope).returns('@shopify')
|
|
778
|
+
Shipit.stubs(:private_npm_registry).returns('some_private_registry')
|
|
779
|
+
@spec.stubs(:scoped_package?).returns(true)
|
|
780
|
+
@spec.stubs(:publish_config_access).returns('restricted')
|
|
781
|
+
assert_equal registry, @spec.registry
|
|
782
|
+
end
|
|
783
|
+
|
|
784
|
+
test '#npmrc_contents returns a public scoped package configuration when the package is scoped and public' do
|
|
785
|
+
registry = "@shopify:registry=https://registry.npmjs.org/"
|
|
786
|
+
Shipit.stubs(:npm_org_scope).returns('@shopify')
|
|
787
|
+
@spec.stubs(:scoped_package?).returns(true)
|
|
788
|
+
@spec.stubs(:publish_config_access).returns('public')
|
|
789
|
+
assert_equal registry, @spec.registry
|
|
790
|
+
end
|
|
791
|
+
|
|
792
|
+
test '#npmrc_contents returns a public non-scoped package configuration when the package is not scoped and public' do
|
|
793
|
+
registry = "registry=https://registry.npmjs.org/"
|
|
794
|
+
@spec.stubs(:scoped_package?).returns(false)
|
|
795
|
+
@spec.stubs(:publish_config_access).returns('public')
|
|
796
|
+
assert_equal registry, @spec.registry
|
|
797
|
+
end
|
|
798
|
+
|
|
799
|
+
test '#publish_lerna_packages guesses npm tag' do
|
|
800
|
+
@spec.stubs(:lerna?).returns(true)
|
|
801
|
+
@spec.stubs(:lerna_version).returns('1.0.0-alpha.1')
|
|
802
|
+
assert_match(/--npm-tag next/, @spec.deploy_steps.last)
|
|
803
|
+
end
|
|
804
|
+
|
|
805
|
+
test '#publish_npm_package checks if version tag and a pre-release flag exist, and then invokes npm deploy script' do
|
|
806
|
+
@spec.stubs(:npm?).returns(true)
|
|
807
|
+
@spec.stubs(:package_version).returns('1.0.0-alpha.1')
|
|
808
|
+
@spec.stubs(:valid_publish_config?).returns(true)
|
|
809
|
+
@spec.stubs(:publish_config_access).returns('restricted')
|
|
810
|
+
@spec.stubs(:registry).returns("@private:registry=some_private_registry")
|
|
811
|
+
assert_equal ['assert-npm-version-tag', 'npm publish --tag next --access restricted'], @spec.deploy_steps
|
|
611
812
|
end
|
|
612
813
|
|
|
613
814
|
test 'bundler installs take priority over yarn installs' do
|
|
@@ -663,14 +864,49 @@ module Shipit
|
|
|
663
864
|
assert_equal ['yarn install --no-progress'], @spec.dependencies_steps
|
|
664
865
|
end
|
|
665
866
|
|
|
666
|
-
test '#
|
|
867
|
+
test '#publish_npm_package checks if version tag exists, and then invokes npm publish script' do
|
|
667
868
|
@spec.stubs(:yarn?).returns(true).at_least_once
|
|
668
|
-
|
|
869
|
+
@spec.stubs(:package_version).returns('1.0.0')
|
|
870
|
+
@spec.stubs(:valid_publish_config?).returns(true)
|
|
871
|
+
@spec.stubs(:publish_config_access).returns('restricted')
|
|
872
|
+
@spec.stubs(:registry).returns("@private:registry=some_private_registry")
|
|
873
|
+
assert_equal ['assert-npm-version-tag', 'npm publish --tag latest --access restricted'], @spec.deploy_steps
|
|
874
|
+
end
|
|
875
|
+
|
|
876
|
+
test '#publish_npm_package checks if version tag exists, generates npmrc, and then invokes npm publish script when enforce_publish_config? is true' do
|
|
877
|
+
@spec.stubs(:yarn?).returns(true).at_least_once
|
|
878
|
+
@spec.stubs(:package_version).returns('1.0.0')
|
|
879
|
+
@spec.stubs(:valid_publish_config?).returns(true)
|
|
880
|
+
|
|
881
|
+
@spec.stubs(:publish_config_access).returns('restricted')
|
|
882
|
+
@spec.stubs(:enforce_publish_config?).returns(true)
|
|
883
|
+
@spec.stubs(:registry).returns('fake')
|
|
884
|
+
|
|
885
|
+
generate_npmrc = 'generate-local-npmrc "fake"'
|
|
886
|
+
npm_publish = 'npm publish --tag latest --access restricted'
|
|
887
|
+
deploy_steps = ['assert-npm-version-tag', generate_npmrc, npm_publish]
|
|
888
|
+
assert_equal deploy_steps, @spec.deploy_steps
|
|
669
889
|
end
|
|
670
890
|
|
|
671
891
|
test 'yarn checklist takes precedence over npm checklist' do
|
|
672
892
|
@spec.stubs(:yarn?).returns(true).at_least_once
|
|
673
893
|
assert_match(/yarn version/, @spec.review_checklist[0])
|
|
674
894
|
end
|
|
895
|
+
|
|
896
|
+
test "max_divergence_commits defaults to `nil" do
|
|
897
|
+
@spec.expects(:load_config).returns({})
|
|
898
|
+
assert_nil @spec.max_divergence_commits
|
|
899
|
+
end
|
|
900
|
+
|
|
901
|
+
test "max_divergence_age defaults to `nil` if `merge.max_divergence.age` cannot be parsed" do
|
|
902
|
+
@spec.expects(:load_config).returns(
|
|
903
|
+
'merge' => {
|
|
904
|
+
'max_divergence' => {
|
|
905
|
+
'age' => 'badbadbad',
|
|
906
|
+
},
|
|
907
|
+
},
|
|
908
|
+
)
|
|
909
|
+
assert_nil @spec.max_divergence_age
|
|
910
|
+
end
|
|
675
911
|
end
|
|
676
912
|
end
|