##// END OF EJS Templates
Add option to test without posting results.
Thomas Kluyver -
Show More
@@ -7,7 +7,6 b' except NameError:'
7 7 pass
8 8
9 9 import requests
10 import keyring
11 10 import getpass
12 11 import json
13 12
@@ -15,7 +14,14 b' import json'
15 14 # password
16 15 fake_username = 'ipython_tools'
17 16
17 token = None
18 18 def get_auth_token():
19 global token
20
21 if token is not None:
22 return token
23
24 import keyring
19 25 token = keyring.get_password('github', fake_username)
20 26 if token is not None:
21 27 return token
@@ -28,9 +34,11 b' def get_auth_token():'
28 34
29 35 auth_request = {
30 36 "scopes": [
31 "public_repo"
37 "public_repo",
38 "gist"
32 39 ],
33 "note": "IPython tools"
40 "note": "IPython tools",
41 "note_url": "https://github.com/ipython/ipython/tree/master/tools",
34 42 }
35 43 response = requests.post('https://api.github.com/authorizations',
36 44 auth=(user, pw), data=json.dumps(auth_request))
@@ -39,4 +47,34 b' def get_auth_token():'
39 47 keyring.set_password('github', fake_username, token)
40 48 return token
41 49
50 def make_auth_header():
51 return {'Authorization': 'token ' + get_auth_token()}
52
53 def post_issue_comment(project, num, body):
54 url = 'https://api.github.com/repos/{project}/issues/{num}/comments'.format(project=project, num=num)
55 payload = json.dumps({'body': body})
56 r = requests.post(url, data=payload, headers=make_auth_header())
57
58 def post_gist(content, description='', filename='file', auth=False):
59 """Post some text to a Gist, and return the URL."""
60 post_data = json.dumps({
61 "description": description,
62 "public": True,
63 "files": {
64 filename: {
65 "content": content
66 }
67 }
68 }).encode('utf-8')
69
70 headers = make_auth_header() if auth else {}
71 response = requests.post("https://api.github.com/gists", data=post_data, headers=headers)
72 response.raise_for_status()
73 response_data = json.loads(response.text)
74 return response_data['html_url']
42 75
76 def get_pull_request(project, num):
77 url = "https://api.github.com/repos/{project}/pulls/{num}".format(project=project, num=num)
78 response = requests.get(url)
79 response.raise_for_status()
80 return json.loads(response.text)
@@ -10,14 +10,16 b' from __future__ import print_function'
10 10
11 11 import errno
12 12 from glob import glob
13 import io
13 14 import json
14 15 import os
15 16 import re
16 17 import requests
17 18 import shutil
18 19 from subprocess import call, check_call, check_output, PIPE, STDOUT, CalledProcessError
20 import sys
19 21
20 import gh_auth
22 import gh_api
21 23
22 24 basedir = os.path.join(os.path.expanduser("~"), ".ipy_pr_tests")
23 25 repodir = os.path.join(basedir, "ipython")
@@ -66,10 +68,6 b' def setup():'
66 68 check_call(['git', 'pull', ipy_repository, 'master'])
67 69 os.chdir(basedir)
68 70
69 def get_pull_request(num):
70 url = "https://api.github.com/repos/{project}/pulls/{num}".format(project=gh_project, num=num)
71 return json.loads(requests.get(url).text)
72
73 71 missing_libs_re = re.compile(r"Tools and libraries NOT available at test time:\n"
74 72 r"\s*(.*?)\n")
75 73 def get_missing_libraries(log):
@@ -108,22 +106,6 b' def run_tests(venv):'
108 106 except CalledProcessError as e:
109 107 return False, e.output.decode('utf-8')
110 108
111 def post_gist(content, description='IPython test log', filename="results.log"):
112 """Post some text to a Gist, and return the URL."""
113 post_data = json.dumps({
114 "description": description,
115 "public": True,
116 "files": {
117 filename: {
118 "content": content
119 }
120 }
121 }).encode('utf-8')
122
123 response = requests.post("https://api.github.com/gists", data=post_data)
124 response_data = json.loads(response.text)
125 return response_data['html_url']
126
127 109 def markdown_format(pr, results):
128 110 def format_result(py, passed, gist_url, missing_libraries):
129 111 s = "* %s: " % py
@@ -149,18 +131,33 b' def markdown_format(pr, results):'
149 131
150 132 def post_results_comment(pr, results, num):
151 133 body = markdown_format(pr, results)
152 url = 'https://api.github.com/repos/{project}/issues/{num}/comments'.format(project=gh_project, num=num)
153 payload = json.dumps({'body': body})
154 auth_token = gh_auth.get_auth_token()
155 headers = {'Authorization': 'token ' + auth_token}
156 r = requests.post(url, data=payload, headers=headers)
134 gh_api.post_issue_comment(gh_project, num, body)
157 135
136 def print_results(pr, results):
137 print("\n")
138 if pr['mergeable']:
139 print("**Test results for commit %s merged into master**" % pr['head']['sha'][:7])
140 else:
141 print("**Test results for commit %s (can't merge cleanly)**" % pr['head']['sha'][:7])
142 print("Platform:", sys.platform)
143 for py, passed, gist_url, missing_libraries in results:
144 if passed:
145 print(py, ":", "OK")
146 else:
147 print(py, ":", "Failed")
148 print(" Test log:", gist_url)
149 if missing_libraries:
150 print(" Libraries not available:", missing_libraries)
151 print("Not available for testing:", ", ".join(unavailable_pythons))
158 152
159 if __name__ == '__main__':
160 import sys
161 num = sys.argv[1]
153 def test_pr(num, post_results=True):
154 # Get Github authorisation first, so that the user is prompted straight away
155 # if their login is needed.
156 if post_results:
157 gh_api.get_auth_token()
158
162 159 setup()
163 pr = get_pull_request(num)
160 pr = gh_api.get_pull_request(gh_project, num)
164 161 get_branch(repo=pr['head']['repo']['clone_url'],
165 162 branch=pr['head']['ref'],
166 163 owner=pr['head']['repo']['owner']['login'],
@@ -174,23 +171,27 b" if __name__ == '__main__':"
174 171 if passed:
175 172 results.append((py, True, None, missing_libraries))
176 173 else:
177 gist_url = post_gist(log)
178 results.append((py, False, gist_url, missing_libraries))
174 if post_results:
175 result_locn = gh_api.post_gist(log, description='IPython test log',
176 filename="results.log", auth=True)
177 else:
178 result_locn = os.path.join(venv, pr['head']['sha'][:7]+".log")
179 with io.open(result_locn, 'w', encoding='utf-8') as f:
180 f.write(log)
181 results.append((py, False, result_locn, missing_libraries))
179 182
180 print("\n")
181 if pr['mergeable']:
182 print("**Test results for commit %s merged into master**" % pr['head']['sha'][:7])
183 else:
184 print("**Test results for commit %s (can't merge cleanly)**" % pr['head']['sha'][:7])
185 print("Platform:", sys.platform)
186 for py, passed, gist_url, missing_libraries in results:
187 if passed:
188 print(py, ":", "OK")
189 else:
190 print(py, ":", "Failed")
191 print(" Test log:", gist_url)
192 if missing_libraries:
193 print(" Libraries not available:", missing_libraries)
194 print("Not available for testing:", ", ".join(unavailable_pythons))
195 post_results_comment(pr, results, num)
196 print("(Posted to Github)")
183 print_results(pr, results)
184 if post_results:
185 post_results_comment(pr, results, num)
186 print("(Posted to Github)")
187
188
189 if __name__ == '__main__':
190 import argparse
191 parser = argparse.ArgumentParser(description="Test an IPython pull request")
192 parser.add_argument('-l', '--local', action='store_true',
193 help="Don't publish the results to Github")
194 parser.add_argument('number', type=int, help="The pull request number")
195
196 args = parser.parse_args()
197 test_pr(args.number, post_results=(not args.local))
General Comments 0
You need to be logged in to leave comments. Login now