shipit-engine 0.21.0 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -106
  3. data/app/assets/images/timedout.svg +14 -0
  4. data/app/assets/stylesheets/_pages/_commits.scss +11 -2
  5. data/app/controllers/shipit/stacks_controller.rb +1 -7
  6. data/app/controllers/shipit/webhooks_controller.rb +102 -66
  7. data/app/helpers/shipit/github_url_helper.rb +2 -2
  8. data/app/helpers/shipit/shipit_helper.rb +3 -31
  9. data/app/jobs/shipit/destroy_job.rb +9 -0
  10. data/app/jobs/shipit/github_sync_job.rb +1 -1
  11. data/app/jobs/shipit/setup_github_hook_job.rb +1 -3
  12. data/app/models/shipit/anonymous_user.rb +4 -1
  13. data/app/models/shipit/commit.rb +8 -8
  14. data/app/models/shipit/commit_deployment.rb +3 -3
  15. data/app/models/shipit/commit_deployment_status.rb +2 -2
  16. data/app/models/shipit/deploy.rb +3 -3
  17. data/app/models/shipit/deploy_spec/file_system.rb +3 -3
  18. data/app/models/shipit/deploy_spec/kubernetes_discovery.rb +10 -2
  19. data/app/models/shipit/github_hook.rb +2 -99
  20. data/app/models/shipit/github_status.rb +1 -1
  21. data/app/models/shipit/hook.rb +1 -1
  22. data/app/models/shipit/pull_request.rb +10 -10
  23. data/app/models/shipit/rollback.rb +1 -1
  24. data/app/models/shipit/stack.rb +27 -26
  25. data/app/models/shipit/task.rb +2 -2
  26. data/app/models/shipit/team.rb +4 -17
  27. data/app/models/shipit/user.rb +3 -3
  28. data/app/serializers/shipit/task_serializer.rb +2 -2
  29. data/app/serializers/shipit/user_serializer.rb +1 -1
  30. data/app/views/shipit/missing_settings.html.erb +5 -36
  31. data/app/views/shipit/stacks/new.html.erb +1 -1
  32. data/app/views/shipit/stacks/settings.html.erb +0 -4
  33. data/config/routes.rb +3 -13
  34. data/config/secrets.development.shopify.yml +10 -15
  35. data/config/secrets.development.yml +1 -1
  36. data/db/migrate/20180417130436_remove_all_github_hooks.rb +11 -0
  37. data/lib/shipit.rb +13 -56
  38. data/lib/shipit/command.rb +1 -1
  39. data/lib/shipit/engine.rb +2 -8
  40. data/lib/shipit/github_app.rb +122 -0
  41. data/lib/shipit/octokit_bot_users_patch.rb +25 -0
  42. data/lib/shipit/octokit_iterator.rb +2 -2
  43. data/lib/shipit/version.rb +1 -1
  44. data/lib/tasks/teams.rake +8 -24
  45. data/test/controllers/stacks_controller_test.rb +3 -29
  46. data/test/controllers/webhooks_controller_test.rb +29 -46
  47. data/test/dummy/config/secrets.yml +40 -10
  48. data/test/dummy/db/development.sqlite3 +0 -0
  49. data/test/dummy/db/schema.rb +1 -1
  50. data/test/dummy/db/seeds.rb +0 -1
  51. data/test/dummy/db/test.sqlite3 +0 -0
  52. data/test/fixtures/payloads/push_master.json +7 -6
  53. data/test/fixtures/payloads/push_not_master.json +7 -6
  54. data/test/fixtures/shipit/users.yml +2 -2
  55. data/test/helpers/hooks_helper.rb +1 -1
  56. data/test/helpers/payloads_helper.rb +1 -2
  57. data/test/jobs/destroy_stack_job_test.rb +1 -1
  58. data/test/models/commits_test.rb +5 -5
  59. data/test/models/deploy_spec_test.rb +17 -5
  60. data/test/models/github_hook_test.rb +1 -40
  61. data/test/models/pull_request_test.rb +11 -11
  62. data/test/models/stacks_test.rb +4 -10
  63. data/test/models/team_test.rb +3 -3
  64. data/test/models/users_test.rb +7 -7
  65. data/test/test_helper.rb +1 -1
  66. data/test/unit/github_app_test.rb +44 -0
  67. data/test/unit/shipit_test.rb +2 -49
  68. metadata +9 -3
  69. data/lib/tasks/webhook.rake +0 -6
