Skip to content
This repository was archived by the owner on Mar 19, 2021. It is now read-only.

Commit 495cf3c

Browse files
committed
Iterate
1 parent 50dd4f4 commit 495cf3c

File tree

1 file changed

+54
-35
lines changed

1 file changed

+54
-35
lines changed

tools/ci/update_pr_preview.py

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
#!/usr/bin/env python
22

3-
# total_count: number
4-
# incomplete_results: boolean
5-
# items: array
3+
# The service provided by this script is not critical, but it shares a GitHub
4+
# API request quota with critical services. For this reason, all requests to
5+
# the GitHub API are preceded by a "guard" which verifies that the subsequent
6+
# request will not deplete the shared quota.
7+
#
8+
# In effect, this script will fail rather than interfere with the operations of
9+
# critical services.
610

711
import argparse
812
import contextlib
@@ -44,16 +48,43 @@ def request(method_name, url, body=None):
4448

4549
return resp.json()
4650

51+
def guard(resource):
52+
'''Decorate a `Project` instance method which interacts with the GitHub
53+
API, ensuring that the subsequent request will not deplete the relevant
54+
allowance. This verification does not itself influence rate limiting:
55+
56+
> Accessing this endpoint does not count against your REST API rate limit.
57+
58+
https://developer.github.com/v3/rate_limit/
59+
'''
60+
def guard_decorator(func):
61+
def wrapped(self, *args, **kwargs):
62+
limits = request('GET', '{}/rate_limit'.format(self._host))
63+
64+
values = limits['resources'].get(resource)
65+
66+
remaining = values['remaining']
67+
limit = values['limit']
68+
69+
logger.info('Limit for "{}" resource: {}/{}'.format(resource, remaining, limit))
70+
71+
if limit and float(remaining) / limit < API_RATE_LIMIT_THRESHOLD:
72+
raise Exception('Exiting to avoid GitHub.com API request throttling.')
73+
74+
return func(self, *args, **kwargs)
75+
return wrapped
76+
return guard_decorator
77+
4778
class Project(object):
48-
def __init__(self, host, org, repo):
79+
def __init__(self, host, github_project):
4980
self._host = host
50-
self._org = org
51-
self._repo = repo
81+
self._github_project = github_project
5282

83+
@guard('search')
5384
def get_pull_requests(self, updated_since):
5485
window_start = time.strftime('%Y-%m-%dT%H:%M:%SZ', updated_since)
55-
url = '{}/search/issues?q=repo:{}/{}+is:pr+updated:>{}'.format(
56-
self._host, self._org, self._repo, window_start
86+
url = '{}/search/issues?q=repo:{}+is:pr+updated:>{}'.format(
87+
self._host, self._github_project, window_start
5788
)
5889

5990
logger.info(
@@ -69,31 +100,34 @@ def get_pull_requests(self, updated_since):
69100

70101
return data['items']
71102

103+
@guard('core')
72104
def add_label(self, pull_request, name):
73105
number = pull_request['number']
74-
url = '{}/repos/{}/{}/issues/{}/labels'.format(
75-
self._host, self._org, self._repo, number
106+
url = '{}/repos/{}/issues/{}/labels'.format(
107+
self._host, self._github_project, number
76108
)
77109

78110
logger.info('Adding label "{}" for pull request #{}"'.format(number, name))
79111

80112
request('POST', url, {'labels': [name]})
81113

114+
@guard('core')
82115
def remove_label(self, pull_request, name):
83116
raise NotImplementedError()
84117

118+
@guard('core')
85119
def create_deployment(self, ref):
86-
url = '{}/repos/{}/{}/deployments'.format(
87-
self._host, self._org, self._repo
120+
url = '{}/repos/{}/deployments'.format(
121+
self._host, self._github_project
88122
)
89123

90124
logger.info('Creating deployment for "{}"'.format(ref))
91125

92126
request('POST', url, {'ref': ref})
93127

94128
class Remote(object):
95-
def __init__(self, url):
96-
self._url = url
129+
def __init__(self, location):
130+
self._location = location
97131

98132
@contextlib.contextmanager
99133
def _make_temp_repo(self):
@@ -113,7 +147,7 @@ def get_revision(self, refspec):
113147
output = subprocess.check_output([
114148
'git',
115149
'ls-remote',
116-
self._url,
150+
self._location,
117151
'refs/{}'.format(refspec)
118152
])
119153

@@ -130,7 +164,7 @@ def delete_ref(self, refspec):
130164

131165
with self._make_temp_repo() as temp_repo:
132166
subprocess.check_call(
133-
['git', 'push', self._url, '--delete', 'refs/{}'.format(refspec)],
167+
['git', 'push', self._location, '--delete', 'refs/{}'.format(refspec)],
134168
cwd=temp_repo
135169
)
136170

@@ -149,24 +183,9 @@ def should_be_mirrored(pull_request):
149183
has_label(pull_request)
150184
)
151185

152-
def main(host, organization, repository):
153-
# > Accessing this endpoint does not count against your REST API rate limit.
154-
#
155-
# https://developer.github.com/v3/rate_limit/
156-
limits = request('GET', 'https://api.github.com/rate_limit')
157-
158-
for name, values in limits['resources'].items():
159-
remaining = values['remaining']
160-
limit = values['limit']
161-
162-
logger.info('Limit for "{}": {}/{}'.format(name, remaining, limit))
163-
164-
if limit and float(remaining) / limit < API_RATE_LIMIT_THRESHOLD:
165-
logger.error('Exiting to avoid GitHub.com API request throttling.')
166-
sys.exit(1)
167-
168-
project = Project(host, organization, repository)
169-
remote = Remote('[email protected]:web-platform-tests/wpt.git')
186+
def main(host, github_project, repository):
187+
project = Project(host, github_project)
188+
remote = Remote(repository)
170189
pull_requests = project.get_pull_requests(
171190
time.gmtime(time.time() - FIVE_MINUTES)
172191
)
@@ -208,7 +227,7 @@ def main(host, organization, repository):
208227
if __name__ == '__main__':
209228
parser = argparse.ArgumentParser()
210229
parser.add_argument('--host', required=True)
211-
parser.add_argument('--organization', required=True)
230+
parser.add_argument('--github-project', required=True)
212231
parser.add_argument('--repository', required=True)
213232

214233
main(**vars(parser.parse_args()))

0 commit comments

Comments
 (0)