shipit-engine 0.38.0 → 0.39.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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -3
  3. data/app/controllers/shipit/api/base_controller.rb +2 -2
  4. data/app/controllers/shipit/api/deploys_controller.rb +5 -1
  5. data/app/models/shipit/api_client.rb +1 -1
  6. data/app/models/shipit/commit_deployment_status.rb +0 -1
  7. data/app/models/shipit/delivery.rb +1 -1
  8. data/app/models/shipit/deploy_spec/file_system.rb +14 -2
  9. data/app/models/shipit/hook.rb +1 -1
  10. data/app/models/shipit/pull_request.rb +1 -1
  11. data/app/models/shipit/stack.rb +13 -5
  12. data/app/models/shipit/task.rb +7 -3
  13. data/app/models/shipit/user.rb +2 -0
  14. data/app/views/shipit/_variables.html.erb +1 -1
  15. data/app/views/shipit/merge_status/failure.html.erb +1 -1
  16. data/app/views/shipit/missing_settings.html.erb +1 -1
  17. data/config/secrets.development.example.yml +1 -1
  18. data/config/secrets.development.shopify.yml +1 -1
  19. data/lib/shipit/engine.rb +1 -1
  20. data/lib/shipit/github_app.rb +0 -1
  21. data/lib/shipit/octokit_check_runs.rb +1 -3
  22. data/lib/shipit/stack_commands.rb +1 -1
  23. data/lib/shipit/version.rb +1 -1
  24. data/lib/shipit.rb +1 -1
  25. data/test/controllers/api/deploys_controller_test.rb +24 -0
  26. data/test/controllers/stacks_controller_test.rb +1 -1
  27. data/test/controllers/tasks_controller_test.rb +8 -1
  28. data/test/dummy/config/application.rb +2 -1
  29. data/test/dummy/config/initializers/0_load_development_secrets.rb +2 -2
  30. data/test/dummy/config/secrets.development.json +3 -0
  31. data/test/dummy/config/secrets.test.json +21 -0
  32. data/test/models/commit_deployment_status_test.rb +0 -1
  33. data/test/models/merge_request_test.rb +4 -1
  34. data/test/models/shipit/{stacks_test.rb → stack_test.rb} +18 -5
  35. data/test/models/users_test.rb +8 -0
  36. data/test/test_helper.rb +2 -2
  37. data/test/unit/github_app_test.rb +1 -1
  38. metadata +13 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f671228679f81a64a70284699951ea5cc8fce83e82a56263cf6a4f52055f5976
4
- data.tar.gz: 0d795762874714a9d592edb0dd3fd1b599f1819edc06d1085252a9e26ef0073b
3
+ metadata.gz: d14e4fec687523820d46bf58196894deb71b3acb79358059b743d33c31bf9305
4
+ data.tar.gz: e5d756e9bc4f452408f40d0a3f1f2d6f06cbeceb7544ae47d91b245acb1fc83b
5
5
  SHA512:
