shipit-engine 0.26.0 → 0.27.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.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/app/assets/images/faulty.svg +9 -0
  3. data/app/assets/images/validating.svg +13 -0
  4. data/app/assets/stylesheets/_pages/_commits.scss +18 -0
  5. data/app/controllers/shipit/api/commits_controller.rb +6 -1
  6. data/app/controllers/shipit/api/deploys_controller.rb +4 -0
  7. data/app/controllers/shipit/release_statuses_controller.rb +2 -10
  8. data/app/jobs/shipit/mark_deploy_healty_job.rb +13 -0
  9. data/app/jobs/shipit/perform_task_job.rb +1 -1
  10. data/app/models/shipit/check_run.rb +8 -0
  11. data/app/models/shipit/deploy.rb +39 -16
  12. data/app/models/shipit/deploy_spec.rb +1 -1
  13. data/app/models/shipit/deploy_spec/lerna_discovery.rb +10 -7
  14. data/app/models/shipit/rollback.rb +10 -1
  15. data/app/models/shipit/stack.rb +7 -5
  16. data/app/models/shipit/task.rb +20 -6
  17. data/app/views/layouts/merge_status.html.erb +1 -1
  18. data/config/routes.rb +1 -1
  19. data/lib/shipit/version.rb +1 -1
  20. data/test/controllers/api/commits_controller_test.rb +10 -0
  21. data/test/controllers/api/deploys_controller_test.rb +11 -0
  22. data/test/controllers/merge_status_controller_test.rb +6 -1
  23. data/test/controllers/release_statuses_controller_test.rb +17 -3
  24. data/test/controllers/stacks_controller_test.rb +5 -0
  25. data/test/dummy/config/application.rb +1 -13
  26. data/test/dummy/config/initializers/0_load_development_secrets.rb +2 -2
  27. data/test/dummy/db/schema.rb +1 -1
  28. data/test/fixtures/shipit/commits.yml +65 -0
  29. data/test/fixtures/shipit/release_statuses.yml +4 -4
  30. data/test/fixtures/shipit/stacks.yml +57 -2
  31. data/test/fixtures/shipit/statuses.yml +9 -0
  32. data/test/fixtures/shipit/tasks.yml +48 -0
  33. data/test/jobs/mark_deploy_healthy_job_test.rb +23 -0
  34. data/test/jobs/perform_task_job_test.rb +30 -0
  35. data/test/models/commits_test.rb +1 -1
  36. data/test/models/deploy_spec_test.rb +2 -2
  37. data/test/models/deploys_test.rb +40 -14
  38. data/test/models/pull_request_test.rb +4 -4
  39. data/test/models/release_statuses_test.rb +2 -2
  40. data/test/models/stacks_test.rb +58 -0
  41. metadata +127 -125
  42. data/app/jobs/shipit/append_delayed_release_status_job.rb +0 -17
  43. data/test/jobs/append_delayed_release_status_job_test.rb +0 -25
@@ -10,6 +10,17 @@ module Shipit
10
10
  @commit = shipit_commits(:fifth)
11
11
  end
12
12
 
13
+ test "#deploys returns the deploys and revisions for a given stack" do
14
+ tasks = @stack.deploys_and_rollbacks.order(id: :desc)
15
+
16
+ get :index, params: {stack_id: @stack.to_param}
17
+ assert_response :ok
18
+
19
+ (0...tasks.length).each do |i|
20
+ assert_json "#{i}.id", tasks[i].id
21
+ end
22
+ end
23
+
13
24
  test "#create triggers a new deploy for the stack" do
14
25
  assert_difference -> { @stack.deploys.count }, 1 do
15
26
  post :create, params: {stack_id: @stack.to_param, sha: @commit.sha}
@@ -36,6 +36,11 @@ module Shipit
36
36
 
37
37
  test "GET show prefers stacks with merge_queue_enabled" do
38
38
  existing = shipit_stacks(:shipit)
39
+ Shipit::Stack.where(
40
+ repo_owner: existing.repo_owner,
41
+ repo_name: existing.repo_name,
42
+ ).update_all(merge_queue_enabled: false)
43
+
39
44
  Shipit::Stack.create(
40
45
  repo_owner: existing.repo_owner,
41
46
  repo_name: existing.repo_name,
@@ -43,7 +48,7 @@ module Shipit
43
48
  branch: existing.branch,
44
49
  merge_queue_enabled: true,
45
50
  )
46
- existing.update!(merge_queue_enabled: false)
51
+
47
52
  get :show, params: {referrer: 'https://github.com/Shopify/shipit-engine/pull/42', branch: 'master'}