@@ -1,6 +1,6 @@
1
1
  module Shipit
2
2
  class Rollback < Deploy
3
- belongs_to :deploy, foreign_key: :parent_id
3
+ belongs_to :deploy, foreign_key: :parent_id, inverse_of: false
4
4
 
5
5
  state_machine :status do
6
6
  after_transition to: :success, do: :lock_reverted_commits
@@ -28,7 +28,10 @@ module Shipit
28
28
  has_many :tasks, dependent: :destroy
29
29
  has_many :deploys
30
30
  has_many :rollbacks
31
- has_many :deploys_and_rollbacks, -> { where(type: %w(Shipit::Deploy Shipit::Rollback)) }, class_name: 'Task'
31
+ has_many :deploys_and_rollbacks,
32
+ -> { where(type: %w(Shipit::Deploy Shipit::Rollback)) },
33
+ class_name: 'Task',
34
+ inverse_of: :stack
32
35
  has_many :github_hooks, dependent: :destroy, class_name: 'Shipit::GithubHook::Repo'
33
36
  has_many :hooks, dependent: :destroy
34
37
  has_many :api_clients, dependent: :destroy
@@ -39,7 +42,12 @@ module Shipit
39
42
  end
40
43
 
41
44
  def lock_author=(user)
42
- super(user.try!(:logged_in?) ? user : nil)
45
+ super(user&.logged_in? ? user : nil)
46
+ end
47
+
48
+ def self.repo(full_name)
49
+ repo_owner, repo_name = full_name.downcase.split('/')
50
+ where(repo_owner: repo_owner, repo_name: repo_name)
43
51
  end
44
52
 
45
53
  before_validation :update_defaults
@@ -51,7 +59,7 @@ module Shipit
51
59
  after_commit :emit_removed_hooks, on: :destroy
52
60
  after_commit :broadcast_update, on: :update
53
61
  after_commit :emit_merge_status_hooks, on: :update
54
- after_commit :setup_hooks, :sync_github, on: :create
62
+ after_commit :sync_github, on: :create
55
63
  after_commit :schedule_merges_if_necessary, on: :update
56
64
 
57
65
  validates :repo_name, uniqueness: {scope: %i(repo_owner environment),
@@ -84,7 +92,7 @@ module Shipit
84
92
 
85
93
  def trigger_task(definition_id, user, env: nil, force: false)
86
94
  definition = find_task_definition(definition_id)
87
- env = env.try!(:to_h) || {}
95
+ env = env&.to_h || {}
88
96
 
89
97
  definition.variables_with_defaults.each do |variable|
90
98
  env[variable.name] ||= variable.default
@@ -110,7 +118,7 @@ module Shipit
110
118
  user_id: user.id,
111
119
  until_commit: until_commit,
112
120
  since_commit: since_commit,
113
- env: filter_deploy_envs(env.try!(:to_h) || {}),
121
+ env: filter_deploy_envs(env&.to_h || {}),
114
122
  allow_concurrency: force,
115
123
  ignored_safeties: force || !until_commit.deployable?,
116
124
  )
@@ -177,7 +185,7 @@ module Shipit
177
185
 
178
186
  def update_deployed_revision(sha)
179
187
  last_deploy = deploys_and_rollbacks.last
180
- return if last_deploy.try!(:active?)
188
+ return if last_deploy&.active?
181
189
 
182
190
  actual_deployed_commit = commits.reachable.by_sha(sha)
183
191
  return unless actual_deployed_commit
@@ -196,7 +204,7 @@ module Shipit
196
204
  end
197
205
 
198
206
  def head
199
- commits.reachable.first.try!(:sha)
207
+ commits.reachable.first&.sha
200
208
  end
201
209
 
202
210
  def merge_status(backlog_leniency_factor: 2.0)
@@ -256,7 +264,7 @@ module Shipit
256
264
  end
257
265
 
258
266
  def last_deployed_commit
259
- last_successful_deploy.try!(:until_commit) || NoDeployedCommit
267
+ last_successful_deploy&.until_commit || NoDeployedCommit
260
268
  end
261
269
 
262
270
  def deployable?
@@ -268,19 +276,19 @@ module Shipit
268
276
  end
269
277
 
270
278
  def repo_name=(name)
271
- super(name.try!(:downcase))
279
+ super(name&.downcase)
272
280
  end
273
281
 
274
282
  def repo_owner=(name)
275
- super(name.try!(:downcase))
283
+ super(name&.downcase)
276
284
  end
