Skip to content

Commit 08f6518

Browse files
authored
Merge pull request #35 from travis-ci/jc-github-app
[WIP] Accept GH app events
2 parents 637bef5 + ba1679d commit 08f6518

File tree

9 files changed

+212
-47
lines changed

9 files changed

+212
-47
lines changed

Procfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
2+
console: bundle exec irb -I lib -r travis/listener

lib/travis/gatekeeper.rb

Lines changed: 0 additions & 11 deletions
This file was deleted.

lib/travis/listener.rb

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
require 'travis/support'
33
require 'travis/listener/app'
44
require 'logger'
5-
require 'sidekiq'
65

76
$stdout.sync = true
87

@@ -15,23 +14,16 @@ def config
1514

1615
module Listener
1716
class Config < Travis::Config
18-
define redis: { url: 'redis://localhost:6379', namespace: 'sidekiq', network_timeout: 5 },
19-
redis_gatekeeper: { url: ENV['REDIS_GATEKEEPER_URL'] || 'redis://localhost:6379', namespace: 'sidekiq', network_timeout: 5 },
20-
gator: { queue: ENV['SIDEKIQ_GATEKEEPER_QUEUE'] || 'build_requests' },
17+
define redis: { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379'), namespace: 'sidekiq', network_timeout: 5 },
18+
redis_gatekeeper: { url: ENV.fetch('REDIS_GATEKEEPER_URL', 'redis://localhost:6379'), namespace: 'sidekiq', network_timeout: 5 },
19+
gator: { queue: ENV.fetch('SIDEKIQ_GATEKEEPER_QUEUE', 'build_requests') },
20+
sync: { queue: ENV.fetch('SIDEKIQ_SYNC_QUEUE', 'sync.gh_apps') },
2121
sentry: { },
2222
metrics: { reporter: 'librato' }
2323
end
2424

2525
class << self
2626
def setup
27-
::Sidekiq.configure_client do |config|
28-
if ENV['REDIS_GATEKEEPER_ENABLED'] == 'true'
29-
config.redis = Travis.config.redis_gatekeeper.to_h
30-
else
31-
config.redis = Travis.config.redis.to_h
32-
end
33-
end
34-
3527
if Travis.config.sentry.dsn
3628
require 'raven'
3729
::Raven.configure do |config|

lib/travis/listener/app.rb

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
require 'sinatra'
22
require 'travis/support/logging'
33
require 'sidekiq'
4-
require 'travis/gatekeeper'
4+
require 'travis/sidekiq'
55
require 'multi_json'
66
require 'ipaddr'
77
require 'metriks'
@@ -17,7 +17,7 @@ class App < Sinatra::Base
1717
# see https://github.com/github/github-services/blob/master/lib/services/travis.rb#L1-2
1818
# https://github.com/travis-ci/travis-api/blob/255640fd4f191f1de6951081f0c5848324210fb5/lib/travis/github/services/set_hook.rb#L8
1919
# https://github.com/travis-ci/travis-api/blob/255640fd4f191f1de6951081f0c5848324210fb5/lib/travis/api/v3/github.rb#L41
20-
set :events, %w[push pull_request create delete repository]
20+
set :events, %w[push pull_request create delete repository installation installation_repositories]
2121

2222
before do
2323
logger.level = 1
@@ -37,7 +37,7 @@ class App < Sinatra::Base
3737
report_ip_validity
3838
if !ip_validation? || valid_ip?
3939
if valid_request?
40-
handle_event
40+
dispatch_event
4141

4242
204
4343
else
@@ -78,11 +78,24 @@ def valid_ips
7878
(Travis.config.listener && Travis.config.listener.valid_ips) || []
7979
end
8080

81-
def handle_event
81+
def dispatch_event
8282
return unless handle_event?
8383
debug "Event payload for #{uuid}: #{payload.inspect}"
84+
85+
case event_type
86+
when 'push', 'pull_request', 'create', 'delete', 'repository' then gatekeeper_event
87+
when 'installation', 'installation_repositories' then sync_event
88+
end
89+
end
90+
91+
def gatekeeper_event
8492
log_event(event_details, uuid: uuid, delivery_guid: delivery_guid, type: event_type, repository: slug)
85-
Travis::Gatekeeper.push(Travis.config.gator.queue, data)
93+
Travis::Sidekiq::Gatekeeper.push(Travis.config.gator.queue, data)
94+
end
95+
96+
def sync_event
97+
log_event(event_details, uuid: uuid, delivery_guid: delivery_guid, type: event_type)
98+
Travis::Sidekiq::GithubSync.push(data)
8699
end
87100

88101
def handle_event?

lib/travis/sidekiq.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
require 'redis'
2+
require 'sidekiq'
3+
4+
module Travis
5+
module Sidekiq
6+
class Gatekeeper
7+
def self.client
8+
@@client ||= ::Sidekiq::Client.new(
9+
::Sidekiq::RedisConnection.create(Travis.config.redis_gatekeeper.to_h)
10+
)
11+
end
12+
13+
def self.push(queue, *args)
14+
client.push(
15+
'queue' => queue,
16+
'class' => 'Travis::Gatekeeper::Worker',
17+
'args' => args
18+
)
19+
end
20+
end
21+
22+
class GithubSync
23+
def self.gh_app_install(data)
24+
push('sync.gh_apps', :gh_app_install, data)
25+
end
26+
27+
def self.gh_app_repos(data)
28+
push('sync.gh_apps', :gh_app_repos, data)
29+
end
30+
31+
def self.client
32+
@@client ||= ::Sidekiq::Client.new(
33+
::Sidekiq::RedisConnection.create(Travis.config.redis.to_h)
34+
)
35+
end
36+
37+
def self.push(queue, *args)
38+
client.push(
39+
'queue' => queue,
40+
'class' => 'Travis::GithubSync::Worker',
41+
'args' => args
42+
)
43+
end
44+
end
45+
end
46+
end

spec/payloads/installation.json

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"action": "deleted",
3+
"installation": {
4+
"id": 2,
5+
"account": {
6+
"login": "octocat",
7+
"id": 1,
8+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
9+
"gravatar_id": "",
10+
"url": "https://api.github.com/users/octocat",
11+
"html_url": "https://github.com/octocat",
12+
"followers_url": "https://api.github.com/users/octocat/followers",
13+
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
14+
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
15+
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
16+
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
17+
"organizations_url": "https://api.github.com/users/octocat/orgs",
18+
"repos_url": "https://api.github.com/users/octocat/repos",
19+
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
20+
"received_events_url": "https://api.github.com/users/octocat/received_events",
21+
"type": "User",
22+
"site_admin": false
23+
},
24+
"repository_selection": "selected",
25+
"access_tokens_url": "https://api.github.com/installations/2/access_tokens",
26+
"repositories_url": "https://api.github.com/installation/repositories"
27+
},
28+
"sender": {
29+
"login": "octocat",
30+
"id": 1,
31+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
32+
"gravatar_id": "",
33+
"url": "https://api.github.com/users/octocat",
34+
"html_url": "https://github.com/octocat",
35+
"followers_url": "https://api.github.com/users/octocat/followers",
36+
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
37+
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
38+
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
39+
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
40+
"organizations_url": "https://api.github.com/users/octocat/orgs",
41+
"repos_url": "https://api.github.com/users/octocat/repos",
42+
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
43+
"received_events_url": "https://api.github.com/users/octocat/received_events",
44+
"type": "User",
45+
"site_admin": false
46+
}
47+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"action": "removed",
3+
"installation": {
4+
"id": 2,
5+
"account": {
6+
"login": "octocat",
7+
"id": 1,
8+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
9+
"gravatar_id": "",
10+
"url": "https://api.github.com/users/octocat",
11+
"html_url": "https://github.com/octocat",
12+
"followers_url": "https://api.github.com/users/octocat/followers",
13+
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
14+
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
15+
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
16+
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
17+
"organizations_url": "https://api.github.com/users/octocat/orgs",
18+
"repos_url": "https://api.github.com/users/octocat/repos",
19+
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
20+
"received_events_url": "https://api.github.com/users/octocat/received_events",
21+
"type": "User",
22+
"site_admin": false
23+
},
24+
"repository_selection": "selected",
25+
"access_tokens_url": "https://api.github.com/installations/2/access_tokens",
26+
"repositories_url": "https://api.github.com/installation/repositories",
27+
"html_url": "https://github.com/settings/installations/2"
28+
},
29+
"repository_selection": "selected",
30+
"repositories_added": [
31+
32+
],
33+
"repositories_removed": [
34+
{
35+
"id": 1296269,
36+
"name": "Hello-World",
37+
"full_name": "octocat/Hello-World"
38+
}
39+
],
40+
"sender": {
41+
"login": "octocat",
42+
"id": 1,
43+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
44+
"gravatar_id": "",
45+
"url": "https://api.github.com/users/octocat",
46+
"html_url": "https://github.com/octocat",
47+
"followers_url": "https://api.github.com/users/octocat/followers",
48+
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
49+
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
50+
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
51+
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
52+
"organizations_url": "https://api.github.com/users/octocat/orgs",
53+
"repos_url": "https://api.github.com/users/octocat/repos",
54+
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
55+
"received_events_url": "https://api.github.com/users/octocat/received_events",
56+
"type": "User",
57+
"site_admin": false
58+
}
59+
}

