|
17 | 17 | import json
|
18 | 18 | import secrets
|
19 | 19 | from collections import OrderedDict
|
| 20 | +from datetime import datetime |
20 | 21 | from urllib.parse import parse_qs, urlparse
|
21 | 22 |
|
22 | 23 | from compliance.utils.credentials import Config
|
@@ -413,6 +414,56 @@ def get_commit_details(self, repo, since, branch='master', path=None):
|
413 | 414 | opts['path'] = path
|
414 | 415 | return self._make_request('get', f'repos/{repo}/commits', params=opts)
|
415 | 416 |
|
| 417 | + def get_pull_requests(self, repo, since=None, **kwargs): |
| 418 | + """ |
| 419 | + Retrieve a repository's pull request information. |
| 420 | +
|
| 421 | + :param repo: the organization/repository as a string. |
| 422 | + :param since: the starting date/time of a pull request as a datetime. |
| 423 | + :param kwargs: key/value pairs of GH pulls API accepted params |
| 424 | + :returns: Repository pull request metadata |
| 425 | + """ |
| 426 | + api_url = f'repos/{repo.strip("/")}/pulls' |
| 427 | + self.session.headers.update( |
| 428 | + {'Accept': 'application/vnd.github.v3+json'} |
| 429 | + ) |
| 430 | + if not since: |
| 431 | + return self._paginate_api(api_url, **kwargs) |
| 432 | + pull_requests = [] |
| 433 | + params = {**kwargs} |
| 434 | + params['page'] = kwargs.get('page', 1) |
| 435 | + # Sort results by "created" in descending order |
| 436 | + params['sort'] = 'created' |
| 437 | + params['direction'] = 'desc' |
| 438 | + response = self._make_request( |
| 439 | + 'get', api_url, parse=False, params=params |
| 440 | + ) |
| 441 | + max_page = 1 |
| 442 | + if 'Link' in response.headers: |
| 443 | + # Link is only present if there are multiple pages |
| 444 | + link = response.headers['Link'] |
| 445 | + urls = link.replace('>', '').replace('<', '').split() |
| 446 | + parsed_url = urlparse(urls[2].strip(';')) |
| 447 | + max_page = int(parse_qs(parsed_url.query)['page'][0]) |
| 448 | + while response: |
| 449 | + for pull_request in response.json(): |
| 450 | + created_at = datetime.strptime( |
| 451 | + pull_request['created_at'], '%Y-%m-%dT%H:%M:%SZ' |
| 452 | + ) |
| 453 | + # Filter based on provided since datetime |
| 454 | + if created_at < since: |
| 455 | + response = None |
| 456 | + break |
| 457 | + pull_requests.append(pull_request) |
| 458 | + params['page'] += 1 |
| 459 | + if params['page'] > max_page: |
| 460 | + response = None |
| 461 | + else: |
| 462 | + response = self._make_request( |
| 463 | + 'get', api_url, parse=False, params=params |
| 464 | + ) |
| 465 | + return pull_requests |
| 466 | + |
416 | 467 | def get_branch_protection_details(self, repo, branch='master'):
|
417 | 468 | """
|
418 | 469 | Retrieve a repository branch's branch protection details.
|
|
0 commit comments