tokite 0.1.5 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cd4cf7e3df9af634d1a79b71996448181b6d3992
4
- data.tar.gz: 99655b09461cd497c09704ae861a43f72b4bd429
3
+ metadata.gz: e5713f325c58d3d8111e0a7d23474ff6f5102a15
4
+ data.tar.gz: c8c4507ea06af90e808469887e83dc8038af430e
5
5
  SHA512:
6
- metadata.gz: b1faa8d9d5bef41d2fe78b5929d4f9d7e307bb616c827e179d755a5d3787cb48953d86b16afe0ccc39a1b1c22de5627561c803fd917c8229166be1f4c9bb2ca2
7
- data.tar.gz: 55b16a25db1f016a4e94f116d88d07124f475d790acdd5e9dc1367da895a10189cd38c71665235f8b75ce3da8fcfecd23340ede0fd4af359241fb7d9ebe8714b
6
+ metadata.gz: 8f13bf68e97bf9ce0b3ff43f1a6326964433545e1b4c6a6456da5371eecda96aa67f88d18e50c5591356cf7a0455f1a8557085f18703deb009eac3d808d9d602
7
+ data.tar.gz: 106be23f58cb08f37146689762decbd6e5d05a902c46ed03afb58392574c88b5715ee8fd0d7bb0a57bdc0d09fcb9c2fbd67f6bc59c5e9e4198afd723d5a98b09
@@ -2,8 +2,8 @@ module Tokite
2
2
  class ApplicationController < ActionController::Base
3
3
  protect_from_forgery with: :exception
4
4
 
5
- helper_method :current_user
6
-
5
+ helper_method :current_user, :current_user_token
6
+
7
7
  before_action :require_login
8
8
 
9
9
  private
@@ -11,10 +11,18 @@ module Tokite
11
11
  def current_user
12
12
  @current_user ||= User.find_by(id: session[:user_id]) if session[:user_id]
13
13
  end
14
-
14
+
15
+ def current_user_token
16
+ current_user&.token
17
+ end
18
+
15
19
  def require_login
16
20
  return if current_user
17
21
  redirect_to sign_in_path
18
22
  end
23
+
24
+ def octokit_client
25
+ @octokit_client ||= Octokit::Client.new(access_token: current_user_token, auto_paginate: true)
26
+ end
19
27
  end
20
28
  end
@@ -5,6 +5,7 @@ module Tokite
5
5
  GITHUB_EVENT_HEADER = "X-GitHub-Event"
6
6
 
7
7
  def create
8
+ logger.debug("Hook triggered: #{github_event}")
8
9
  Hook.fire!(github_event, request.request_parameters)
9
10
  render plain: "ok"
10
11
  end
@@ -0,0 +1,41 @@
1
+ module Tokite
2
+ class RepositoriesController < ApplicationController
3
+ before_action :require_github_token, only: [:new, :create, :destroy]
4
+
5
+ def index
6
+ @repositories = Repository.all
7
+ end
8
+
9
+ def new
10
+ github_repos = octokit_client.repositories.select{|r| r.permissions.admin }.delete_if(&:fork)
11
+ @repositories = github_repos.map do |repo|
12
+ Repository.new(name: repo.full_name, url: repo.html_url)
13
+ end
14
+ Repository.all.pluck(:name).each do |existing_name|
15
+ @repositories.delete_if {|repo| repo.name == existing_name }
16
+ end
17
+ end
18
+
19
+ def create
20
+ params[:names].each do |name|
21
+ github_repo = octokit_client.repository(name)
22
+ Repository.hook!(octokit_client, github_repo)
23
+ end
24
+ flash[:info] = "Import repositories."
25
+ redirect_to repositories_path
26
+ end
27
+
28
+ def destroy
29
+ repo = Repository.find(params[:id])
30
+ repo.unhook!(octokit_client)
31
+ flash[:info] = "Unhook repository #{repo.name}"
32
+ redirect_to repositories_path
33
+ end
34
+
35
+ private
36
+
37
+ def require_github_token
38
+ redirect_to repositories_path unless current_user_token
39
+ end
40
+ end
41
+ end
@@ -5,49 +5,48 @@ module Tokite
5
5
  end