spec/travis/app_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
let(:auth) { ['user', '12345'] }
66
let(:payload) { GITHUB_PAYLOADS['gem-release'] }
77
let(:redis) { Redis.new }
8-
let(:queue) { Travis::Gatekeeper }
8+
let(:queue) { Travis::Sidekiq::Gatekeeper }
99

1010
before do
1111
authorize(*auth)

spec/travis/events_spec.rb

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
require 'spec_helper'
22

33
describe Travis::Listener::App do
4-
let(:app) { subject }
5-
let(:auth) { ['user', '12345'] }
6-
let(:payload) { Payloads.load(type) }
7-
let(:redis) { Redis.new }
8-
let(:queue) { Travis::Gatekeeper }
4+
let(:app) { subject }
5+
let(:auth) { ['user', '12345'] }
6+
let(:payload) { Payloads.load(type) }
7+
let(:redis) { Redis.new }
8+
let(:gatekeeper_queue) { Travis::Sidekiq::Gatekeeper }
9+
let(:gh_sync_queue) { Travis::Sidekiq::GithubSync }
910

10-
before { allow(queue).to receive(:push) }
11+
before { allow(gatekeeper_queue).to receive(:push) }
12+
before { allow(gh_sync_queue).to receive(:push) }
1113
before { authorize(*auth) }
1214
before { create }
1315

