|
3 | 3 | import sys |
4 | 4 | import os |
5 | 5 | import json |
| 6 | +import requests |
6 | 7 | from distutils.util import strtobool |
7 | | -# import Github |
| 8 | +from requests.adapters import HTTPAdapter |
| 9 | +from requests.packages.urllib3.util.retry import Retry |
8 | 10 |
|
9 | | -# Script args: |
| 11 | +# Expected script args: |
10 | 12 | # sys.argv[1] - Pattern (string) |
11 | 13 | # sys.argv[2] - Check commit title (bool) |
12 | 14 | # sys.argv[3] - Check commit body (bool) |
|
25 | 27 |
|
26 | 28 | ##### Functions ##### |
27 | 29 | def check_valid_title(pull_request_json): |
28 | | - # Check if there is a title element (first line of the git commit message) |
29 | 30 | if "title" in pull_request_json: |
30 | 31 | # Check that it's not set to null/empty |
31 | 32 | if pull_request_json['title'] is not None: |
32 | | - regex_match = re.search(pattern, pull_request_json['title']) |
33 | | - return regex_match |
| 33 | + return re.search(pattern, pull_request_json['title']) |
34 | 34 | else: |
35 | 35 | return False # Didn't contain anything/exist, so cant be valid |
36 | 36 | else: |
37 | 37 | raise SystemExit('Did not find the expected title elemment in the pull request event data!') |
38 | 38 |
|
| 39 | +def check_valid_title_from_api(github_commits_from_api_json): |
| 40 | + if "commit" in github_commits_from_api_json: |
| 41 | + if "message" in github_commits_from_api_json['commit']: |
| 42 | + title = github_commits_from_api_json['commit']['message'].splitlines()[0] |
| 43 | + |
| 44 | + if title is not None: |
| 45 | + return re.search(pattern, title) |
| 46 | + else: |
| 47 | + return False # Didn't contain anything/exist, so cant be valid |
| 48 | + |
| 49 | +def check_valid_body_from_api(github_commits_from_api_json): |
| 50 | + if "commit" in github_commits_from_api_json: |
| 51 | + if "message" in github_commits_from_api_json['commit']: |
| 52 | + body = '\n'.join(github_commits_from_api_json['commit']['message'].splitlines()[1:]) |
| 53 | + |
| 54 | + if body is not None: |
| 55 | + return re.search(pattern, body) |
| 56 | + else: |
| 57 | + return False # Didn't contain anything/exist, so cant be valid |
| 58 | + |
| 59 | +def check_valid_message_from_api(github_commits_from_api_json): |
| 60 | + if "commit" in github_commits_from_api_json: |
| 61 | + if "message" in github_commits_from_api_json['commit']: |
| 62 | + if github_commits_from_api_json['commit']['message'] is not None: |
| 63 | + return re.search(pattern, github_commits_from_api_json['commit']['message']) |
| 64 | + else: |
| 65 | + return False # Didn't contain anything/exist, so cant be valid |
| 66 | + |
39 | 67 | def check_valid_body(pull_request_json): |
40 | | - # Check if there is a body element (the rest of the commit message, excl the first line) |
41 | 68 | if "body" in pull_request_json: |
42 | 69 | # Check that it's not set to null/empty |
43 | 70 | if pull_request_json['body'] is not None: |
44 | | - regex_match = re.search(pattern, pull_request_json['body']) |
45 | | - return regex_match |
| 71 | + return re.search(pattern, pull_request_json['body']) |
| 72 | + |
46 | 73 | else: |
47 | 74 | return False # Didn't contain anything/exist, so cant be valid |
48 | 75 | else: |
@@ -87,14 +114,50 @@ def get_pull_request_json(): |
87 | 114 | except: |
88 | 115 | raise SystemExit('Unable to parse the pull request!') |
89 | 116 |
|
| 117 | +def get_github_commits_from_api(pull_request_json): |
| 118 | + if "commits_url" in pull_request_json: |
| 119 | + auth_headers = {"Authorization": f"token {github_token}"} |
| 120 | + |
| 121 | + try: |
| 122 | + session = requests.Session() |
| 123 | + retries = Retry(total=10, backoff_factor=1, status_forcelist=[ 404, 429, 500, 502, 503, 504 ]) |
| 124 | + session.mount('https://', HTTPAdapter(max_retries=retries)) |
| 125 | + |
| 126 | + resp = session.get(pull_request_json['commits_url'], headers=auth_headers) |
| 127 | + if resp.status_code == 200: |
| 128 | + return resp.json() |
| 129 | + else: |
| 130 | + raise SystemExit('Recieved unknown response code from the Github REST API!') |
| 131 | + except: |
| 132 | + raise SystemExit('Could not talk to the Github API, gave up after 10 retries!') |
| 133 | + else: |
| 134 | + raise SystemExit('The event file did not contain a commits_url element!') |
| 135 | + |
90 | 136 | ##### Main ##### |
91 | 137 | if __name__ == '__main__': |
92 | 138 | valid_pull_request = True # Assume true, unless checks fail |
93 | 139 |
|
94 | 140 | pull_request_json = get_pull_request_json() |
95 | 141 |
|
96 | 142 | if check_all_commits: |
97 | | - pass |
| 143 | + print("Fetching all commits with the Github REST API") |
| 144 | + |
| 145 | + # Get a json list of commmits, they dont contain title/body, so we need to parse that ourself |
| 146 | + github_api_commits = get_github_commits_from_api(pull_request_json) |
| 147 | + |
| 148 | + # Go through each commit and see if they are valid |
| 149 | + for commit in github_api_commits: |
| 150 | + if check_commit_title: |
| 151 | + if not check_valid_title_from_api(commit): |
| 152 | + valid_pull_request = False |
| 153 | + |
| 154 | + if check_commit_body: |
| 155 | + if not check_valid_body_from_api(commit): |
| 156 | + valid_pull_request = False |
| 157 | + |
| 158 | + if check_commit_message: |
| 159 | + if not check_valid_title_from_api(commit): |
| 160 | + valid_pull_request = False |
98 | 161 | else: |
99 | 162 | # We can rely on just the pull request json without having to use PyGithub |
100 | 163 | if check_commit_title: |
|
0 commit comments