6
6
 
7
7
  def new
8
- @rule = rule_user.rules.build
8
+ @rule_user = User.find(params[:user_id])
9
+ @rule = @rule_user.rules.build
9
10
  end
10
11
 
11
12
  def create
12
- @rule = rule_user.rules.new(rule_params)
13
+ @rule_user = User.find(params[:user_id])
14
+ @rule = @rule_user.rules.new(rule_params)
13
15
  if @rule.save
14
16
  flash[:info] = "Rule created."
15
- redirect_to edit_user_rule_path(params[:user_id], @rule)
17
+ redirect_to user_path(@rule.user_id)
16
18
  else
17
19
  render "new"
18
20
  end
19
21
  end
20
22
 
21
23
  def edit
22
- @rule = rule_user.rules.find(params[:id])
24
+ @rule_user = nil
25
+ @rule = Rule.find(params[:id])
23
26
  end
24
27
 
25
28
  def update
26
- @rule = rule_user.rules.find(params[:id])
29
+ @rule = Rule.find(params[:id])
27
30
  @rule.assign_attributes(rule_params)
28
31
  if @rule.save
29
32
  flash[:info] = "Rule updated."
30
- redirect_to edit_user_rule_path(params[:user_id], @rule)
33
+ redirect_to user_path(@rule.user_id)
31
34
  else
32
35
  render "edit"
33
36
  end
34
37
  end
35
-
38
+
36
39
  def destroy
37
- @rule = rule_user.rules.find(params[:id])
40
+ @rule = Rule.find(params[:id])
38
41
  @rule.destroy!
39
42
  flash[:info] = "Rule deleted."
40
- redirect_to user_rules_path(params[:user_id])
43
+ redirect_to user_path(@rule.user_id)
41
44
  end
42
-
45
+
43
46
  private
44
-
45
- def rule_user
46
- @rule_user ||= User.find(params[:user_id])
47
- end
48
-
47
+
49
48
  def rule_params
50
- params.require(:rule).permit(:name, :query, :channel, :icon_emoji, :additional_text)
49
+ params.require(:rule).permit(:user_id, :name, :query, :channel, :icon_emoji, :additional_text)
51
50
  end
52
51
  end
53
52
  end
@@ -7,18 +7,7 @@ module Tokite
7
7
 
8
8
  def create
9
9
  auth = request.env["omniauth.auth"]
10
- user = User.find_or_initialize_by(
11
- provider: auth[:provider],
12
- uid: auth[:uid],
13
- )
14
- unless user.persisted?
15
- user.update!(
16
- name: auth[:info][:name],
17
- email: auth[:info][:email],
18
- image_url: auth[:info][:image],
19
- )
20
- end
21
-
10
+ user = User.login!(auth)
22
11
  session[:user_id] = user.id
23
12
  redirect_to root_path
24
13
  end
@@ -0,0 +1,14 @@
1
+ module Tokite
2
+ class TransfersController < ApplicationController
3
+ def new
4
+ @transfer = Transfer.new(rule_id: params[:rule_id])
5
+ @rule = @transfer.rule
6
+ @users = User.where.not(id: @rule.user_id)
7
+ end
8
+
9
+ def create
10
+ @transfer = Transfer.create!(rule_id: params[:rule_id], user_id: params[:transfer][:user_id])
11
+ redirect_to user_path(@transfer.rule.user_id)
12
+ end
13
+ end
14
+ end
@@ -26,5 +26,9 @@ module Tokite
26
26
  end
27
27
  end
28
28
  end
29
+
30
+ def show_admin_menu?
31
+ params[:admin]
32
+ end
29
33
  end
30
34
  end