@@ -18,67 +20,83 @@ def create(opts = {})
1820
post(opts[:url] || '/', params, headers)
1921
end
2022

21-
shared_examples_for 'queues the event' do |&block|
22-
it { expect(queue).to have_received(:push).with('build_requests', hash_including(type: event)) }
23+
shared_examples_for 'queues gatekeeper event' do |&block|
24+
it { expect(gatekeeper_queue).to have_received(:push).with('build_requests', hash_including(type: event)) }
25+
end
26+
27+
shared_examples_for 'queues gh sync event' do |&block|
28+
it { expect(gh_sync_queue).to have_received(:push).with(hash_including(type: event)) }
2329
end
2430

2531
describe 'a push event' do
2632
let(:type) { 'push' }
2733
let(:event) { 'push' }
28-
include_examples 'queues the event'
34+
include_examples 'queues gatekeeper event'
2935
end
3036

3137
describe 'a pull_request event' do
3238
let(:type) { 'pull_request' }
3339
let(:event) { 'pull_request' }
34-
include_examples 'queues the event'
40+
include_examples 'queues gatekeeper event'
3541
end
3642

3743
describe 'a branch_created event' do
3844
let(:type) { 'branch_created' }
3945
let(:event) { 'create' }
40-
include_examples 'queues the event'
46+
include_examples 'queues gatekeeper event'
4147
end
4248

4349
describe 'a branch_deleted event' do
4450
let(:type) { 'branch_deleted' }
4551
let(:event) { 'delete' }
46-
include_examples 'queues the event'
52+
include_examples 'queues gatekeeper event'
4753
end
4854

4955
describe 'a tag_created event' do
5056
let(:type) { 'tag_created' }
5157
let(:event) { 'create' }
52-
include_examples 'queues the event'
58+
include_examples 'queues gatekeeper event'
5359
end
5460

5561
describe 'a tag_deleted event' do
5662
let(:type) { 'tag_deleted' }
5763
let(:event) { 'delete' }
58-
include_examples 'queues the event'
64+
include_examples 'queues gatekeeper event'
5965
end
6066

6167
describe 'a repo_created event' do
6268
let(:type) { 'repo_created' }
6369
let(:event) { 'create' }
64-
include_examples 'queues the event'
70+
include_examples 'queues gatekeeper event'
6571
end
6672

6773
describe 'a repo_deleted event' do
6874
let(:type) { 'repo_deleted' }
6975
let(:event) { 'delete' }
70-
include_examples 'queues the event'
76+
include_examples 'queues gatekeeper event'
7177
end
7278

7379
describe 'a repo_privatized event' do
7480
let(:type) { 'repo_privatized' }
7581
let(:event) { 'repository' }
76-
include_examples 'queues the event'
82+
include_examples 'queues gatekeeper event'
7783
end
7884

7985
describe 'a repo_publicized event' do
8086
let(:type) { 'repo_publicized' }
8187
let(:event) { 'repository' }
82-
include_examples 'queues the event'
88+
include_examples 'queues gatekeeper event'
89+
end
90+
91+
describe 'an installation event' do
92+
let(:type) { 'installation' }
93+
let(:event) { 'installation' }
94+
include_examples 'queues gh sync event'
95+
end
96+
97+
describe 'an installation_repositories event' do
98+
let(:type) { 'installation_repositories' }
99+
let(:event) { 'installation_repositories' }
100+
include_examples 'queues gh sync event'
83101
end
84102
end

0 commit comments

Comments
 (0)