48
53
  assert_response :ok
49
54
  assert_includes response.body, 'shipit-engine/foo'
@@ -3,12 +3,12 @@ require 'test_helper'
3
3
  module Shipit
4
4
  class ReleaseStatusesControllerTest < ActionController::TestCase
5
5
  setup do
6
- @stack = shipit_stacks(:shipit)
7
- @deploy = shipit_deploys(:shipit)
6
+ @stack = shipit_stacks(:shipit_canaries)
7
+ @deploy = shipit_deploys(:canaries_validating)
8
8
  session[:user_id] = shipit_users(:walrus).id
9
9
  end
10
10
 
11
- test ":create allow users to append release statuses" do
11
+ test ":create allow users to append release statuses and mark the deploy as success" do
12
12
  assert_difference -> { ReleaseStatus.count }, +1 do
13
13
  post :create, params: {stack_id: @stack, deploy_id: @deploy.id, status: 'success'}
14
14
  assert_response :created
@@ -18,6 +18,20 @@ module Shipit
18
18
  assert_equal 'success', status.state
19
19
  assert_equal '@walrus signaled this release as healthy.', status.description
20
20
  assert_equal @deploy.permalink, status.target_url
21
+ assert_equal 'success', @deploy.reload.status
22
+ end
23
+
24
+ test ":create allow users to append release statuses and mark the deploy as faulty" do
25
+ assert_difference -> { ReleaseStatus.count }, +1 do
26
+ post :create, params: {stack_id: @stack, deploy_id: @deploy.id, status: 'failure'}
27
+ assert_response :created
28
+ end
29
+
30
+ status = ReleaseStatus.last
31
+ assert_equal 'failure', status.state
32
+ assert_equal '@walrus signaled this release as faulty.', status.description
33
+ assert_equal @deploy.permalink, status.target_url
34
+ assert_equal 'faulty', @deploy.reload.status
21
35
  end
22
36
  end
23
37
  end
@@ -51,6 +51,11 @@ module Shipit
51
51
  assert_response :ok
52
52
  end
53
53
 
54
+ test "#show with faulty and validating deploys is success" do
55
+ get :show, params: {id: shipit_stacks(:shipit_canaries).to_param}
56
+ assert_response :ok
57
+ end
58
+
54
59
  test "#show with a single CheckRun is successful" do
55
60
  @stack = shipit_stacks(:check_runs)
56
61
  assert_not_equal 0, CheckRun.where(stack_id: @stack.id).count
@@ -12,19 +12,7 @@ end
12
12
 
13
13
  module Shipit
14
14
  class Application < Rails::Application
15
- # Settings in config/environments/* take precedence over those specified here.
16
- # Application configuration should go into files in config/initializers
17
- # -- all .rb files in that directory are automatically loaded.
18
-
19
- # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
20
- # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
21
- # config.time_zone = 'Central Time (US & Canada)'
22
-
23
- # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
24
- # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
25
- # config.i18n.default_locale = :de
26
-
27
- Rails.application.config.active_record.belongs_to_required_by_default = true
15
+ config.load_defaults 5.2
28
16
  end
29
17
  end
30
18
 
@@ -1,9 +1,9 @@
1
1
  local_secrets = Shipit::Engine.root.join('config/secrets.development.yml')
2
2
  if local_secrets.exist?
3
- secrets = YAML.load(local_secrets.read)
3
+ secrets = YAML.load(local_secrets.read).deep_symbolize_keys
4
4
  if Rails.env.development?
5
5
  Rails.application.secrets.deep_merge!(secrets)
6
6
  elsif Rails.env.test?
7
- Rails.application.secrets.merge!(redis_url: secrets['redis_url'])
7
+ Rails.application.secrets.merge!(redis_url: secrets[:redis_url])
8
8
  end
9
9
  end
@@ -10,7 +10,7 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 20181010150947) do
13
+ ActiveRecord::Schema.define(version: 2018_10_10_150947) do
14
14
 
15
15
  create_table "api_clients", force: :cascade do |t|
16
16
  t.text "permissions", limit: 65535
@@ -181,3 +181,68 @@ check_runs_first:
181
181
  additions: 42
182
182
  deletions: 24
183
183
  updated_at: <%= 8.days.ago.to_s(:db) %>