@@ -0,0 +1,41 @@
1
+ module Tokite
2
+ class Repository < ApplicationRecord
3
+ def self.hook!(octokit_client, github_repo)
4
+ repo_name = github_repo.full_name
5
+ existing_hook = find_hook(octokit_client, repo_name)
6
+ if existing_hook
7
+ octokit_client.edit_hook(repo_name, existing_hook.id, "web", hook_config, hook_options)
8
+ else
9
+ octokit_client.create_hook(repo_name, "web", hook_config, hook_options)
10
+ end
11
+ create!(name: repo_name, url: github_repo.html_url)
12
+ end
13
+
14
+ def self.find_hook(octokit_client, repo_name)
15
+ octokit_client.hooks(repo_name).find {|hook| hook.config.url == hooks_url }
16
+ end
17
+
18
+ def self.hook_config
19
+ {
20
+ content_type: "json",
21
+ url: hooks_url,
22
+ }
23
+ end
24
+
25
+ def self.hook_options
26
+ {
27
+ events: ["*"]
28
+ }
29
+ end
30
+
31
+ def self.hooks_url
32
+ Tokite::Engine.routes.url_helpers.hooks_url
33
+ end
34
+
35
+ def unhook!(octokit_client)
36
+ hook = self.class.find_hook(octokit_client, name)
37
+ octokit_client.remove_hook(name, hook.id) if hook
38
+ destroy!
39
+ end
40
+ end
41
+ end
@@ -5,7 +5,8 @@ module Tokite
5
5
  belongs_to :user
6
6
 
7
7
  validate :validate_query
8
-
8
+ validate :validate_user_id
9
+
9
10
  # TODO: Performance
10
11
  def self.matched_rules(event)
11
12
  Rule.all.to_a.select do |rule|
@@ -30,11 +31,11 @@ module Tokite
30
31
  end
31
32
 
32
33
  def rule_name_link
33
- "<#{Tokite::Engine.routes.url_helpers.edit_user_rule_url(user, self)}|#{name}>"
34
+ "<#{Tokite::Engine.routes.url_helpers.edit_rule_url(self)}|#{name}>"
34
35
  end
35
36
 
36
37
  def user_link
37
- "<#{Tokite::Engine.routes.url_helpers.user_rules_url(user)}|#{user.name}>"
38
+ "<#{Tokite::Engine.routes.url_helpers.user_url(user)}|#{user.name}>"
38
39
  end
39
40
 
40
41
  def validate_query
@@ -42,5 +43,11 @@ module Tokite
42
43
  rescue SearchQuery::ParseError => e
43
44
  errors.add(:query, e.message)
44
45
  end
46
+
47
+ def validate_user_id
48
+ unless User.find_by(id: user_id)
49
+ errors.add(:user_id, "Unknown user_id: #{user_id}")
50
+ end
51
+ end
45
52
  end
46
53
  end
@@ -0,0 +1,5 @@
1
+ module Tokite
2
+ class SecureUserToken < ApplicationRecord
3
+ belongs_to :user
4
+ end
5
+ end
@@ -0,0 +1,19 @@
1
+ module Tokite
2
+ class Transfer
3
+ include ActiveModel::Model
4
+
5
+ attr_accessor :rule_id, :user_id
6
+ attr_reader :rule
7
+
8
+ def self.create!(attributes)
9
+ transfer = new(attributes)
10
+ transfer.rule.update!(user_id: transfer.user_id)
11
+
12
+ return transfer
13
+ end
14
+
15
+ def rule
16
+ @rule ||= Rule.find(rule_id)
17
+ end
18
+ end
19
+ end
@@ -1,13 +1,36 @@
1
1
  module Tokite
2
2
  class User < ApplicationRecord
3
3
  has_many :rules, dependent: :destroy
4
-
4
+
5
+ has_one :secure_user_token
6
+
7
+ delegate :token, to: :secure_user_token, allow_nil: true
8
+
9
+ def self.login!(auth)
10
+ user = find_or_initialize_by(
11
+ provider: auth[:provider],
12
+ uid: auth[:uid],
13
+ )
14
+ if user.persisted?
15
+ user.secure_user_token.update!(token: auth[:credentials][:token])
16
+ else
17
+ user.assign_attributes(
18
+ name: auth[:info][:name],
19
+ image_url: auth[:info][:image],
20
+ )
21
+ user.build_secure_user_token(token: auth[:credentials][:token])
22
+ transaction do
23
+ user.save!
24
+ end
25
+ end
26
+ user
27
+ end
28
+
5
29
  def self.create_group_user!(name)
