forked from jeffkaufman/nomic
-
Notifications
You must be signed in to change notification settings - Fork 0
/
validate.py
131 lines (103 loc) · 3.12 KB
/
validate.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import os
import random
import requests
def request(url):
request_headers = {'User-Agent': 'jeffkaufman/nomic'}
response = requests.get(url, headers=request_headers)
for header in ['X-RateLimit-Limit',
'X-RateLimit-Remaining',
'X-RateLimit-Reset']:
if header in response.headers:
print(' > %s: %s' % (header, response.headers[header]))
if response.status_code != 200:
print(' > %s' % response.content)
response.raise_for_status()
return response
def get_repo():
return os.environ['TRAVIS_REPO_SLUG']
def get_pr():
return os.environ['TRAVIS_PULL_REQUEST']
def get_commit():
return os.environ['TRAVIS_PULL_REQUEST_SHA']
def base_pr_url():
# This is configured in nginx like:
#
# location /nomic-github/repos/jeffkaufman/nomic {
# proxy_pass https://api.github.com/repos/jeffkaufman/nomic;
# proxy_set_header
# Authorization
# "Basic [base64 of 'username:token']";
# }
#
# Where the token is a github personal access token:
# https://github.com/settings/tokens
#
# There's an API limit of 60/hr per IP by default, and 5000/hr by
# user, and we need the higher limit.
return 'https://www.jefftk.com/nomic-github/repos/%s/pulls/%s' % (
get_repo(), get_pr())
def get_author():
response = request(base_pr_url())
return response.json()['user']['login']
def get_reviews():
target_commit = get_commit()
print('Considering reviews at commit %s' % target_commit)
url = '%s/reviews' % base_pr_url()
reviews = {}
while True:
response = request(url)
for review in response.json():
user = review['user']['login']
commit = review['commit_id']
state = review['state']
print(' %s: %s at %s' % (user, state, commit))
if commit != target_commit:
continue # Only accept PR reviews for the most recent commit.
if state == 'COMMENTED':
continue # Ignore comments.
reviews[user] = state
if 'next' in response.links:
url = response.links['next']['url']
else:
return reviews
def get_users():
users = set()
with open('players.txt') as inf:
for line in inf:
line = line.strip()
if line:
users.add(line.strip())
return list(sorted(users))
def determine_if_mergeable():
users = get_users()
print('Users:')
for user in users:
print(' %s' % user)
author = get_author()
print('\nAuthor: %s' % author)
reviews = get_reviews()
if author in users:
reviews[author] = 'APPROVED'
print('\nReviews:')
for user, state in sorted(reviews.items()):
print (' %s: %s' % (user, state))
approval_count = 0
for user in users:
if reviews.get(user, None) == 'APPROVED':
approval_count += 1
if approval_count < len(users):
raise Exception('Insufficient approval.')
print('\nPASS')
def determine_if_winner():
users = get_users()
for user in users:
if random.random() < 0.0001:
raise RuntimeException('%s wins!' % user)
print('The game continues.')
def start():
if get_pr() == 'false':
determine_if_winner()
else:
determine_if_mergeable()
if __name__ == '__main__':
start()