Skip to content

Commit ee307c3

Browse files
authored
Merge pull request #110 from sommersoft/fest_of_hacktober
Automate Hacktoberfest Label
2 parents 9fb8d33 + 700f8a9 commit ee307c3

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed

adabot/lib/assign_hacktober_label.py

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# The MIT License (MIT)
2+
#
3+
# Copyright (c) 2019 Michael Schroeder
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in
13+
# all copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
# THE SOFTWARE.
22+
23+
import requests
24+
25+
from adabot import github_requests as github
26+
from adabot.lib import common_funcs
27+
28+
29+
def ensure_hacktober_label_exists(repo):
30+
""" Checks if the 'Hacktoberfest' label exists on the repo.
31+
If not, creates the label.
32+
"""
33+
response = github.get("/repos/" + repo["full_name"] + "/labels")
34+
if not response.ok:
35+
print("Failed to retrieve labels for '{}'".format(repo["name"]))
36+
return False
37+
38+
repo_labels = [label["name"] for label in response.json()]
39+
40+
hacktober_exists = {"Hacktoberfest", "hacktoberfest"} & set(repo_labels)
41+
if not hacktober_exists:
42+
params = {
43+
"name": "Hacktoberfest",
44+
"color": "f2b36f",
45+
"description": "DigitalOcean's Hacktoberfest"
46+
}
47+
result = github.post("/repos/" + repo["full_name"] + "/labels", json=params)
48+
if not result.status_code == 201:
49+
print("Failed to create new Hacktoberfest label for: {}".format(repo["name"]))
50+
return False
51+
52+
return True
53+
54+
def assign_hacktoberfest(repo):
55+
""" Gathers open issues on a repo, and assigns the 'Hacktoberfest' label
56+
to each issue if its not already assigned.
57+
"""
58+
labels_assigned = 0
59+
60+
params = {
61+
"state": "open",
62+
}
63+
response = github.get("/repos/" + repo["full_name"] + "/issues", params=params)
64+
if not response.ok:
65+
print("Failed to retrieve issues for '{}'".format(repo["name"]))
66+
return False
67+
68+
issues = []
69+
while response.ok:
70+
issues.extend([issue for issue in response.json() if "pull_request" not in issue])
71+
72+
try:
73+
links = response.headers["Link"]
74+
except KeyError:
75+
break
76+
next_url = None
77+
for link in links.split(","):
78+
link, rel = link.split(";")
79+
link = link.strip(" <>")
80+
rel = rel.strip()
81+
if rel == "rel=\"next\"":
82+
next_url = link
83+
break
84+
if not next_url:
85+
break
86+
87+
response = requests.get(link, timeout=30)
88+
89+
for issue in issues:
90+
label_names = [label["name"] for label in issue["labels"]]
91+
has_good_first = "good first issue" in label_names
92+
has_hacktober = {"Hacktoberfest", "hacktoberfest"} & set(label_names)
93+
94+
if has_good_first and not has_hacktober:
95+
label_exists = ensure_hacktober_label_exists(repo)
96+
if not label_exists:
97+
continue
98+
99+
label_names.append("Hacktoberfest")
100+
params = {
101+
"labels": label_names
102+
}
103+
result = github.patch("/repos/"
104+
+ repo["full_name"]
105+
+ "/issues/"
106+
+ str(issue["number"]),
107+
json=params)
108+
109+
if result.ok:
110+
labels_assigned += 1
111+
else:
112+
# sadly, GitHub will only silently ignore labels that are
113+
# not added and return a 200. so this will most likely only
114+
# trigger on endpoint/connection failures.
115+
print("Failed to add Hacktoberfest label to: {}".format(issue["url"]))
116+
117+
return labels_assigned
118+
119+
def process_hacktoberfest(repo):
120+
result = assign_hacktoberfest(repo)
121+
return result
122+
123+
124+
if __name__ == "__main__":
125+
labels_assigned = 0
126+
127+
print("Checking for open issues to assign the Hacktoberfest label to...")
128+
129+
repos = common_funcs.list_repos()
130+
for repo in repos:
131+
labels_assigned += process_hacktoberfest(repo)
132+
133+
print("Added the Hacktoberfest label to {} issues.".format(labels_assigned))

0 commit comments

Comments
 (0)