4
4
require 'active_support/all'
5
5
require 'octokit'
6
6
7
+ begin
8
+ GITHUB_APP_ID = contents [ "app_id" ]
9
+ path_to_pem = './private-key.pem'
10
+ GITHUB_PRIVATE_KEY = File . read ( path_to_pem )
11
+ rescue KeyError
12
+ $stderr. puts "To run this script, please set the following environment variables:"
13
+ $stderr. puts "- GITHUB_APP_ID: GitHub App ID"
14
+ rescue Exception => e
15
+ $stderr. puts "To run this script, please copy you App's private key to this directory"
16
+ $stderr. puts " and rename it to `private_key.pem`"
17
+ end
18
+
7
19
@client = nil
8
20
21
+ # Webhook listener
9
22
post '/payload' do
10
23
github_event = request . env [ 'HTTP_X_GITHUB_EVENT' ]
11
- if github_event == "integration_installation"
12
- #|| github_event == "installation_repositories"
24
+ if github_event == "installation"
13
25
parse_installation_payload ( request . body . read )
14
26
else
15
27
puts "New event #{ github_event } "
16
28
end
17
-
18
29
end
19
30
31
+ # To authenticate as a GitHub App, generate a private key. Use this key to sign
32
+ # a JSON Web Token (JWT), and encode using the RS256 algorithm. GitHub checks
33
+ # that the request is authenticated by verifying the token with the
34
+ # integration's stored public key. https://git.io/vQOLW
20
35
def get_jwt_token
21
- path_to_pem = './platform-samples-app-bot.2017-06-24.private-key.pem'
22
- private_pem = File . read ( path_to_pem )
23
- private_key = OpenSSL ::PKey ::RSA . new ( private_pem )
36
+ private_key = OpenSSL ::PKey ::RSA . new ( GITHUB_PRIVATE_KEY )
24
37
25
38
payload = {
26
39
# issued at time
27
40
iat : Time . now . to_i ,
28
41
# JWT expiration time (10 minute maximum)
29
42
exp : 5 . minutes . from_now . to_i ,
30
43
# GitHub App's identifier
31
- iss : 2583
44
+ iss : GITHUB_APP_ID
32
45
}
33
46
34
47
JWT . encode ( payload , private_key , "RS256" )
35
48
end
36
49
50
+ # A GitHub App is installed by a user on one or more repositories.
51
+ # The installation ID is passed in the webhook event. This returns all
52
+ # repositories this installation has access to.
37
53
def get_app_repositories
38
-
39
54
json_response = @client . list_installation_repos
40
55
41
56
repository_list = [ ]
@@ -50,7 +65,8 @@ def get_app_repositories
50
65
repository_list
51
66
end
52
67
53
-
68
+ # For each repository that has Issues enabled, create an issue stating that a
69
+ # GitHub App was installed
54
70
def create_issues ( repositories , sender_username )
55
71
repositories . each do |repo |
56
72
begin
@@ -61,19 +77,24 @@ def create_issues(repositories, sender_username)
61
77
end
62
78
end
63
79
80
+ # When an App is added by a user, it will generate a webhook event. Parse an
81
+ # `installation` webhook event, list all repositories this App has access to,
82
+ # and create an issue.
64
83
def parse_installation_payload ( json_body )
65
84
webhook_data = JSON . parse ( json_body )
66
85
if webhook_data [ "action" ] == "created" || webhook_data [ "action" ] == "added"
67
86
installation_id = webhook_data [ "installation" ] [ "id" ]
68
- # Get token for app
69
- puts get_jwt_token
87
+
88
+ # Get JWT for App and get access token for an installation
70
89
jwt_client = Octokit ::Client . new ( :bearer_token => get_jwt_token )
71
90
jwt_client . default_media_type = "application/vnd.github.machine-man-preview+json"
72
91
app_token = jwt_client . create_installation_access_token ( installation_id )
73
92
93
+ # Create octokit client that has access to installation resources
74
94
@client = Octokit ::Client . new ( access_token : app_token [ :token ] )
75
95
@client . default_media_type = "application/vnd.github.machine-man-preview+json"
76
-
96
+
97
+ # List all repositories this installation has access to
77
98
repository_list = [ ]
78
99
if webhook_data [ "installation" ] . key? ( "repositories_added" )
79
100
webhook_data [ "installation" ] [ "repositories_added" ] . each do |repo |
@@ -84,6 +105,7 @@ def parse_installation_payload(json_body)
84
105
repository_list = get_app_repositories
85
106
end
86
107
108
+ # Create an issue in each repository stating an App has been given added
87
109
create_issues ( repository_list , webhook_data [ "sender" ] [ "login" ] )
88
110
end
89
111
end
0 commit comments