277
285
 
278
286
  def repo_http_url
279
- Shipit.github_url("#{repo_owner}/#{repo_name}")
287
+ Shipit.github.url("#{repo_owner}/#{repo_name}")
280
288
  end
281
289
 
282
290
  def repo_git_url
283
- "git@#{Shipit.github_domain}:#{repo_owner}/#{repo_name}.git"
291
+ "git@#{Shipit.github.domain}:#{repo_owner}/#{repo_name}.git"
284
292
  end
285
293
 
286
294
  def base_path
@@ -319,7 +327,7 @@ module Shipit
319
327
 
320
328
  def github_commits
321
329
  handle_github_redirections do
322
- Shipit.github_api.commits(github_repo_name, sha: branch)
330
+ Shipit.github.api.commits(github_repo_name, sha: branch)
323
331
  end
324
332
  rescue Octokit::Conflict
325
333
  [] # Repository is empty...
@@ -337,9 +345,9 @@ module Shipit
337
345
  end
338
346
 
339
347
  def refresh_repository!
340
- resource = Shipit.github_api.repo(github_repo_name)
348
+ resource = Shipit.github.api.repo(github_repo_name)
341
349
  if resource.try(:message) == 'Moved Permanently'
342
- resource = Shipit.github_api.get(resource.url)
350
+ resource = Shipit.github.api.get(resource.url)
343
351
  end
344
352
  update!(repo_owner: resource.owner.login, repo_name: resource.name)
345
353
  end
@@ -413,13 +421,6 @@ module Shipit
413
421
  )
414
422
  end
415
423
 
416
- def setup_hooks
417
- REQUIRED_HOOKS.each do |event|
418
- hook = github_hooks.find_or_create_by!(event: event)
419
- hook.schedule_setup!
420
- end
421
- end
422
-
423
424
  def schedule_for_destroy!
424
425
  DestroyStackJob.perform_later(self)
425
426
  end
@@ -463,16 +464,16 @@ module Shipit
463
464
  tasks.where(type: 'Shipit::Deploy').success.order(id: :desc).limit(100).durations
464
465
  end
465
466
 
467
+ def sync_github
468
+ GithubSyncJob.perform_later(stack_id: id)
469
+ end
470
+
466
471
  private
467
472
 
468
473
  def clear_cache
469
474
  remove_instance_variable(:@active_task) if defined?(@active_task)
470
475
  end
471
476
 
472
- def sync_github
473
- GithubSyncJob.perform_later(stack_id: id)
474
- end
475
-
476
477
  def clear_local_files
477
478
  FileUtils.rm_rf(base_path.to_s)
478
479
  end
@@ -11,7 +11,7 @@ module Shipit
11
11
 
12
12
  attr_accessor :pid
13
13
 
14
- belongs_to :deploy, foreign_key: :parent_id, required: false # required for fixtures
14
+ belongs_to :deploy, foreign_key: :parent_id, required: false, inverse_of: false # required for fixtures
15
15
 
16
16
  belongs_to :user, optional: true
17
17
  belongs_to :aborted_by, class_name: 'User', optional: true
@@ -21,7 +21,7 @@ module Shipit
21
21
 
22
22
  deferred_touch stack: :updated_at
23
23
 
24
- has_many :chunks, -> { order(:id) }, class_name: 'OutputChunk', dependent: :delete_all
24
+ has_many :chunks, -> { order(:id) }, class_name: 'OutputChunk', dependent: :delete_all, inverse_of: :task
25
25
 
26
26
  serialize :definition, TaskDefinition
27
27
  serialize :env, Hash
@@ -9,9 +9,8 @@ module Shipit
9
9
  -> { where(event: REQUIRED_HOOKS) },
10
10
  foreign_key: :organization,
11
11
  primary_key: :organization,
12
- class_name: 'GithubHook::Organization'
13
-
14
- after_commit :setup_hooks, if: :automatically_setup_hooks?
12
+ class_name: 'GithubHook::Organization',
13
+ inverse_of: false
15
14
 
16
15
  class << self
17
16
  def find_or_create_by_handle(handle)
@@ -26,7 +25,7 @@ module Shipit
26
25
  end
27
26
 
28
27
  def find_team_on_github(organization, slug)
29
- teams = Shipit::OctokitIterator.new { Shipit.github_api.org_teams(organization, per_page: 100) }
28
+ teams = Shipit::OctokitIterator.new { Shipit.github.api.org_teams(organization, per_page: 100) }
30
29
  teams.find { |t| t.slug == slug }