6
30
  uuid = SecureRandom.uuid.tr("-", "")
7
31
  create!(
8
32
  provider: "GROUP",
9
33
  uid: uuid,
10
- email: uuid,
11
34
  image_url: "",
12
35
  name: name
13
36
  )
@@ -16,5 +39,9 @@ module Tokite
16
39
  def group_user?
17
40
  provider == "GROUP"
18
41
  end
42
+
43
+ def name_with_provider
44
+ "#{name} (#{provider})"
45
+ end
19
46
  end
20
47
  end
@@ -1,5 +1,5 @@
1
1
  !!!
2
- %html
2
+ %html{lang: :en}
3
3
  %head
4
4
  %title Tokite
5
5
  = csrf_meta_tags
@@ -15,6 +15,9 @@
15
15
  = nav_list_item "Top", root_path, ["top"]
16
16
  = nav_list_item "Users", users_path, ["users"]
17
17
  = nav_list_item "Rules", rules_path, ["rules"]
18
+ = nav_list_item "Repositories", repositories_path, ["repositories"]
19
+ .nav-right
20
+ %span.nav-item.is-tab= current_user.name_with_provider
18
21
 
19
22
  %section.section
20
23
  - if flash[:info]
@@ -0,0 +1,13 @@
1
+ - if current_user_token
2
+ = link_to "Watch new repositories", new_repository_path, class: "button is-primary"
3
+
4
+ .vspace-40
5
+
6
+ %h1.title Watching repositories
7
+
8
+ %table.table.is-bordered
9
+ - @repositories.each do |repo|
10
+ %tr
11
+ %td= link_to repo.name, repo.url
12
+ - if show_admin_menu?
13
+ %td= link_to "Unwatch", repo, method: :delete, class: "button is-danger", data: { confirm: "Unwatch repository?" }
@@ -0,0 +1,18 @@
1
+ - if @repositories.present?
2
+ = form_tag repositories_path do |f|
3
+ %ul
4
+ - @repositories.each do |repo|
5
+ %li.field
6
+ .control
7
+ %label.checkbox
8
+ = check_box_tag "names[]", repo.name, false, id: "names_#{sanitize_to_id(repo.name)}", multiple: true
9
+ = repo.name
10
+ = link_to "@", repo.url
11
+
12
+ .vspace-40
13
+
14
+ .field
15
+ .control
16
+ = submit_tag "Import repositories", class: "button is-primary"
17
+ - else
18
+ No importable repositories.
@@ -4,10 +4,11 @@
4
4
  = form_text_field f, :channel, size: 40, class: "input"
5
5
  = form_text_field f, :icon_emoji, size: 40, class: "input"
6
6
  = form_text_field f, :additional_text, size: 40, class: "input"
7
- .field
8
- = f.submit class: "button is-primary"
7
+ .field.columns
8
+ .column.is-8= f.submit "Update", class: "button is-primary"
9
9
  - if @rule.persisted?
10
- = link_to "Delete rule", user_rule_path(@rule_user, @rule), method: :delete, data: { confirm: %(Delete "#{@rule.name}"?) }, class: "button is-danger is-pulled-right"
10
+ .column.is-2= link_to "Transfer", new_rule_transfers_path(@rule), class: "button is-primary"
11
+ .column.is-2= link_to "Delete", rule_path(@rule), method: :delete, data: { confirm: %(Delete "#{@rule.name}"?) }, class: "button is-danger"
11
12
 
12
13
  .message.vspace-40
13
14
  .message-header
@@ -2,7 +2,7 @@
2
2
  %h3 Rules
3
3
  %ul
4
4
  - user.rules.order(:id).each do |rule|
5
- %li= link_to rule.name, edit_user_rule_path(user, rule)
5
+ %li= link_to rule.name, edit_rule_path(rule)
6
6
 
