shipit-engine 0.38.0 → 0.39.0

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