Skip to content

Commit fcfbd24

Browse files
committed
ci: overhaul assignment script
Signed-off-by: Anas Nashif <[email protected]>
1 parent a1a6d52 commit fcfbd24

File tree

1 file changed

+56
-23
lines changed

1 file changed

+56
-23
lines changed

scripts/set_assignees.py

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@ def process_pr(gh, maintainer_file, number):
143143
log(f"Too many files changed ({len(fn)}), skipping....")
144144
return
145145

146+
# areas where assignment happens if only area is affected
147+
meta_areas = [
148+
'Release Notes',
149+
'Documentation',
150+
'Samples'
151+
]
152+
146153
for changed_file in fn:
147154

148155
num_files += 1
@@ -163,15 +170,25 @@ def process_pr(gh, maintainer_file, number):
163170
else:
164171
areas = maintainer_file.path2areas(changed_file.filename)
165172

173+
print(f"areas for {changed_file}: {areas}")
174+
166175
if not areas:
167176
continue
168177

178+
# instance of an area, for example a driver or a board, not APIs or subsys code.
169179
is_instance = False
170180
sorted_areas = sorted(areas, key=lambda x: 'Platform' in x.name, reverse=True)
171181
for area in sorted_areas:
172-
c = 1 if not is_instance else 0
182+
# do not count cmake file changes, i.e. when there are changes to
183+
# instances of an area listed in both the subsystem and the
184+
# platform implementing it
185+
if 'CMakeLists.txt' in changed_file.filename or area.name in meta_areas:
186+
c = 0
187+
else:
188+
c = 1 if not is_instance else 0
173189

174190
area_counter[area] += c
191+
print(f"area counter: {area_counter}")
175192
labels.update(area.labels)
176193
# FIXME: Here we count the same file multiple times if it exists in
177194
# multiple areas with same maintainer
@@ -198,22 +215,26 @@ def process_pr(gh, maintainer_file, number):
198215
log(f"Submitted by: {pr.user.login}")
199216
log(f"candidate maintainers: {_all_maintainers}")
200217

201-
assignees = []
202-
tmp_assignees = []
218+
ranked_assignees = []
219+
assignees = None
203220

204221
# we start with areas with most files changed and pick the maintainer from the first one.
205222
# if the first area is an implementation, i.e. driver or platform, we
206223
# continue searching for any other areas involved
207224
for area, count in area_counter.items():
208-
if count == 0:
225+
# if only meta area is affected, assign one of the maintainers of that area
226+
if area.name in meta_areas and len(area_counter) == 1:
227+
assignees = area.maintainers
228+
break
229+
# if no maintainers, skip
230+
if count == 0 or len(area.maintainers) == 0:
209231
continue
232+
# if there are maintainers, but no assignees yet, set them
210233
if len(area.maintainers) > 0:
211-
tmp_assignees = area.maintainers
212234
if pr.user.login in area.maintainers:
213-
# submitter = assignee, try to pick next area and
214-
# assign someone else other than the submitter
215-
# when there also other maintainers for the area
216-
# assign them
235+
# If submitter = assignee, try to pick next area and assign
236+
# someone else other than the submitter, otherwise when there
237+
# are other maintainers for the area, assign them.
217238
if len(area.maintainers) > 1:
218239
assignees = area.maintainers.copy()
219240
assignees.remove(pr.user.login)
@@ -222,16 +243,25 @@ def process_pr(gh, maintainer_file, number):
222243
else:
223244
assignees = area.maintainers
224245

225-
if 'Platform' not in area.name:
226-
break
246+
# found a non-platform area that was changed, pick assignee from this
247+
# area and put them on top of the list, otherwise just append.
248+
if 'Platform' not in area.name:
249+
ranked_assignees.insert(0, area.maintainers)
250+
break
251+
else:
252+
ranked_assignees.append(area.maintainers)
227253

228-
if tmp_assignees and not assignees:
229-
assignees = tmp_assignees
254+
if ranked_assignees:
255+
assignees = ranked_assignees[0]
230256

231257
if assignees:
232258
prop = (found_maintainers[assignees[0]] / num_files) * 100
233259
log(f"Picked assignees: {assignees} ({prop:.2f}% ownership)")
234260
log("+++++++++++++++++++++++++")
261+
elif len(_all_maintainers) > 0:
262+
# if we have maintainers found, but could not pick one based on area,
263+
# then pick the one with most changes
264+
assignees = [next(iter(_all_maintainers))]
235265

236266
# Set labels
237267
if labels:
@@ -282,21 +312,24 @@ def process_pr(gh, maintainer_file, number):
282312
if len(existing_reviewers) < 15:
283313
reviewer_vacancy = 15 - len(existing_reviewers)
284314
reviewers = reviewers[:reviewer_vacancy]
285-
286-
if reviewers:
287-
try:
288-
log(f"adding reviewers {reviewers}...")
289-
if not args.dry_run:
290-
pr.create_review_request(reviewers=reviewers)
291-
except GithubException:
292-
log("cant add reviewer")
293315
else:
294316
log("not adding reviewers because the existing reviewer count is greater than or "
295-
"equal to 15")
317+
"equal to 15. Adding maintainers of all areas as reviewers instead.")
318+
# FIXME: Here we could also add collaborators of the areas most
319+
# affected, i.e. the one with the final assigne.
320+
reviewers = list(_all_maintainers.keys())
321+
322+
if reviewers:
323+
try:
324+
log(f"adding reviewers {reviewers}...")
325+
if not args.dry_run:
326+
pr.create_review_request(reviewers=reviewers)
327+
except GithubException:
328+
log("can't add reviewer")
296329

297330
ms = []
298331
# assignees
299-
if assignees and not pr.assignee:
332+
if assignees and (not pr.assignee or args.dry_run):
300333
try:
301334
for assignee in assignees:
302335
u = gh.get_user(assignee)

0 commit comments

Comments
 (0)