7
7
  .content
8
8
  = link_to "New Rule", new_user_rule_path(user), class: "button is-primary"
@@ -1 +1 @@
1
- = link_to "Login with Google+", "/auth/google_oauth2"
1
+ = link_to "Login with GitHub", "/auth/github"
@@ -0,0 +1,8 @@
1
+ %h1.title
2
+ Transfer
3
+ = link_to @rule.name, edit_rule_path(@rule)
4
+
5
+ = form_for [@rule, @transfer] do |f|
6
+ = f.collection_select :user_id, @users, :id, :name_with_provider
7
+ .field.columns
8
+ .column.is-8= f.submit "Transfer", class: "button is-primary"
@@ -8,7 +8,7 @@
8
8
  %tr
9
9
  %td= user.id
10
10
  %td
11
- = link_to user.name, user_path(user)
11
+ = link_to user.name_with_provider, user_path(user)
12
12
 
13
13
  = link_to "Create group", users_path, method: :post, data: { confirm: %(Create Group?) }, class: "button is-primary"
14
14
 
@@ -0,0 +1,7 @@
1
+ require "octokit"
2
+
3
+ if ENV["GITHUB_HOST"].present?
4
+ Octokit.configure do |c|
5
+ c.api_endpoint = URI.join(ENV["GITHUB_HOST"], "/api/v3/").to_s
6
+ end
7
+ end
@@ -1,7 +1,16 @@
1
- require "omniauth-google-oauth2"
1
+ require "omniauth-github"
2
2
 
3
3
  Tokite::Engine.config.middleware.use OmniAuth::Builder do
4
- provider :google_oauth2, ENV["GOOGLE_CLIENT_ID"], ENV["GOOGLE_CLIENT_SECRET"], {
5
- hd: ENV["GOOGLE_HOSTED_DOMAIN"].present? ? ENV["GOOGLE_HOSTED_DOMAIN"] : nil,
6
- }
4
+ options = { scope: "repo,write:repo_hook" }
5
+ host = ENV["GITHUB_HOST"]
6
+ if host.present?
7
+ options.merge!(
8
+ client_options: {
9
+ site: "#{host}/api/v3",
10
+ authorize_url: "#{host}/login/oauth/authorize",
11
+ token_url: "#{host}/login/oauth/access_token",
12
+ }
13
+ )
14
+ end
15
+ provider :github, ENV["GITHUB_CLIENT_ID"], ENV["GITHUB_CLIENT_SECRET"], options
7
16
  end
data/config/routes.rb CHANGED
@@ -3,12 +3,15 @@ Tokite::Engine.routes.draw do
3
3
 
4
4
  resources :hooks, only: %w(create)
5
5
  resources :users, only: %w(index show create edit update destroy) do
6
- resources :rules, only: %w(new create edit update destroy)
6
+ resources :rules, only: %w(new create edit update destroy), shallow: true do
7
+ resource :transfers, only: %w(new create)
8
+ end
7
9
  end
8
10
  resources :rules, only: %w(index)
11
+ resources :repositories, only: %w(index new create destroy)
9
12
 
10
13
  get "sign_in", to: "sessions#new", as: "sign_in"
11
- get "auth/google_oauth2/callback", to: "sessions#create"
14
+ get "auth/github/callback", to: "sessions#create"
12
15
  delete "sign_out", to: "sessions#destroy", as: "sign_out"
13
16
 
14
17
  get "site/sha", to: "sha#show"
@@ -12,12 +12,7 @@ namespace :tokite do
12
12
  yml = Rails.root.join("config/database.yml").to_s
13
13
  sh "bundle", "exec", "ridgepole", "-c", yml, "-E", Rails.env, *args
14
14
  end
15
-
16
- desc "Export current schema"
17
- task :export do
18
- ridgepole_exec("--export", app_path("schema/Schemafile"), "--split")
19
- end
20
-
15
+
21
16
  desc "Apply Schemafile"
22
17
  task :apply do
23
18
  ridgepole_exec("--file", app_path("schema/Schemafile"), "-a")