184
+
185
+ canaries_first:
186
+ id: 301
187
+ sha: 6d9278037b872fd9a6690523e411ecb3aa181355
188
+ message: "lets go"
189
+ stack: shipit_canaries
190
+ author: walrus
191
+ committer: walrus
192
+ authored_at: <%= 10.days.ago.to_s(:db) %>
193
+ committed_at: <%= 9.days.ago.to_s(:db) %>
194
+ additions: 42
195
+ deletions: 24
196
+ updated_at: <%= 8.days.ago.to_s(:db) %>
197
+
198
+ canaries_second:
199
+ id: 302
200
+ sha: f890fd8b5f2be05d1fedb763a3605ee461c39074
201
+ message: "sheep it!"
202
+ stack: shipit_canaries
203
+ author: walrus
204
+ committer: walrus
205
+ authored_at: <%= 8.days.ago.to_s(:db) %>
206
+ committed_at: <%= 7.days.ago.to_s(:db) %>
207
+ additions: 1
208
+ deletions: 1
209
+ updated_at: <%= 8.days.ago.to_s(:db) %>
210
+
211
+ canaries_third:
212
+ id: 303
213
+ sha: 367578b362bf2b4df5903e1c7960929361c39074
214
+ message: "fix it!"
215
+ stack: shipit_canaries
216
+ author: walrus
217
+ committer: walrus
218
+ authored_at: <%= 6.days.ago.to_s(:db) %>
219
+ committed_at: <%= 5.days.ago.to_s(:db) %>
220
+ additions: 12
221
+ deletions: 64
222
+ updated_at: <%= 8.days.ago.to_s(:db) %>
223
+
224
+ canaries_fourth:
225
+ id: 304
226
+ sha: 467578b362bf2b4df5903e1c7960929361c3435a
227
+ message: "Merge pull request #7 from shipit-engine/yoloshipit\n\nyoloshipit!"
228
+ stack: shipit_canaries
229
+ author: walrus
230
+ committer: walrus
231
+ authored_at: <%= 4.days.ago.to_s(:db) %>
232
+ committed_at: <%= 3.days.ago.to_s(:db) %>
233
+ additions: 420
234
+ deletions: 342
235
+ updated_at: <%= 8.days.ago.to_s(:db) %>
236
+
237
+ canaries_fifth:
238
+ id: 305
239
+ sha: 567578b362bf2b4df5903e1c7960929361c3abcd
240
+ message: "fix all the things"
241
+ stack: shipit_canaries
242
+ author: walrus
243
+ committer: walrus
244
+ authored_at: <%= 2.days.ago.to_s(:db) %>
245
+ committed_at: <%= 1.days.ago.to_s(:db) %>
246
+ additions: 1
247
+ deletions: 24
248
+ updated_at: <%= 8.days.ago.to_s(:db) %>
@@ -1,14 +1,14 @@
1
1
  to_be_created:
2
- stack: shipit
3
- commit_id: 4
2
+ stack: shipit_canaries
3
+ commit_id: 304
4
4
  user: walrus
5
5
  state: pending
6
6
  description: Deploy started
7
7
  target_url: https://example.com/deploys/42
8
8
 
9
9
  created:
10
- stack: shipit
11
- commit_id: 1
10
+ stack: shipit_canaries
11
+ commit_id: 301
12
12
  user: walrus
13
13
  state: pending
14
14
  description: Deploy started
@@ -20,9 +20,64 @@ shipit:
20
20
  "deploy": {"override": null, "interval": 60, "max_commits": 3, "variables": [{"name": "SAFETY_DISABLED", "title": "Set to 1 to do dangerous things", "default": 0}]},
21
21
  "rollback": {"override": ["echo 'Rollback!'"]},
22
22
  "fetch": ["echo '42'"],