31
30
  rescue Octokit::NotFound
32
31
  end
@@ -40,20 +39,8 @@ module Shipit
40
39
  members.append(member) unless members.include?(member)
41
40
  end
42
41
 
43
- attr_writer :automatically_setup_hooks
44
- def automatically_setup_hooks?
45
- @automatically_setup_hooks
46
- end
47
-
48
- def setup_hooks(async: true)
49
- REQUIRED_HOOKS.each do |event|
50
- hook = github_hooks.find_or_create_by!(event: event)
51
- async ? hook.schedule_setup! : hook.setup!
52
- end
53
- end
54
-
55
42
  def refresh_members!
56
- github_members = Shipit::OctokitIterator.new(Shipit.github_api.get(api_url).rels[:members])
43
+ github_members = Shipit::OctokitIterator.new(Shipit.github.api.get(api_url).rels[:members])
57
44
  members = github_members.map { |u| User.find_or_create_from_github(u) }
58
45
  self.members = members
59
46
  save!
@@ -12,7 +12,7 @@ module Shipit
12
12
 
13
13
  def self.find_or_create_by_login!(login)
14
14
  find_or_create_by!(login: login) do |user|
15
- user.github_user = Shipit.github_api.user(login)
15
+ user.github_user = Shipit.github.api.user(login)
16
16
  end
17
17
  end
18
18
 
@@ -44,7 +44,7 @@ module Shipit
44
44
  end
45
45
 
46
46
  def github_api
47
- return Shipit.github_api unless github_access_token
47
+ return Shipit.github.api unless github_access_token
48
48
 
49
49
  @github_api ||= begin
50
50
  client = Octokit::Client.new(access_token: github_access_token)
@@ -71,7 +71,7 @@ module Shipit
71
71
  end
72
72
 
73
73
  def refresh_from_github!
74
- update!(github_user: Shipit.github_api.user(github_id))
74
+ update!(github_user: Shipit.github.api.user(github_id))
75
75
  rescue Octokit::NotFound
76
76
  identify_renamed_user!
77
77
  end
@@ -43,7 +43,7 @@ module Shipit
43
43
  end
44
44
 
45
45
  def action
46
- object.definition.try!(:action)
46
+ object.definition&.action
47
47
  end
48
48
 
49
49
  def include_action?
@@ -51,7 +51,7 @@ module Shipit
51
51
  end
52
52
 
53
53
  def description
54
- object.definition.try!(:action)
54
+ object.definition&.action
55
55
  end
56
56
 
57
57
  def include_description?
@@ -1,5 +1,5 @@
1
1
  module Shipit
2
2
  class UserSerializer < ActiveModel::Serializer
3
- attributes :id, :name, :email, :login, :avatar_url, :created_at, :updated_at
3
+ attributes :id, :name, :email, :login, :avatar_url, :created_at, :updated_at, :github_id
4
4
  end
5
5
  end
@@ -17,52 +17,21 @@
17
17
  <div class="wrapper">
18
18
  <section>
19
19
  <header class="section-header">
20
- <h2>GitHub application</h2>
20
+ <h2>GitHub App</h2>
21
21
  </header>
22
22
 
23
- <% if Shipit.github_oauth_id.blank? || Shipit.github_oauth_secret.blank? %>
24
- <p><%= missing_github_oauth_message %></p>
25
- <% end %>
26
- <p id="github_oauth_id">
27
- ID:
28
- <% if Shipit.github_oauth_id.present? %>
23
+ <p id="github_app">
24
+ Config:
25
+ <% if Rails.application.secrets.github.present? %>
29
26
  Success!
30
27
  <% else %>
31
28
  <span class="missing">
32
- <%= missing_github_oauth_id_message %>
33
- </span>
34
- <% end %>
35
- </p>
36
-
37
- <p id="github_oauth_secret">
38
- Secret:
39
- <% if Shipit.github_oauth_secret.present? %>
40
- Success!
41
- <% else %>
42
- <span class="missing">
43
- <%= missing_github_oauth_secret_message %>
29
+ <%= missing_github_app_message %>
44
30
  </span>
45
31
  <% end %>
46
32
  </p>
47
33
  </section>
48
34
 