@@ -30,10 +25,21 @@ namespace :tokite do
30
25
 
31
26
  desc "Install schema"
32
27
  task :install do
28
+ tokite_schema_dir = app_path("schema/tokite")
29
+ mkdir(tokite_schema_dir) unless Dir.exist?(tokite_schema_dir)
30
+
33
31
  schema_dir = app_path("schema")
34
32
  mkdir(schema_dir) unless Dir.exist?(schema_dir)
35
- Dir.glob("#{engine_path("schema")}/*").each do |f|
36
- cp f, schema_dir
33
+
34
+ Dir.glob("#{engine_path("schema")}/*").each do |src_path|
35
+ basename = File.basename(src_path)
36
+ if File.exist?(File.join(tokite_schema_dir, basename))
37
+ puts "Skip install schema #{src_path}"
38
+ else
39
+ puts "Install schema #{src_path}"
40
+ cp src_path, tokite_schema_dir
41
+ cp src_path, schema_dir
42
+ end
37
43
  end
38
44
  end
39
45
  end
@@ -1,3 +1,3 @@
1
1
  module Tokite
2
- VERSION = '0.1.5'
2
+ VERSION = '0.2.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tokite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - hogelog
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-12 00:00:00.000000000 Z
11
+ date: 2017-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -81,7 +81,21 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: omniauth-google-oauth2
84
+ name: omniauth-github
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: octokit
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - ">="
@@ -179,10 +193,12 @@ files:
179
193
  - app/assets/stylesheets/tokite/application.scss
180
194
  - app/controllers/tokite/application_controller.rb
181
195
  - app/controllers/tokite/hooks_controller.rb
196
+ - app/controllers/tokite/repositories_controller.rb
182
197
  - app/controllers/tokite/rules_controller.rb
183
198
  - app/controllers/tokite/sessions_controller.rb
184
199
  - app/controllers/tokite/sha_controller.rb
185
200
  - app/controllers/tokite/top_controller.rb
201
+ - app/controllers/tokite/transfers_controller.rb
186
202
  - app/controllers/tokite/users_controller.rb
187
203
  - app/helpers/tokite/application_helper.rb
188
204
  - app/jobs/tokite/application_job.rb
@@ -194,13 +210,18 @@ files:
194
210
  - app/models/tokite/hook_event/issue_comment.rb
195
211
  - app/models/tokite/hook_event/issues.rb
196
212
  - app/models/tokite/hook_event/pull_request.rb
213
+ - app/models/tokite/repository.rb
197
214
  - app/models/tokite/revision.rb
198
215
  - app/models/tokite/rule.rb
199
216
  - app/models/tokite/search_query.rb
217
+ - app/models/tokite/secure_user_token.rb
218
+ - app/models/tokite/transfer.rb
200
219
  - app/models/tokite/user.rb
201
220
  - app/views/layouts/tokite/application.html.haml
202
221
  - app/views/layouts/tokite/mailer.html.erb
203
222
  - app/views/layouts/tokite/mailer.text.erb
223
+ - app/views/tokite/repositories/index.html.haml
224
+ - app/views/tokite/repositories/new.html.haml
204
225
  - app/views/tokite/rules/_form.html.haml
205
226
  - app/views/tokite/rules/_rules.html.haml
206
227
  - app/views/tokite/rules/edit.html.haml
@@ -208,10 +229,12 @@ files:
208
229
  - app/views/tokite/rules/new.html.haml
209
230
  - app/views/tokite/sessions/new.html.haml
210
231
  - app/views/tokite/top/show.html.haml
232
+ - app/views/tokite/transfers/new.html.haml
211
233
  - app/views/tokite/users/_form.html.haml
212
234
  - app/views/tokite/users/edit.html.haml
213
235
  - app/views/tokite/users/index.html.haml
214
236
  - app/views/tokite/users/show.html.haml
237
+ - config/initializers/octokit.rb
215
238
  - config/initializers/omniauth.rb
216
239
  - config/initializers/slack_notifier.rb
217
240
  - config/routes.rb