23
+ "tasks": {
24
+ "restart": {
25
+ "action": "Restart application",
26
+ "description": "Restart app and job servers",
27
+ "variables": [
28
+ {"name": "FOO", "title": "Set to 0 to foo", "default": 1},
29
+ {"name": "BAR", "title": "Set to 1 to bar", "default": 0},
30
+ {"name": "WALRUS", "title": "Walrus without a default value"}
31
+ ],
32
+ "steps": [
33
+ "cap $ENVIRONMENT deploy:restart"
34
+ ]
35
+ },
36
+ "flush_cache": {
37
+ "action": "Flush cache",
38
+ "description": "Flush the application cache",
39
+ "steps": [
40
+ "cap $ENVIRONMENT cache:flush"
41
+ ],
42
+ "allow_concurrency": true
43
+ }
44
+ },
45
+ "merge": {
46
+ "revalidate_after": 900
47
+ },
48
+ "ci": {
49
+ "hide": ["ci/hidden"],
50
+ "allow_failures": ["ci/ok_to_fail"]
51
+ }
52
+ }
53
+ last_deployed_at: <%= 8.days.ago.to_s(:db) %>
54
+ updated_at: <%= 8.days.ago.to_s(:db) %>
55
+
56
+ shipit_canaries:
57
+ repo_owner: "shopify"
58
+ repo_name: "shipit-engine"
59
+ environment: "canaries"
60
+ branch: master
61
+ ignore_ci: false
62
+ merge_queue_enabled: true
63
+ tasks_count: 3
64
+ undeployed_commits_count: 1
65
+ cached_deploy_spec: >
66
+ {
67
+ "machine": {"environment": {}},
68
+ "review": {
69
+ "checklist": ["foo", "bar", "baz"],
70
+ "monitoring": [
71
+ {"image": "https://example.com/monitor.png", "width": 200, "height": 300}
72
+ ]
73
+ },
74
+ "dependencies": {"override": []},
75
+ "deploy": {"override": null, "max_commits": 3, "variables": [{"name": "SAFETY_DISABLED", "title": "Set to 1 to do dangerous things", "default": 0}]},
76
+ "rollback": {"override": ["echo 'Rollback!'"]},
77
+ "fetch": ["echo '42'"],
23
78
  "status": {
24
- "context": "shipit/production",
25
- "delay": 60
79
+ "context": "shipit/canaries",
80
+ "delay": 480
26
81
  },
27
82
  "tasks": {
28
83
  "restart": {
@@ -125,3 +125,12 @@ soc_third:
125
125
  created_at: <%= 7.days.ago.to_s(:db) %>
126
126
  state: success
127
127
  target_url: "http://www.example.com"
128
+
129
+ canaries_fifth_success:
130
+ stack: shipit_canaries
131
+ commit_id: 305
132
+ description: All good
133
+ context: ci/travis
134
+ created_at: <%= 7.days.ago.to_s(:db) %>
135
+ state: success
136
+ target_url: "http://www.example.com"
@@ -161,3 +161,51 @@ shipit_rendered_failover:
161
161
  created_at: <%= (60 - 3).minutes.ago.to_s(:db) %>
162
162
  started_at: <%= (60 - 3).minutes.ago.to_s(:db) %>
163
163
  ended_at: <%= (60 - 4).minutes.ago.to_s(:db) %>
164
+
165
+ canaries_success:
166
+ id: 101
167
+ stack: shipit_canaries
168
+ user: walrus
169
+ since_commit_id: 301
170
+ until_commit_id: 302
171
+ type: Shipit::Deploy
172
+ status: success
173
+ created_at: <%= (60 - 1).minutes.ago.to_s(:db) %>
174
+ started_at: <%= (60 - 1).minutes.ago.to_s(:db) %>
175
+ ended_at: <%= (60 - 3).minutes.ago.to_s(:db) %>
176
+
177
+ canaries_faulty:
178
+ id: 102
179
+ stack: shipit_canaries
180
+ user: walrus
181
+ since_commit_id: 302
182
+ until_commit_id: 303
183
+ type: Shipit::Deploy
184
+ status: faulty
185
+ created_at: <%= (60 - 4).minutes.ago.to_s(:db) %>
186
+ started_at: <%= (60 - 4).minutes.ago.to_s(:db) %>
187
+ ended_at: <%= (60 - 7).minutes.ago.to_s(:db) %>
188
+
189
+ canaries_validating:
190
+ id: 103
191
+ stack: shipit_canaries
192
+ user: walrus
193
+ since_commit_id: 303
194
+ until_commit_id: 304
195
+ type: Shipit::Deploy
196
+ status: validating
197
+ created_at: <%= (60 - 7).minutes.ago.to_s(:db) %>
198
+ started_at: <%= (60 - 7).minutes.ago.to_s(:db) %>
199
+ ended_at: <%= (60 - 10).minutes.ago.to_s(:db) %>
200
+
201
+ canaries_running:
202
+ id: 104
203
+ stack: shipit_canaries
204
+ user: walrus
205
+ since_commit_id: 304
206
+ until_commit_id: 305
207
+ type: Shipit::Deploy
208
+ status: running
209
+ created_at: <%= (60 - 7).minutes.ago.to_s(:db) %>
210
+ started_at: <%= (60 - 7).minutes.ago.to_s(:db) %>
211
+ ended_at: <%= (60 - 10).minutes.ago.to_s(:db) %>
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+
3
+ module Shipit
4
+ class MarkDeployHealthyJobTest < ActiveSupport::TestCase
5
+ setup do
6
+ @job = MarkDeployHealthyJob.new
7
+ @deploy = shipit_deploys(:canaries_validating)
8
+ end
9
+
10
+ test "#perform bails out if the deploy was marked as healthy or faulty" do
11
+ @deploy.report_faulty!
12
+ assert_no_difference -> { ReleaseStatus.count } do
13
+ @job.perform(@deploy)
14
+ end
15
+ end
16
+
17
+ test "#perform appends the new status if no other status was appended in the meantime" do
18
+ assert_difference -> { ReleaseStatus.count }, +1 do
19
+ @job.perform(@deploy)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -35,6 +35,7 @@ module Shipit
35
35
  end
36
36
 
37
37
  test "#perform enqueues a FetchDeployedRevisionJob" do
38
+ @deploy.stack.expects(:release_status?).at_least_once.returns(false)
38
39
  Dir.stubs(:chdir).yields
39
40
  DeployCommands.any_instance.expects(:perform).returns([])
40
41
  @job.stubs(:capture!)
@@ -45,10 +46,39 @@ module Shipit
45
46
  end
46
47
 
47
48
  test "marks deploy as successful" do
49
+ @deploy.stack.expects(:release_status?).at_least_once.returns(false)
48
50
  Dir.stubs(:chdir).yields
49
51
  DeployCommands.any_instance.expects(:perform).returns([])
50
52
  @job.stubs(:capture!)
51
53
 
54
+ assert_equal 'pending', @deploy.status
55
+ @job.perform(@deploy)
56
+ assert_equal 'success', @deploy.reload.status
57
+ end
58
+
59
+ test "marks deploy as validating when the stack has a positive release status delay" do
60
+ @deploy = shipit_tasks(:canaries_running)
61
+ @deploy.update_column(:status, 'pending')
62
+
63
+ Dir.stubs(:chdir).yields
64
+ DeployCommands.any_instance.expects(:perform).returns([])
65
+ @job.stubs(:capture!)
66
+
67
+ assert_equal 'pending', @deploy.status
68
+ @job.perform(@deploy)
69
+ assert_equal 'validating', @deploy.reload.status
70
+ end
71
+
72
+ test "marks deploy as successful when the stack has no release status delay" do
73
+ @deploy = shipit_tasks(:canaries_running)
74
+ @deploy.update_column(:status, 'pending')
75
+ @deploy.stack.expects(:release_status_delay).at_least_once.returns(Duration.parse(0))
76
+
77
+ Dir.stubs(:chdir).yields
78
+ DeployCommands.any_instance.expects(:perform).returns([])
79
+ @job.stubs(:capture!)
80
+
81
+ assert_equal 'pending', @deploy.status
52
82
  @job.perform(@deploy)
53
83
  assert_equal 'success', @deploy.reload.status
54
84
  end
@@ -277,7 +277,7 @@ module Shipit
277
277
  end
278
278
 
279
279
  test ".by_sha! can match sha prefixes" do
280
- assert_equal @commit, Commit.by_sha!(@commit.sha[0..7])
280
+ assert_equal @commit, shipit_stacks(:shipit).commits.by_sha!(@commit.sha[0..7])
281
281
  end
282
282
 
283
283
  test ".by_sha! raises on ambigous sha prefixes" do
@@ -355,7 +355,7 @@ module Shipit
355
355
  'review' => {'checklist' => [], 'monitoring' => [], 'checks' => []},
356
356
  'status' => {
357
357
  'context' => nil,
358
- 'delay' => nil,
358
+ 'delay' => 0,
359
359
  },
360
360
  'dependencies' => {'override' => []},
361
361
  'plugins' => {},
@@ -789,7 +789,7 @@ module Shipit
789
789
  @spec.stubs(:lerna?).returns(true)
790
790
  @spec.stubs(:lerna_version).returns('1.0.0')
791
791
  assert_equal 'assert-lerna-fixed-version-tag', @spec.deploy_steps[0]
792
- assert_equal 'node_modules/.bin/lerna publish --yes --skip-git --repo-version 1.0.0 --force-publish=* --npm-tag latest', @spec.deploy_steps[1]
792
+ assert_equal 'node_modules/.bin/lerna publish --yes --skip-git --repo-version 1.0.0 --force-publish=* --npm-tag latest --npm-client=npm --skip-npm=false', @spec.deploy_steps[1]
793
793
  end
794
794
 
795
795
  test '#enforce_publish_config? is false when Shipit.enforce_publish_config is nil' do