shipit-engine 0.26.0 → 0.27.0

Sign up to get free protection for your applications and to get access to all the features.
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