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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -2
  3. data/app/assets/stylesheets/_pages/_deploy.scss +0 -2
  4. data/app/controllers/shipit/api/ccmenu_controller.rb +1 -1
  5. data/app/controllers/shipit/api/deploys_controller.rb +2 -0
  6. data/app/controllers/shipit/api/rollbacks_controller.rb +2 -1
  7. data/app/controllers/shipit/api/stacks_controller.rb +1 -0
  8. data/app/controllers/shipit/deploys_controller.rb +1 -1
  9. data/app/controllers/shipit/stacks_controller.rb +2 -2
  10. data/app/controllers/shipit/tasks_controller.rb +2 -2
  11. data/app/controllers/shipit/webhooks_controller.rb +23 -4
  12. data/app/helpers/shipit/shipit_helper.rb +0 -1
  13. data/app/jobs/shipit/deliver_hook_job.rb +1 -1
  14. data/app/jobs/shipit/github_sync_job.rb +13 -9
  15. data/app/jobs/shipit/update_github_last_deployed_ref_job.rb +1 -1
  16. data/app/models/shipit/anonymous_user.rb +6 -2
  17. data/app/models/shipit/check_run.rb +36 -0
  18. data/app/models/shipit/commit.rb +20 -9
  19. data/app/models/shipit/commit_checks.rb +13 -13
  20. data/app/models/shipit/commit_deployment.rb +3 -3
  21. data/app/models/shipit/commit_deployment_status.rb +3 -3
  22. data/app/models/shipit/deploy.rb +16 -11
  23. data/app/models/shipit/deploy_spec/lerna_discovery.rb +12 -4
  24. data/app/models/shipit/duration.rb +2 -0
  25. data/app/models/shipit/hook.rb +26 -2
  26. data/app/models/shipit/merge_request.rb +9 -7
  27. data/app/models/shipit/pull_request.rb +1 -1
  28. data/app/models/shipit/release_status.rb +1 -1
  29. data/app/models/shipit/repository.rb +9 -3
  30. data/app/models/shipit/review_stack.rb +16 -2
  31. data/app/models/shipit/stack.rb +59 -25
  32. data/app/models/shipit/status/group.rb +1 -1
  33. data/app/models/shipit/task.rb +6 -2
  34. data/app/models/shipit/task_execution_strategy/default.rb +4 -5
  35. data/app/models/shipit/team.rb +4 -2
  36. data/app/models/shipit/user.rb +4 -0
  37. data/app/models/shipit/webhooks/handlers/pull_request/review_stack_adapter.rb +1 -1
  38. data/app/models/shipit/webhooks/handlers/push_handler.rb +4 -1
  39. data/app/serializers/shipit/merge_request_serializer.rb +1 -1
  40. data/app/validators/subset_validator.rb +1 -1
  41. data/app/views/layouts/merge_status.html.erb +1 -1
  42. data/app/views/shipit/stacks/_banners.html.erb +2 -1
  43. data/app/views/shipit/stacks/new.html.erb +1 -1
  44. data/config/secrets.development.example.yml +24 -0
  45. data/config/secrets.development.shopify.yml +20 -9
  46. data/db/migrate/20210325194053_remove_stacks_branch_default.rb +5 -0
  47. data/db/migrate/20210504200438_add_github_updated_at_to_check_runs.rb +5 -0
  48. data/lib/shipit.rb +39 -15
  49. data/lib/shipit/command.rb +7 -6
  50. data/lib/shipit/commands.rb +9 -2
  51. data/lib/shipit/engine.rb +2 -0
  52. data/lib/shipit/flock.rb +8 -1
  53. data/lib/shipit/github_app.rb +7 -5
  54. data/lib/shipit/octokit_iterator.rb +3 -3
  55. data/lib/shipit/simple_message_verifier.rb +2 -2
  56. data/lib/shipit/stack_commands.rb +28 -4
  57. data/lib/shipit/task_commands.rb +6 -0
  58. data/lib/shipit/version.rb +1 -1
  59. data/lib/snippets/publish-lerna-independent-packages +35 -34
  60. data/lib/snippets/publish-lerna-independent-packages-legacy +39 -0
  61. data/test/controllers/api/ccmenu_controller_test.rb +1 -1
  62. data/test/controllers/api/deploys_controller_test.rb +17 -0
  63. data/test/controllers/api/stacks_controller_test.rb +21 -7
  64. data/test/controllers/webhooks_controller_test.rb +26 -11
  65. data/test/dummy/app/assets/config/manifest.js +3 -0
  66. data/test/dummy/config/application.rb +1 -1
  67. data/test/dummy/config/database.yml +9 -0
  68. data/test/dummy/config/environments/development.rb +1 -1
  69. data/test/dummy/config/secrets_double_github_app.yml +79 -0
  70. data/test/dummy/db/schema.rb +5 -4
  71. data/test/dummy/db/seeds.rb +1 -0
  72. data/test/fixtures/payloads/check_suite_master.json +2 -30
  73. data/test/fixtures/payloads/push_master.json +1 -1
  74. data/test/fixtures/payloads/push_not_master.json +1 -1
  75. data/test/fixtures/shipit/commits.yml +2 -2
  76. data/test/fixtures/shipit/hooks.yml +1 -0
  77. data/test/fixtures/shipit/tasks.yml +1 -1
  78. data/test/helpers/json_helper.rb +5 -1
  79. data/test/jobs/github_sync_job_test.rb +2 -1
  80. data/test/models/commit_deployment_status_test.rb +3 -3
  81. data/test/models/commits_test.rb +2 -0
  82. data/test/models/deploy_spec_test.rb +7 -0
  83. data/test/models/deploys_test.rb +18 -0
  84. data/test/models/hook_test.rb +30 -1
  85. data/test/models/merge_request_test.rb +19 -4
  86. data/test/models/shipit/check_run_test.rb +124 -5
  87. data/test/models/shipit/review_stack_test.rb +38 -6
  88. data/test/models/shipit/stacks_test.rb +42 -4
  89. data/test/models/shipit/webhooks/handlers/pull_request/review_stack_adapter_test.rb +24 -0
  90. data/test/models/tasks_test.rb +22 -0
  91. data/test/test_helper.rb +15 -0
  92. data/test/unit/anonymous_user_serializer_test.rb +1 -1
  93. data/test/unit/command_test.rb +5 -0
  94. data/test/unit/commit_serializer_test.rb +1 -1
  95. data/test/unit/deploy_commands_test.rb +70 -14
  96. data/test/unit/deploy_serializer_test.rb +1 -1
  97. data/test/unit/github_app_test.rb +2 -3
  98. data/test/unit/github_apps_test.rb +416 -0
  99. data/test/unit/shipit_deployment_checks_test.rb +77 -0
  100. data/test/unit/shipit_test.rb +14 -0
  101. data/test/unit/user_serializer_test.rb +1 -1
  102. 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!(@stack.id, github_check_run)
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
- @commit.check_runs.create_or_update_from_github!(@stack.id, github_check_run)
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
- @github_check_run ||= OpenStruct.new(
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: 'success',
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
- # Asserting that :archived_25hours_ago, :archived_30minutes_ago and :shipit are not queued.
13
- assert_enqueued_jobs 1 do
14
- assert_enqueued_with(job: Shipit::ClearGitCacheJob, args: [shipit_stacks(:archived_6hours_ago)]) do
15
- ReviewStack.clear_stale_caches
16
- end
17
- end
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 master" do
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 'master', @stack.branch
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.acquire_git_cache_lock do
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(
@@ -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
- assert_json("anonymous", true, document: serialized)
11
+ assert_json_document(serialized, "anonymous", true)
12
12
  end
13
13
  end
14
14
  end
@@ -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
- assert_json("author.name", commit.author.name, document: serialized)
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
- Dir.expects(:exist?).with(@stack.git_path).returns(true)
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
- Dir.expects(:exist?).with(@stack.git_path).returns(true)
34
+ @stack.git_path.stubs(:exist?).returns(true)
35
+ @stack.git_path.stubs(:empty?).returns(false)
36
+
31
37
  command = @commands.fetch
32
- assert_equal @stack.git_path, command.chdir
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
- Dir.expects(:exist?).with(@stack.git_path).returns(false)
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
- Dir.expects(:exist?).with(@stack.git_path).returns(false)
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
- Dir.expects(:exist?).with(@stack.git_path).returns(false)
99
+ @stack.git_path.stubs(:exist?).returns(false)
100
+
52
101
  command = @commands.fetch
53
- assert_equal @stack.deploys_path, command.chdir
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