49
- <section>
50
- <header class="section-header">
51
- <h2>GitHub API</h2>
52
- </header>
53
-
54
- <p id="github_api">
55
- Token:
56
- <% if Shipit.github_api_credentials.present? %>
57
- Success!
58
- <% else %>
59
- <span class="missing">
60
- <%= missing_github_api_credentials_message %>
61
- </span>
62
- <% end %>
63
- </p>
64
- </section>
65
-
66
35
  <section>
67
36
  <header class="section-header">
68
37
  <h2>Redis</h2>
@@ -9,7 +9,7 @@
9
9
  <div class="field-wrapper">
10
10
  <%= label_tag "Repo" %>
11
11
  <br>
12
- <%= Shipit.github_url %>
12
+ <%= Shipit.github.url %>
13
13
  /
14
14
  <%= f.text_field :repo_owner, placeholder: 'e.g. Shopify', required: true, class: "repo" %>
15
15
  /
@@ -64,10 +64,6 @@
64
64
  <div class="setting-section">
65
65
  <h5>Resynchronize this stack</h5>
66
66
  <table>
67
- <tr>
68
- <td><%= button_to "Webhooks", stack_sync_webhooks_path(@stack), class: "btn", method: "post" %></td>
69
- <td>Ensure that all required webhooks have been created.</td>
70
- </tr>
71
67
  <tr>
72
68
  <td><%= button_to "Clear Git Cache", stack_clear_git_cache_path(@stack), class: "btn", method: "post" %></td>
73
69
  <td>Delete the local git mirror in case it's in a bad state.</td>
@@ -8,18 +8,7 @@ Shipit::Engine.routes.draw do
8
8
  # Robots
9
9
  get '/status/version' => 'status#version', as: :version
10
10
 
11
- resources :stacks, only: %i(new create index) do
12
- resource :webhooks, only: [] do
13
- post :push, :state
14
- end
15
- end
16
-
17
- resources :webhooks, only: [] do
18
- collection do
19
- post :membership
20
- get :membership
21
- end
22
- end
11
+ resources :webhooks, only: :create
23
12
 
24
13
  # API
25
14
  namespace :api do
@@ -50,6 +39,8 @@ Shipit::Engine.routes.draw do
50
39
  end
51
40
 
52
41
  # Humans
42
+ resources :stacks, only: %i(new create index)
43
+
53
44
  scope '/github/auth/github', as: :github_authentication, controller: :github_authentication do
54
45
  get '/', action: :request
55
46
  post :callback
@@ -64,7 +55,6 @@ Shipit::Engine.routes.draw do
64
55
  get :settings, controller: :stacks
65
56
  post :refresh, controller: :stacks
66
57
  get :refresh, controller: :stacks # For easier design, sorry :/
67
- post :sync_webhooks, controller: :stacks
68
58
  post :clear_git_cache, controller: :stacks
69
59
  end
70
60
 
@@ -1,19 +1,14 @@
1
1
  host: 'https://shipit-engine.myshopify.io'
2
2
  redis_url: 'redis://shipit-engine.railgun:6379'
3
3
 
4
- github_api:
5
- # Can be obtained there: https://github.com/settings/tokens/new
6
- # The required permissions are: `admin:org_hook`, `admin:repo_hook`, `read:org` and `repo`
4
+ # TODO: document creating a dev app
5
+ github:
6
+ app_id:
7
+ installation_id:
8
+ webhook_secret: # nil
9
+ private_key:
10
+ oauth:
11
+ id:
12
+ secret:
13
+ teams:
7
14
  access_token:
8
-
9
- # Can be obtained there: https://github.com/settings/applications/new
10
- # Set the "Authorization callback URL" as `<host>/github/auth/github/callback`
11
- github_oauth:
12
- id:
13
- secret:
14
- # teams: # Optional
15
-
16
- # To work on the kubernetes deploy script
17
- # env:
18
- # KUBECONFIG: # Path of the kubeconfig you want to use.
19
- # GOOGLE_APPLICATION_CREDENTIALS: # Used if your kube auth provider is gcp, in which case it should be path of the service account credentials you want to use. Alternatively, you can run `gcloud auth application-default login` (and remove this variable) to use your own google account locally.
@@ -1,7 +1,7 @@
1
1
  host: 'http://shipit-engine.localhost'
2
2
  redis_url: 'redis://shipit-engine.railgun:6379'
3
3
 
4
- github_api:
4
+ github:
5
5
  access_token: 4cc410d7a8fb04f6095076f519f7e0981d915136
6
6
 
7
7
  # If you want to test GitHub Authentication
