forked from platisd/definition-of-done
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun_action.py
executable file
·137 lines (117 loc) · 4.63 KB
/
run_action.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env python
import os
import sys
import requests
import argparse
import yaml
MESSAGE_HEADER = os.environ["INPUT_MESSAGE_HEADER"]
EMPTY_CHECKMARK = "- [ ]"
RIGHT_ARROW_EMOJI = "➡️"
def dod_criteria_to_message(dod_criteria):
message = MESSAGE_HEADER + "\n"
for criterion in dod_criteria:
indentation_depth = criterion.count(RIGHT_ARROW_EMOJI)
indentation = 2 * " " * indentation_depth
criterion = criterion.replace(RIGHT_ARROW_EMOJI, "")
message += indentation + EMPTY_CHECKMARK + " " + criterion + "\n"
return message
def has_bot_comment(pull_request_description):
return MESSAGE_HEADER in pull_request_description
def has_unsatisfied_dod(pull_request_description, dod_criteria):
# Extract the bot message from the pull request description
bot_message_begin = pull_request_description.find(MESSAGE_HEADER)
last_criterion = dod_criteria[-1]
bot_message_end = pull_request_description.find(last_criterion)
if bot_message_end == -1:
print(
"DoD criteria are missing. "
+ "Please fully remove any remnants of the bot's comment and try again."
)
return True
bot_message = pull_request_description[bot_message_begin:bot_message_end]
return EMPTY_CHECKMARK in bot_message
def main():
parser = argparse.ArgumentParser(description="Definition of Done checker")
parser.add_argument(
"--pull-request-id", type=str, required=True, help="The pull request id"
)
args = parser.parse_args()
github_workspace = os.environ["GITHUB_WORKSPACE"]
dod_yaml = os.environ["INPUT_DOD_YAML"]
dod_yaml_path = os.path.join(github_workspace, dod_yaml)
config = {}
with open(dod_yaml_path, "r") as stream:
try:
config = yaml.safe_load(stream)
except yaml.YAMLError as yaml_exception:
print("Invalid YAML file")
print(yaml_exception)
return 1
if "dod" not in config:
print("No DoD section in config")
return 1
repo = os.environ.get("GITHUB_REPOSITORY")
pull_request_id = args.pull_request_id
github_token = os.environ.get("INPUT_GITHUB_TOKEN")
github_api_url = os.environ.get("GITHUB_API_URL")
authorization_header = {"authorization": "Bearer %s" % github_token}
issue_url = "%s/repos/%s/issues/%s" % (
github_api_url,
repo,
pull_request_id,
)
get_pull_request_description_result = requests.get(
issue_url, headers=authorization_header
)
if get_pull_request_description_result.status_code != 200:
print(
"Getting pull request description from GitHub failed with code: "
+ str(get_pull_request_description_result.status_code)
)
print(get_pull_request_description_result.text)
return 1
pull_request_description = get_pull_request_description_result.json()["body"]
if not pull_request_description:
pull_request_description = ""
if has_bot_comment(pull_request_description):
if has_unsatisfied_dod(pull_request_description, config["dod"]):
print(
"The Definition of Done for this pull request "
+ "has not been yet been fully marked as satisfied "
+ "by a repository maintainer. "
+ "Please make sure all checkboxes in the relevant pull request "
+ "comment have been checked off."
)
return 1
else:
print("All DoD criteria are satisfied. 🎉")
return 0
else:
bot_message = dod_criteria_to_message(config["dod"])
space_between_message_and_description = (
"\n\n" if pull_request_description else ""
)
update_pull_request_description_result = requests.patch(
issue_url,
headers=authorization_header,
json={
"body": pull_request_description
+ space_between_message_and_description
+ bot_message,
},
)
if update_pull_request_description_result.status_code != 200:
print(
"Updating pull request comment body failed with code: "
+ str(update_pull_request_description_result.status_code)
)
return 1
print(
"The Definition of Done for this pull request "
+ "needs to fully marked as satisfied by a repository maintainer. "
+ "Please make sure a maintainer marks off the checklist "
+ "that was appended to the pull request description."
)
return 1
if __name__ == "__main__":
sys.exit(main())