Skip to content

Commit 6a3fb45

Browse files
omgjlkwestphahl
authored andcommitted
Add classes to support Checks API
This adds a new 'checks' module with classes to support the Checks API (https://developer.github.com/v3/checks/). The CheckSuite and CheckRun classes will be used to represent those objects. There are some TODOs left in. Additional classes are needed to handle a CheckRun output, which itelf needs classes for CheckRunAnnotation and CheckRunAction. For now those are left in raw hash form. Additionally when updating a CheckRun deeper cleaning of the parameters is needed, as the parameters can include a list (of hashes) and a hash. Testing has not been introduced yet. The APIs these classes use can only be accessed by properly authenticated and authorized GitHub Apps (https://developer.github.com/apps/about-apps/). When support for these Apps lands I'm sure there will be new decorators to use to indicate the requirement. See sigmavirus24#887 for further details.
1 parent 5deccee commit 6a3fb45

File tree

1 file changed

+277
-0
lines changed

1 file changed

+277
-0
lines changed

src/github3/checks.py

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
# -*- coding: utf-8 -*-
2+
"""This module contains all the classes relating to Checks."""
3+
from __future__ import unicode_literals
4+
5+
from json import dumps
6+
7+
from . import models
8+
from . import pulls
9+
from .repos import ShortRepository
10+
from .decorators import requires_auth
11+
12+
13+
class CheckSuite(models.GitHubCore):
14+
"""The :class:`CheckSuite <CheckSuite>` object.
15+
16+
Please see GitHub's `CheckSuite Documentation`_ for more information.
17+
18+
.. attribute:: status
19+
20+
The status of the Check Suite
21+
22+
.. attribute:: conclusion
23+
24+
The highest priority check run conclusion. If it has not completed this
25+
will be None
26+
27+
.. attribute:: head_sha
28+
29+
The sha of the commit at the head of the branch checked
30+
31+
.. attribute:: head_branch
32+
33+
The branch checked
34+
35+
.. attribute:: before
36+
37+
The sha of the target branch before the change
38+
39+
.. attribute:: after
40+
41+
The sha of the target branch after the change is applied
42+
43+
.. attribute:: repository
44+
45+
A representation of the repository the suite belongs to as
46+
:class:`~github3.repos.repo.ShortRepository`.
47+
48+
.. attribute:: pull_requests
49+
50+
A list of representations of the pull requests the suite belongs to as
51+
:class:`~github3.pulls.ShortPullRequest`. This may be empty.
52+
53+
.. attribute:: id
54+
55+
The unique GitHub assigned numerical id of this check suite.
56+
57+
.. CheckSuite Documentation:
58+
http://developer.github.com/v3/checks/suites/
59+
"""
60+
61+
class_name = 'CheckSuite'
62+
CUSTOM_HEADERS = {
63+
'Accept': 'application/vnd.github.antiope-preview+json'
64+
}
65+
66+
def _update_attributes(self, suite):
67+
self._api = suite['url']
68+
#self.base = Base(pull['base'], self)
69+
self.status = suite['status']
70+
self.conclusion = suite['conclusion']
71+
self.head_branch = suite['head_branch']
72+
self.head_sha = suite['head_sha']
73+
self.before = suite['before']
74+
self.after = suite['after']
75+
pull_requests = suite.get('pull_requests', [])
76+
self.pull_requests = [
77+
pulls.ShortPullRequest(p, self) for p in pull_requests
78+
]
79+
self.repository = ShortRepository(suite['repository'], self)
80+
self.id = suite['id']
81+
82+
def _repr(self):
83+
return '<{0} [{1}]>'.format(self.class_name, self.id)
84+
# FIXME(omgjlk): This could be more descriptive perhaps
85+
86+
@requires_auth
87+
def rerequest(self):
88+
"""Rerequest the check suite.
89+
90+
:returns:
91+
True if successful, False otherwise
92+
:rtype:
93+
bool
94+
"""
95+
96+
url = self._build_url('rerequest', base_url=self._api)
97+
return self._boolean(self._post(
98+
url, headers=CheckSuite.CUSTOM_HEADERS), 201, 404)
99+
100+
@requires_auth
101+
def check_runs(self):
102+
"""Retrieve the check runs for this suite.
103+
104+
:returns:
105+
the check runs for this commit
106+
:rtype:
107+
:class:`~github3.checks.CheckRun`
108+
"""
109+
url = self._build_url('check-runs', base_url=self._api)
110+
return self._iter(-1, url, CheckRun)
111+
112+
113+
class CheckRun(models.GitHubCore):
114+
"""The :class:`CheckRun <CheckRun>` object.
115+
116+
Please see GitHub's `CheckRun Documentation`_ for more information.
117+
118+
.. attribute:: status
119+
120+
The current status of the check.
121+
122+
.. attribute:: conclusion
123+
124+
The final conclusion of the check. If the run has not concluded
125+
this will be None.
126+
127+
.. attribute:: head_sha
128+
129+
The sha of the commit at the head of the branch checked.
130+
131+
.. attribute:: name
132+
133+
The name of the check.
134+
135+
.. attribute:: started_at
136+
137+
A :class:`~datetime.datetime` object representing the date and time
138+
when this check run started.
139+
140+
.. attribute:: completed_at
141+
142+
A :class:`~datetime.datetime` object representing the date and time
143+
when this check run completed. If this run is not completed it will
144+
be ``None``.
145+
146+
.. attribute:: pull_requests
147+
148+
A list of representations of the pull requests the check run belongs to as
149+
:class:`~github3.pulls.ShortPullRequest` (this may be empty).
150+
151+
.. attribute:: id
152+
153+
The unique GitHub assigned numerical id of this check run.
154+
155+
.. attribute:: external_id
156+
157+
A reference for the run on the integrator's system. This may be None.
158+
159+
.. attribute:: html_url
160+
161+
The URL one would use to view this check run in the browser.
162+
163+
.. attribute:: check_suite
164+
165+
The ID of the check suite this run belongs to.
166+
167+
.. attribute:: output
168+
169+
A :class:`~github3.checks.CheckRunOutput` representing the output
170+
of this check run. (TODO: Implement this object)
171+
172+
.. attribute:: app
173+
174+
A :class:`~github3.apps.App` representing the App
175+
this run belongs to. (TODO: Implement this)
176+
177+
.. CheckRun Documentation:
178+
http://developer.github.com/v3/checks/runs/
179+
"""
180+
181+
class_name = 'CheckRun'
182+
CUSTOM_HEADERS = {
183+
'Accept': 'application/vnd.github.antiope-preview+json'
184+
}
185+
186+
def _update_attributes(self, run):
187+
self._api = run['url']
188+
self.html_url = run['html_url']
189+
self.status = run['status']
190+
self.conclusion = run['conclusion']
191+
self.started_at = self._strptime(run['created_at'])
192+
self.completed_at = self._strptime(run['completed_at'])
193+
self.head_sha = run['head_sha']
194+
self.name = run['name']
195+
pull_requests = run.get('pull_requests', [])
196+
self.pull_requests = [
197+
pulls.ShortPullRequest(p, self) for p in pull_requests
198+
]
199+
self.id = run['id']
200+
self.external_id = run['external_id']
201+
# self.app = app.App(run['app'], self)
202+
self.app = run['app'] # TODO: turn into an object
203+
self.check_suite = run['check_suite']['id']
204+
# self.output = CheckRunOutput(run['output'], self)
205+
self.output = run['output'] # TODO: turn into an object
206+
207+
def _repr(self):
208+
return '<{s.class_name} [{s.name}:{s.status}]>'.format(s=self)
209+
210+
@requires_auth
211+
def update(self, name=None, details_url=None, external_id=None,
212+
started_at=None, status=None, conclusion=None,
213+
completed_at=None, output=None, actions=None):
214+
"""Update this check run.
215+
216+
All parameters are optional.
217+
218+
:param str name:
219+
(optional), new name of the check
220+
:param str details_url:
221+
(optional), The URL of the integrator's site that has the full
222+
details of the check
223+
:param str external_id:
224+
(optional), A reference for the run on the integrator's system
225+
:param str started_at:
226+
(optional), ISO 8601 time format: YYYY-MM-DDTHH:MM:SSZ
227+
:param str status:
228+
(optional), ('queued', 'in_progress', 'completed')
229+
:param str conclusion:
230+
(optional), Required if you provide 'completed_at', or a
231+
'status' of 'completed'. The final conclusion of the check.
232+
('success', 'failure', 'neutral', 'cancelled', 'timed_out',
233+
'action_required')
234+
:param str completed_at:
235+
(optional), Required if you provide 'conclusion'. ISO 8601 time
236+
format: YYYY-MM-DDTHH:MM:SSZ
237+
:param dict output:
238+
(optional), key-value pairs representing the output. Format:
239+
{'title': 'string', 'summary', 'text, can be markdown', 'text':
240+
'text, can be markdown', 'annotations': [{}], 'images': [{}]}
241+
:param array actions:
242+
(optiona), array of action objects. Object format is:
243+
{'label': 'text', 'description', 'text', 'identifier', 'text'}
244+
:returns:
245+
True if successful, False otherwise
246+
:rtype:
247+
bool
248+
"""
249+
250+
# TODO: Clean output dict, actions array. Need a deep recursive clean
251+
data = {'name': name, 'details_url': details_url, 'external_id':
252+
external_id, 'started_at': started_at, 'status': status,
253+
'conclusion': conclusion, 'completed_at': completed_at,
254+
'output': output, 'actions': actions}
255+
self._remove_none(data)
256+
json = None
257+
258+
if data:
259+
json = self._json(self._patch(self._api, data=dumps(data)), 200)
260+
if json:
261+
self._update_attributes(json)
262+
return True
263+
return False
264+
265+
@requires_auth
266+
def rerequest(self):
267+
"""Rerequest the check suite.
268+
269+
:returns:
270+
True if successful, False otherwise
271+
:rtype:
272+
bool
273+
"""
274+
275+
url = self._build_url('rerequest', base_url=self._api)
276+
return self._boolean(self._post(
277+
url, headers=CheckSuite.CUSTOM_HEADERS), 201, 404)

0 commit comments

Comments
 (0)