@@ -0,0 +1,11 @@
1
+ class RemoveAllGithubHooks < ActiveRecord::Migration[5.1]
2
+ def change
3
+ if !Shipit.legacy_github_api && Shipit::GithubHook.any?
4
+ Rails.logger.error("Can't destroy github hooks because no legacy token is configred")
5
+ else
6
+ Shipit::GithubHook.find_each do |hook|
7
+ Shipit::DestroyJob.perform_later(hook)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -26,10 +26,13 @@ require 'redis-objects'
26
26
  require 'redis-namespace'
27
27
 
28
28
  require 'octokit'
29
+ require 'shipit/octokit_bot_users_patch'
30
+
29
31
  require 'faraday-http-cache'
30
32
 
31
33
  require 'shipit/version'
32
34
 
35
+ require 'shipit/github_app'
33
36
  require 'shipit/paginator'
34
37
  require 'shipit/null_serializer'
35
38
  require 'shipit/csv_serializer'
@@ -72,39 +75,24 @@ module Shipit
72
75
  Redis::Namespace.new(namespace, redis: @redis)
73
76
  end
74
77
 
75
- def github_domain
76
- @github_domain ||= secrets.github_domain.presence || 'github.com'.freeze
77
- end
78
-
79
- def github_enterprise?
80
- github_domain != 'github.com'
78
+ def github
79
+ @github ||= GitHubApp.new(secrets.github)
81
80
  end
82
81
 
83
- def github_url(path = nil)
84
- @github_url ||= "https://#{github_domain}".freeze
85
- path ? File.join(@github_url, path) : @github_url
86
- end
87
-
88
- def github_api_endpoint
89
- github_url('/api/v3/') if github_enterprise?
82
+ def legacy_github_api
83
+ if secrets&.github_api.present?
84
+ @legacy_github_api ||= Octokit::Client.new(access_token: secrets.github_api['access_token'])
85
+ end
90
86
  end
91
87
 
92
88
  def user
93
- if github_api.login
94
- User.find_or_create_by_login!(github_api.login)
89
+ if github.bot_login
90
+ User.find_or_create_by_login!(github.bot_login)
95
91
  else
96
92
  AnonymousUser.new
97
93
  end
98
94
  end
99
95
 
100
- def github_api
101
- @github_api ||= begin
102
- client = Octokit::Client.new(github_api_credentials)
103
- client.middleware = new_faraday_stack
104
- client
105
- end
106
- end
107
-
108
96
  def new_faraday_stack
109
97
  Faraday::RackBuilder.new do |builder|
110
98
  builder.use(
@@ -121,10 +109,6 @@ module Shipit
121
109
  end
122
110
  end
123
111
 
124
- def github_api_credentials
125
- {api_endpoint: github_api_endpoint}.merge((Rails.application.secrets.github_api || {}).symbolize_keys)
126
- end
127
-
128
112
  def api_clients_secret
129
113
  secrets.api_clients_secret.presence || secrets.secret_key_base
130
114
  end
@@ -150,39 +134,12 @@ module Shipit
150
134
  end
151
135
 
152
136
  def github_teams
153
- @github_teams ||= github_teams_handles.map { |t| Team.find_or_create_by_handle(t) }
154
- end
155
-
156
- def github_teams_handles
157
- (Array(github_oauth_credentials['team']) + Array(github_oauth_credentials['teams'])).sort.uniq
158
- end
159
-
160
- def github_oauth_id
161
- github_oauth_credentials['id']
162
- end
163
-
164
- def github_oauth_secret
165
- github_oauth_credentials['secret']
166
- end
167
-
168
- def github_oauth_credentials
169
- (secrets.github_oauth || {}).to_h.stringify_keys
170
- end
171
-
172
- def github_oauth_options
173
- return {} unless github_enterprise?
174
- {
175
- site: github_api_endpoint,
176
- authorize_url: github_url('/login/oauth/authorize'),
177
- token_url: github_url('/login/oauth/access_token'),
178
- }
137
+ @github_teams ||= github.oauth_teams.map { |t| Team.find_or_create_by_handle(t) }
179
138
  end
180
139
 
181
140
  def all_settings_present?
182
141
  @all_settings_present ||= [
183
- github_oauth_id,
184
- github_oauth_secret,
185
- github_api_credentials,
142
+ secrets.github, # TODO: handle GitHub settings
186
143
  redis_url,
187
144
  host,
188
145
  ].all?(&:present?)