6
- metadata.gz: 6c55d8a3f3ab16affd874abd8c15e51c19a29e81ddb3131a4695d9ca2ba409e312e40892ddbd66ec6bca32ce403254f02de632dbab06a97306c6a0da5e684c2e
7
- data.tar.gz: fd7b4ad69bd0b03a486a38a4ce2dcf0802581aee836e44f1390f362aeace5b1fbb30f24bd3a5579da89e0bfca8f588ed16d121e9be7a4afd7f7f1efda208a97f
6
+ metadata.gz: e4a7e88bdf8fe9c40fe6520054fad67a72af184524bb1a8f3a20c0bea07b858cf5d568b272ce0a95060c8bfa2c64b5cb1adec7487a877e23f37e6a8bf3f143ed
7
+ data.tar.gz: 6cab2f24a84a81251991dc20b23c4d9f966fa8b98f053b904b34227850efca196133ec2c395a5e0c8444b8c41d6672d1362058fd1c90e543e7b1c97d6f07732a
data/README.md CHANGED
@@ -25,8 +25,8 @@ This guide aims to help you [set up](#installation-and-setup), [use](#using-ship
25
25
  **II. USING SHIPIT**
26
26
 
27
27
  * [Adding stacks](#adding-stacks)
28
- * [Working on stacks](#working-on-stacks),
29
- * [Configuring stacks](#configuring-stacks).
28
+ * [Working on stacks](#working-on-stacks)
29
+ * [Configuring stacks](#configuring-stacks)
30
30
 
31
31
  **III. REFERENCE**
32
32
 
@@ -357,6 +357,11 @@ For example:
357
357
  fetch:
358
358
  curl --silent https://app.example.com/services/ping/version
359
359
  ```
360
+
361
+ **Note:** Currently, deployments in emergency mode are configured to occur concurrently via [the `build_deploy` method](https://github.com/Shopify/shipit-engine/blob/main/app/models/shipit/stack.rb),
362
+ whose `allow_concurrency` keyword argument defaults to `force`, where `force` is true when emergency mode is enabled.
363
+ If you'd like to separate these two from one another, override this method as desired in your service.
364
+
360
365
  <h3 id="kubernetes">Kubernetes</h3>
361
366
 
362
367
  **<code>kubernetes</code>** allows to specify a Kubernetes namespace and context to deploy to.
@@ -641,7 +646,7 @@ Your deploy scripts have access to the following environment variables:
641
646
  * `GITHUB_REPO_OWNER`: The GitHub username of the repository owner for the current deploy/task.
642
647
  * `EMAIL`: Email of the user that triggered the deploy/task (if available)
643
648
  * `ENVIRONMENT`: The stack environment (e.g `production` / `staging`)
644
- * `BRANCH`: The stack branch (e.g `master`)
649
+ * `BRANCH`: The stack branch (e.g `main`)
645
650
  * `LAST_DEPLOYED_SHA`: The git SHA of the last deployed commit
646
651
  * `DIFF_LINK`: URL to the diff on GitHub.
647
652
  * `TASK_ID`: ID of the task that is running
@@ -93,8 +93,8 @@ module Shipit
93
93
  render(status: :not_found, json: { status: '404', error: 'Not Found' })
94
94
  end
95
95
 
96
- def conflict(_error)
97
- render(status: :conflict, json: { status: '409', error: 'Conflict' })
96
+ def conflict(error)
97
+ render(status: :conflict, json: { status: '409', error: error.message })
98
98
  end
99
99
  end
100
100
  end
@@ -11,6 +11,7 @@ module Shipit
11
11
  params do
12
12
  requires :sha, String, length: { in: 6..40 }
13
13
  accepts :force, Boolean, default: false
14
+ accepts :allow_concurrency, Boolean
14
15
  accepts :require_ci, Boolean, default: false
15
16
  accepts :env, Hash, default: {}
16
17
  end
@@ -18,7 +19,10 @@ module Shipit
18
19
  commit = stack.commits.by_sha(params.sha) || param_error!(:sha, 'Unknown revision')
19
20
  param_error!(:force, "Can't deploy a locked stack") if !params.force && stack.locked?
20
21
  param_error!(:require_ci, "Commit is not deployable") if params.require_ci && !commit.deployable?
21
- deploy = stack.trigger_deploy(commit, current_user, env: params.env, force: params.force)
22
+
23
+ allow_concurrency = params.allow_concurrency.nil? ? params.force : params.allow_concurrency
24
+ deploy = stack.trigger_deploy(commit, current_user, env: params.env, force: params.force,
25
+ allow_concurrency: allow_concurrency)
22
26
  render_resource(deploy, status: :accepted)
23
27
  end
24
28
  end
@@ -8,7 +8,7 @@ module Shipit
8
8
 
9
9
  validates :creator, :name, presence: true
10
10
 
11
- serialize :permissions, Shipit.serialized_column(:permissions, type: Array)
11
+ serialize :permissions, coder: Shipit.serialized_column(:permissions, type: Array)
12
12
  PERMISSIONS = %w(
13
13
  read:stack
14
14
  write:stack
@@ -48,7 +48,6 @@ module Shipit
48
48
  client.create_deployment_status(
49
49
  commit_deployment.api_url,
50
50
  status,
51
- accept: 'application/vnd.github.flash-preview+json',
52
51
  target_url: url_helpers.stack_deploy_url(stack, task),
53
52
  description: description.truncate(DESCRIPTION_CHARACTER_LIMIT_ON_GITHUB),
54
53
  environment_url: stack.deploy_url,
@@ -9,7 +9,7 @@ module Shipit
9
9
  validates :url, presence: true, url: { no_local: true, allow_blank: true }
10
10
  validates :content_type, presence: true
11
11
 
12
- serialize :response_headers, SafeJSON
12
+ serialize :response_headers, coder: SafeJSON
13
13
 
14
14
  after_commit :purge_old_deliveries, on: :create
15
15
 
@@ -101,11 +101,23 @@ module Shipit
101
101
  end
102
102
 
103
103
  def shipit_file_names_in_priority_order
104
- ["#{app_name}.#{@env}.yml", "#{app_name}.yml", "shipit.#{@env}.yml", "shipit.yml"].uniq
104
+ [
105
+ "#{app_name}.#{@env}.yml",
106
+ ".shipit/#{app_name}.#{@env}.yml",
107
+
108
+ "#{app_name}.yml",
109
+ ".shipit/#{app_name}.yml",
110
+
111
+ "shipit.#{@env}.yml",
112
+ ".shipit/#{@env}.yml",
113
+
114
+ "shipit.yml",
115
+ ".shipit/shipit.yml",
116
+ ].uniq
105
117
  end
106
118
 
107
119
  def bare_shipit_filenames
108
- ["#{app_name}.yml", "shipit.yml"].uniq
120
+ ["#{app_name}.yml", "shipit.yml", ".shipit/#{app_name}.yml", ".shipit/shipit.yml"].uniq
109
121
  end
110
122
 
111
123
  def config_file_path
@@ -87,7 +87,7 @@ module Shipit
87
87
  validates :content_type, presence: true, inclusion: { in: CONTENT_TYPES.keys }
88
88
  validates :events, presence: true, subset: { of: EVENTS }
89
89
 
90
- serialize :events, Shipit::CSVSerializer
90
+ serialize :events, coder: Shipit::CSVSerializer
91
91
 
92
92
  scope :global, -> { where(stack_id: nil) }
93
93
  scope :scoped_to, ->(stack) { where(stack_id: stack.id) }
@@ -11,7 +11,7 @@ module Shipit
11
11
  has_many :pull_request_assignments
12
12
  has_many :assignees, class_name: :User, through: :pull_request_assignments, source: :user
13
13
 
14
- serialize :labels, Shipit.serialized_column(:labels, type: Array)
14
+ serialize :labels, coder: Shipit.serialized_column(:labels, type: Array)
15
15
 
16
16
  after_create_commit :emit_create_hooks
17
17
  after_update_commit :emit_update_hooks
@@ -101,7 +101,7 @@ module Shipit
101
101
 
102
102
  validates :lock_reason, length: { maximum: 4096 }
103
103
 
104
- serialize :cached_deploy_spec, DeploySpec
104
+ serialize :cached_deploy_spec, coder: DeploySpec
105
105
  delegate(
106
106
  :provisioning_handler_name,
107
107
  :find_task_definition,
@@ -150,14 +150,14 @@ module Shipit
150
150
  task
151
151
  end
152
152
 
153
- def build_deploy(until_commit, user, env: nil, force: false)
153
+ def build_deploy(until_commit, user, env: nil, force: false, allow_concurrency: force)
154
154
  since_commit = last_deployed_commit.presence || commits.first
155
155
  deploys.build(
156
156
  user_id: user.id,
157
157
  until_commit: until_commit,
158
158
  since_commit: since_commit,
159
159
  env: filter_deploy_envs(env&.to_h || {}),
160
- allow_concurrency: force,
160
+ allow_concurrency: allow_concurrency,
161
161
  ignored_safeties: force || !until_commit.deployable?,
162
162
  max_retries: retries_on_deploy,
163
163
  )
@@ -226,8 +226,12 @@ module Shipit
226
226
 
227
227
  def next_commit_to_deploy
228
228
  commits_to_deploy = commits.order(id: :asc).newer_than(last_deployed_commit).reachable.preload(:statuses)
229
- commits_to_deploy = commits_to_deploy.limit(maximum_commits_per_deploy) if maximum_commits_per_deploy
230
- commits_to_deploy.to_a.reverse.find(&:deployable?)
229
+ if maximum_commits_per_deploy
230
+ commits_with_max_applied = commits_to_deploy.limit(maximum_commits_per_deploy)
231
+ deployable_commits(commits_with_max_applied) || deployable_commits(commits_to_deploy)
232
+ else
233
+ deployable_commits(commits_to_deploy)
234
+ end
231
235
  end
232
236
 
233
237
  def deployed_too_recently?
@@ -628,6 +632,10 @@ module Shipit
628
632
 
629
633
  private
630
634
 
635
+ def deployable_commits(commits)
636
+ commits.to_a.reverse.find(&:deployable?)
637
+ end
638
+
631
639
  def clear_cache
632
640
  remove_instance_variable(:@active_task) if defined?(@active_task)
633
641
  end
@@ -3,7 +3,11 @@ module Shipit
3
3
  class Task < Record
4
4
  include DeferredTouch
5
5
 
6
- ConcurrentTaskRunning = Class.new(StandardError)
6
+ class ConcurrentTaskRunning < StandardError
7
+ def message
8
+ "A task is already running."
9
+ end
10
+ end
7
11
 
8
12
  PRESENCE_CHECK_TIMEOUT = 30
9
13
  ACTIVE_STATUSES = %w(pending running aborting).freeze
@@ -54,8 +58,8 @@ module Shipit
54
58
  end
55
59
  end
56
60
 
57
- serialize :definition, TaskDefinition
58
- serialize :env, Shipit.serialized_column(:env, coder: EnvHash)
61
+ serialize :definition, coder: TaskDefinition
62
+ serialize :env, coder: Shipit.serialized_column(:env, coder: EnvHash)
59
63
 
60
64
  scope :success, -> { where(status: 'success') }
61
65
  scope :completed, -> { where(status: COMPLETED_STATUSES) }
@@ -95,6 +95,8 @@ module Shipit
95
95
  update!(github_user: Shipit.github.api.user(github_id))
96
96
  rescue Octokit::NotFound
97
97
  identify_renamed_user!
98
+ rescue Octokit::Forbidden
99
+ Rails.logger.info("User #{name}, github_id #{github_id} has forbidden access to their GitHub, likely deleted.")
98
100
  end
99
101
 
100
102
  def github_user=(github_user)
@@ -9,7 +9,7 @@
9
9
  <% if variable.select %>
10
10
  <%= field.select variable.name, options_for_select([["Please select...", { disabled: "disabled" }]] + variable.select, variable.default || "Please select...") %>
11
11
  <% else %>
12
- <%= field.text_field variable.name, value: variable.default %>
12
+ <%= field.text_field variable.name, value: params[variable.name].presence || variable.default %>
13
13
  <% end %>
14
14
  <%= field.label variable.name, variable.title || variable.name %>
15
15
  </p>
@@ -15,7 +15,7 @@
15
15
  </h4>
16
16
  <span class="status-meta">
17
17
  <%= link_to @stack.to_param, stack_url(@stack), target: '_blank', rel: 'noopener' %>
18
- <strong>master branch is failing!</strong>
18
+ <strong>main branch is failing!</strong>
19
19
  </span>
20
20
  <%= render 'commit_count_warning' if display_commit_count_warning?(params[:commits].to_i) %>
21
21
  </div>
@@ -22,7 +22,7 @@
22
22
 
23
23
  <p id="github_app">
24
24
  Config:
25
- <% if Rails.application.secrets.github.present? %>
25
+ <% if Rails.application.credentials.github.present? %>
26
26
  Success!
27
27
  <% else %>
28
28
  <span class="missing">
@@ -1,7 +1,7 @@
1
1
  host: 'localhost:3000'
2
2
  redis_url: 'redis://127.0.0.1:6379/0'
3
3
 
4
- # For creating an app see: https://github.com/Shopify/shipit-engine/blob/master/docs/setup.md#creating-the-github-app
4
+ # For creating an app see: https://github.com/Shopify/shipit-engine/blob/main/docs/setup.md#creating-the-github-app
5
5
  # Can be obtained there: https://github.com/settings/apps
6
6
  # Set the "Authorization callback URL" as `<host>/github/auth/github/callback`
7
7
 
@@ -1,7 +1,7 @@
1
1
  host: 'shipit-engine.myshopify.io'
2
2
  redis_url: 'redis://shipit-engine.railgun:6379'
3
3
 
4
- # For creating an app see: https://github.com/Shopify/shipit-engine/blob/master/docs/setup.md#creating-the-github-app
4
+ # For creating an app see: https://github.com/Shopify/shipit-engine/blob/main/docs/setup.md#creating-the-github-app
5
5
 
6
6
  github:
7
7
  somegithuborg:
data/lib/shipit/engine.rb CHANGED
@@ -21,7 +21,7 @@ module Shipit
21
21
  Shipit::Engine.routes.default_url_options[:host] = Shipit.host
22
22
  Pubsubstub.redis_url = Shipit.redis_url.to_s
23
23
 
24
- Rails.application.secrets.deep_symbolize_keys!
24
+ Rails.application.credentials.deep_symbolize_keys!
25
25
 
26
26
  app.config.assets.paths << Emoji.images_path
27
27
  app.config.assets.precompile += %w(
@@ -103,7 +103,6 @@ module Shipit
103
103
  ) do
104
104
  response = new_client(bearer_token: authentication_payload).create_app_installation_access_token(
105
105
  installation_id,
106
- accept: 'application/vnd.github.machine-man-preview+json',
107
106
  )
108
107
  token = Token.from_github(response)
109
108
  raise AuthenticationFailed if token.blank?
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  module OctokitCheckRuns
3
3
  def check_runs(repo, sha, options = {})
4
- paginate("#{Octokit::Repository.path(repo)}/commits/#{sha}/check-runs", options.reverse_merge(
5
- accept: 'application/vnd.github.antiope-preview+json',
6
- ))
4
+ paginate("#{Octokit::Repository.path(repo)}/commits/#{sha}/check-runs", options)
7
5
  end
8
6
  end
9
7
 
@@ -106,7 +106,7 @@ module Shipit
106
106
  .success?
107
107
  end
108
108
 
109
- def git_clone(url, path, branch: 'master', **kwargs)
109
+ def git_clone(url, path, branch: 'main', **kwargs)
110
110
  git('clone', '--quiet', *modern_git_args, '--recursive', '--branch', branch, url, path, **kwargs)
111
111
  end
112
112
 
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Shipit
3
- VERSION = '0.38.0'
3
+ VERSION = '0.39.0'
4
4
  end
data/lib/shipit.rb CHANGED
@@ -291,7 +291,7 @@ module Shipit
291
291
  end
292
292
 
293
293
  def secrets
294
- Rails.application.secrets
294
+ Rails.application.credentials
295
295
  end
296
296
  end
297
297
 
@@ -81,6 +81,7 @@ module Shipit
81
81
  end
82
82
 
83
83
  assert_response :conflict
84
+ assert_json 'error', 'A task is already running.'
84
85
  end
85
86
 
86
87
  test "#create refuses to deploy unsuccessful commits if the require_ci flag is passed" do
@@ -119,6 +120,29 @@ module Shipit
119
120
  assert_response :accepted
120
121
  assert_json 'status', 'pending'
121
122
  end
123
+
124
+ test "#create uses allow_concurrency param when provided" do
125
+ @stack.update!(lock_reason: 'Something broken')
126
+
127
+ assert_difference -> { @stack.deploys.count }, 1 do
128
+ post :create, params: { stack_id: @stack.to_param, sha: @commit.sha, force: 'true', allow_concurrency: 'false' }
129
+ end
130
+ assert_response :accepted
131
+ assert_json 'status', 'pending'
132
+ refute @stack.deploys.last.allow_concurrency
133
+ end
134
+
135
+ test "#create defaults allow_concurrency to force param when not provided" do
136
+ @stack.update!(lock_reason: 'Something broken')
137
+ expected_force = true
138
+
139
+ assert_difference -> { @stack.deploys.count }, 1 do
140
+ post :create, params: { stack_id: @stack.to_param, sha: @commit.sha, force: expected_force }
141
+ end
142
+ assert_response :accepted
143
+ assert_json 'status', 'pending'
144
+ assert_equal expected_force, @stack.deploys.last.allow_concurrency
145
+ end
122
146
  end
123
147
  end
124
148
  end
@@ -10,7 +10,7 @@ module Shipit
10
10
  end
11
11
 
12
12
  test "validates that Shipit.github is present" do
13
- Rails.application.secrets.stubs(:github).returns(nil)
13
+ Rails.application.credentials.stubs(:github).returns(nil)
14
14
  get :index
15
15
  assert_select "#github_app .missing"
16
16
  assert_select ".missing", count: 1
@@ -11,9 +11,16 @@ module Shipit
11
11
  session[:user_id] = shipit_users(:walrus).id
12
12
  end
13
13
 
14
- test "tasks defined in the shipit.yml can be displayed" do
14
+ test "tasks defined in the shipit.yml can be displayed with default variable values" do
15
15
  get :new, params: { stack_id: @stack, definition_id: @definition.id }
16
16
  assert_response :ok
17
+ assert_select 'input[name="task[env][FOO]"][value="1"]'
18
+ end
19
+
20
+ test "it is possible to provide a default value override for a task" do
21
+ get :new, params: { stack_id: @stack, definition_id: @definition.id, FOO: '42' }
22
+ assert_response :ok
23
+ assert_select 'input[name="task[env][FOO]"][value="42"]'
17
24
  end
18
25
 
19
26
  test "tasks defined in the shipit.yml can't be triggered if the stack is being deployed" do
@@ -17,6 +17,7 @@ end
17
17
 
18
18
  module Shipit
19
19
  class Application < Rails::Application
20
- config.load_defaults 7.0
20
+ config.load_defaults 7.1
21
+ config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true
21
22
  end
22
23
  end
@@ -2,8 +2,8 @@ local_secrets = Shipit::Engine.root.join('config/secrets.development.yml')
2
2
  if local_secrets.exist?
3
3
  secrets = YAML.load(local_secrets.read).deep_symbolize_keys
4
4
  if Rails.env.development?
5
- Rails.application.secrets.deep_merge!(secrets)
5
+ Rails.application.credentials.deep_merge!(secrets)
6
6
  elsif Rails.env.test?
7
- Rails.application.secrets.merge!(redis_url: secrets[:redis_url])
7
+ Rails.application.credentials.merge!(redis_url: secrets[:redis_url])
8
8
  end
9
9
  end
@@ -0,0 +1,3 @@
1
+ {
2
+ "secret_key_base": "s3cr3ts3cr3ts3cr3ts3cr3ts3cr3ts3cr3t"
3
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "host": "shipit.com",
3
+ "secret_key_base": "s3cr3ts3cr3ts3cr3ts3cr3ts3cr3ts3cr3t",
4
+ "github_api": {
5
+ "token": "t0k3n"
6
+ },
7
+ "github": {
8
+ "domain": null,
9
+ "app_id": 42,
10
+ "installation_id": 43,
11
+ "bot_login": "shipit[bot]",
12
+ "webhook_secret": null,
13
+ "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA7iUQC2uUq/gtQg0gxtyaccuicYgmq1LUr1mOWbmwM1Cv63+S\n73qo8h87FX+YyclY5fZF6SMXIys02JOkImGgbnvEOLcHnImCYrWs03msOzEIO/pG\nM0YedAPtQ2MEiLIu4y8htosVxeqfEOPiq9kQgFxNKyETzjdIA9q1md8sofuJUmPv\nibacW1PecuAMnn+P8qf0XIDp7uh6noB751KvhCaCNTAPtVE9NZ18OmNG9GOyX/pu\npQHIrPgTpTG6KlAe3r6LWvemzwsMtuRGU+K+KhK9dFIlSE+v9rA32KScO8efOh6s\nGu3rWorV4iDu14U62rzEfdzzc63YL94sUbZxbwIDAQABAoIBADLJ8r8MxZtbhYN1\nu0zOFZ45WL6v09dsBfITvnlCUeLPzYUDIzoxxcBFittN6C744x3ARS6wjimw+EdM\nTZALlCSb/sA9wMDQzt7wchhz9Zh2H5RzDu+2f54sjDh38KqancdT8PO2fAFGxX/b\nqicOVyeZB9gv6MJtJc20olBbuXAeBNfcDABF9oxF+0i+Ssg7B4VXiqgcjtGbr/Og\nqRll7AqyTArVx2xEcVfZxeZ4zGnigzcJq4te7yYpxzwk+RxblkPh54Yt4WxZ+8DI\nRsn3r6ajlpwzpwvsJFU2Txq7xBTzGQMFmy/Pnjk83kP2cogxB2+tRyjITGqTwD8b\ngg9PFCkCgYEA+7u8A0l0Cz6p0SI6c7ftVePVRiIhpawWN7og/wEmI6zUjm/3rA+R\nhrhaVKuOD8QF/HdDsqTck5gjGAjTmJz6r33/cl1Tz+pr62znsrB4r0yMKvQbKN81\nWGaWOsi2+ZXqLNv5h5wpUF0MTKlXHeKnwP5kuEvGwVn6WURFCh6PhLMCgYEA8i5e\nJjulJVGyd5HuoY3xyO7E6DjidsqRnVRq+hYpORjnHvTmSwe4+tH4ha2p9Kv2Y6k3\nC1NYY/fSMQoYCCRaYyJleI+la/9tsZqAmtms4ZB8KhFmPHf9fW75i6G0xKWyZ8K+\nE2Ft/UaEiM282593cguV6+Kt5uExnyPxLLK4FlUCgYEAwRJ/JGI8/7bjFkTTYheq\nj5q75BufhOrU6471acAe2XPgXxLfefdC3Xodxh0CS3NESBvNL4Ikr4sbN37lk4Kq\n/th7iOKtuqUIeru/hZy2I3VpeDRbdGCmEJQ2GwYA2LKztg5Nd0Y9paaIHXAwIfrK\nQUqcQ4HTAk8ZpUeoUBeaaeMCgYANLmbjb9WiPVsYVPIHCwHA7PX8qbPxwT7BsGmO\nKQyfVfKmZa/vH4F67Vi4deZNMdrcO8aKMEQcVM2065a5QrlEsgeR00eupB1lUEJ1\nqylUsZeAdqf43JMIc7TTW77KATa/nQLZbTEeWus1wvTngztuEqFbUGAks9cOkVc8\nFpIcbQKBgQDVIL8gPLmn0f+4oLF8MBC+oxtKpz14X5iJ1saGFkzW5I+nIEskpS0S\nqtirnTCnJFGdCrFwctnxiuiCmyGwpBYdjIfHyvYAHnqAtMnESzCUyeSFZiquVW5W\nMvbMmDPoV27XOHU9kIq6NXtfrkpufiyo6/VEYWozXalxKLNuqLYfPQ==\n-----END RSA PRIVATE KEY-----\n",
14
+ "oauth": {
15
+ "id": "Iv1.bf2c2c45b449bfd9",
16
+ "secret": "ef694cd6e45223075d78d138ef014049052665f1",
17
+ "teams": null
18
+ }
19
+ },
20
+ "redis_url": "redis://127.0.0.1:6379/7"
21
+ }
@@ -15,7 +15,6 @@ module Shipit
15
15
  @author.github_api.class.any_instance.expects(:create_deployment_status).with(
16
16
  @deployment.api_url,
17
17
  'in_progress',
18
- accept: "application/vnd.github.flash-preview+json",
19
18
  target_url: "http://shipit.com/shopify/shipit-engine/production/deploys/#{@task.id}",
20
19
  description: "walrus triggered the deploy of shopify/shipit-engine/production to #{@deployment.short_sha}",
21
20
  environment_url: "https://shipit.shopify.com",
@@ -243,7 +243,10 @@ module Shipit
243
243
  end
244
244
 
245
245
  test "status transitions emit hooks" do
246
- job = assert_enqueued_with(job: EmitEventJob) do
246
+ expected_args = ->(job_args) do
247
+ job_args.first[:event] == 'merge'
248
+ end
249
+ job = assert_enqueued_with(job: EmitEventJob, args: expected_args) do
247
250
  @pr.reject!('merge_conflict')
248
251
  end
249
252
  params = job.arguments.first
@@ -3,7 +3,7 @@ require 'test_helper'
3
3
  require 'securerandom'
4
4
 
5
5
  module Shipit
6
- class StacksTest < ActiveSupport::TestCase
6
+ class StackTest < ActiveSupport::TestCase
7
7
  def setup
8
8
  @stack = shipit_stacks(:shipit)
9
9
  @expected_base_path = Rails.root.join('data', 'stacks', @stack.to_param).to_s
@@ -704,12 +704,12 @@ module Shipit
704
704
  assert_equal shipit_commits(:fifth), @stack.next_commit_to_deploy
705
705
  end
706
706
 
707
- test "#next_commit_to_deploy respects the deploy.max_commits directive" do
707
+ test "#next_commit_to_deploy respects the deploy.max_commits directive given the commit is deployable" do
708
708
  @stack.tasks.destroy_all
709
709
 
710
- fifth_commit = shipit_commits(:third)
711
- fifth_commit.statuses.create!(stack_id: @stack.id, state: 'success', context: 'ci/travis')
712
- assert_predicate fifth_commit, :deployable?
710
+ third_commit = shipit_commits(:third)
711
+ third_commit.statuses.create!(stack_id: @stack.id, state: 'success', context: 'ci/travis')
712
+ assert_predicate third_commit, :deployable?
713
713
 
714
714
  assert_equal shipit_commits(:third), @stack.next_commit_to_deploy
715
715
 
@@ -717,6 +717,19 @@ module Shipit
717
717
  assert_equal shipit_commits(:third), @stack.next_commit_to_deploy
718
718
  end
719
719
 
720
+ test "#next_commit_to_deploy deploys the first deployable commit when deploy.max_commits directive fails to find a deployable commit" do
721
+ @stack.tasks.destroy_all
722
+
723
+ third_commit = shipit_commits(:third)
724
+ third_commit.statuses.create!(stack_id: @stack.id, state: 'success', context: 'ci/travis')
725
+ assert_predicate third_commit, :deployable?
726
+
727
+ assert_equal shipit_commits(:third), @stack.next_commit_to_deploy
728
+
729
+ @stack.expects(:maximum_commits_per_deploy).returns(1).at_least_once
730
+ assert_equal shipit_commits(:third), @stack.next_commit_to_deploy
731
+ end
732
+
720
733
  test "setting #lock_reason also sets #locked_since" do
721
734
  assert_predicate @stack.locked_since, :nil?
722
735
 
@@ -203,6 +203,14 @@ module Shipit
203
203
  assert_equal 'george@cyclim.se', user.email
204
204
  end
205
205
 
206
+ test "#refresh_from_github! logs deleted users" do
207
+ Shipit.github.api.expects(:user).with(@user.github_id).raises(Octokit::Forbidden)
208
+
209
+ Rails.logger.expects(:info).with("User #{@user.name}, github_id #{@user.github_id} has forbidden access to their GitHub, likely deleted.")
210
+
211
+ @user.refresh_from_github!
212
+ end
213
+
206
214
  test "#github_api uses the user's access token" do
207
215
  assert_equal @user.github_access_token, @user.github_api.access_token
208
216
  end
data/test/test_helper.rb CHANGED
@@ -23,7 +23,7 @@ require 'spy/integration'
23
23
 
24
24
  # Load fixtures from the engine
25
25
  if ActiveSupport::TestCase.respond_to?(:fixture_path=)
26
- ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
26
+ ActiveSupport::TestCase.fixture_paths << File.expand_path("../fixtures", __FILE__)
27
27
  ActiveSupport::TestCase.fixtures(:all)
28
28
  end
29
29
 
@@ -71,7 +71,7 @@ module ActiveSupport
71
71
  end
72
72
  end
73
73
 
74
- ActiveRecord::Migration.check_pending!
74
+ ActiveRecord::Migration.check_all_pending!
75
75
 
76
76
  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
77
77
  #
@@ -202,7 +202,7 @@ module Shipit
202
202
  end
203
203
 
204
204
  def default_config
205
- Rails.application.secrets.github.deep_dup
205
+ Rails.application.credentials.github.deep_dup
206
206
  end
207
207
  end
208
208
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shipit-engine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.38.0
4
+ version: 0.39.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-04 00:00:00.000000000 Z
11
+ date: 2024-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_model_serializers
@@ -156,14 +156,14 @@ dependencies:
156
156
  requirements:
157
157
  - - "~>"
158
158
  - !ruby/object:Gem::Version
159
- version: '4.20'
159
+ version: 5.6.0
160
160
  type: :runtime
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
- version: '4.20'
166
+ version: 5.6.0
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: omniauth-github
169
169
  requirement: !ruby/object:Gem::Requirement
@@ -198,14 +198,14 @@ dependencies:
198
198
  requirements:
199
199
  - - "~>"
200
200
  - !ruby/object:Gem::Version
201
- version: 7.0.0
201
+ version: 7.1.1
202
202
  type: :runtime
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
206
  - - "~>"
207
207
  - !ruby/object:Gem::Version
208
- version: 7.0.0
208
+ version: 7.1.1
209
209
  - !ruby/object:Gem::Dependency
210
210
  name: rails-timeago
211
211
  requirement: !ruby/object:Gem::Requirement
@@ -878,6 +878,8 @@ files:
878
878
  - test/dummy/config/initializers/wrap_parameters.rb
879
879
  - test/dummy/config/locales/en.yml
880
880
  - test/dummy/config/routes.rb
881
+ - test/dummy/config/secrets.development.json
882
+ - test/dummy/config/secrets.test.json
881
883
  - test/dummy/config/secrets.yml
882
884
  - test/dummy/config/secrets_double_github_app.yml
883
885
  - test/dummy/db/schema.rb
@@ -974,7 +976,7 @@ files:
974
976
  - test/models/shipit/review_stack_provision_status_test.rb
975
977
  - test/models/shipit/review_stack_provisioning_queue_test.rb
976
978
  - test/models/shipit/review_stack_test.rb
977
- - test/models/shipit/stacks_test.rb
979
+ - test/models/shipit/stack_test.rb
978
980
  - test/models/shipit/webhooks/handlers/pull_request/assigned_handler_test.rb
979
981
  - test/models/shipit/webhooks/handlers/pull_request/closed_handler_test.rb
980
982
  - test/models/shipit/webhooks/handlers/pull_request/edited_handler_test.rb
@@ -1041,7 +1043,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1041
1043
  - !ruby/object:Gem::Version
1042
1044
  version: '0'
1043
1045
  requirements: []
1044
- rubygems_version: 3.4.14
1046
+ rubygems_version: 3.5.7
1045
1047
  signing_key:
1046
1048
  specification_version: 4
1047
1049
  summary: Application deployment software
@@ -1104,6 +1106,8 @@ test_files:
1104
1106
  - test/dummy/config/initializers/wrap_parameters.rb
1105
1107
  - test/dummy/config/locales/en.yml
1106
1108
  - test/dummy/config/routes.rb
1109
+ - test/dummy/config/secrets.development.json
1110
+ - test/dummy/config/secrets.test.json
1107
1111
  - test/dummy/config/secrets.yml
1108
1112
  - test/dummy/config/secrets_double_github_app.yml
1109
1113
  - test/dummy/config.ru
@@ -1201,7 +1205,7 @@ test_files:
1201
1205
  - test/models/shipit/review_stack_provision_status_test.rb
1202
1206
  - test/models/shipit/review_stack_provisioning_queue_test.rb
1203
1207
  - test/models/shipit/review_stack_test.rb
1204
- - test/models/shipit/stacks_test.rb
1208
+ - test/models/shipit/stack_test.rb
1205
1209
  - test/models/shipit/webhooks/handlers/pull_request/assigned_handler_test.rb
1206
1210
  - test/models/shipit/webhooks/handlers/pull_request/closed_handler_test.rb
1207
1211
  - test/models/shipit/webhooks/handlers/pull_request/edited_handler_test.rb