shipit-engine 0.33.0 → 0.34.0

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