@@ -143,6 +143,13 @@ def process_pr(gh, maintainer_file, number):
143
143
log (f"Too many files changed ({ len (fn )} ), skipping...." )
144
144
return
145
145
146
+ # areas where assignment happens if only area is affected
147
+ meta_areas = [
148
+ 'Release Notes' ,
149
+ 'Documentation' ,
150
+ 'Samples'
151
+ ]
152
+
146
153
for changed_file in fn :
147
154
148
155
num_files += 1
@@ -163,15 +170,25 @@ def process_pr(gh, maintainer_file, number):
163
170
else :
164
171
areas = maintainer_file .path2areas (changed_file .filename )
165
172
173
+ print (f"areas for { changed_file } : { areas } " )
174
+
166
175
if not areas :
167
176
continue
168
177
178
+ # instance of an area, for example a driver or a board, not APIs or subsys code.
169
179
is_instance = False
170
180
sorted_areas = sorted (areas , key = lambda x : 'Platform' in x .name , reverse = True )
171
181
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
173
189
174
190
area_counter [area ] += c
191
+ print (f"area counter: { area_counter } " )
175
192
labels .update (area .labels )
176
193
# FIXME: Here we count the same file multiple times if it exists in
177
194
# multiple areas with same maintainer
@@ -198,22 +215,26 @@ def process_pr(gh, maintainer_file, number):
198
215
log (f"Submitted by: { pr .user .login } " )
199
216
log (f"candidate maintainers: { _all_maintainers } " )
200
217
201
- assignees = []
202
- tmp_assignees = []
218
+ ranked_assignees = []
219
+ assignees = None
203
220
204
221
# we start with areas with most files changed and pick the maintainer from the first one.
205
222
# if the first area is an implementation, i.e. driver or platform, we
206
223
# continue searching for any other areas involved
207
224
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 :
209
231
continue
232
+ # if there are maintainers, but no assignees yet, set them
210
233
if len (area .maintainers ) > 0 :
211
- tmp_assignees = area .maintainers
212
234
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.
217
238
if len (area .maintainers ) > 1 :
218
239
assignees = area .maintainers .copy ()
219
240
assignees .remove (pr .user .login )
@@ -222,16 +243,25 @@ def process_pr(gh, maintainer_file, number):
222
243
else :
223
244
assignees = area .maintainers
224
245
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 )
227
253
228
- if tmp_assignees and not assignees :
229
- assignees = tmp_assignees
254
+ if ranked_assignees :
255
+ assignees = ranked_assignees [ 0 ]
230
256
231
257
if assignees :
232
258
prop = (found_maintainers [assignees [0 ]] / num_files ) * 100
233
259
log (f"Picked assignees: { assignees } ({ prop :.2f} % ownership)" )
234
260
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 ))]
235
265
236
266
# Set labels
237
267
if labels :
@@ -282,21 +312,24 @@ def process_pr(gh, maintainer_file, number):
282
312
if len (existing_reviewers ) < 15 :
283
313
reviewer_vacancy = 15 - len (existing_reviewers )
284
314
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" )
293
315
else :
294
316
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" )
296
329
297
330
ms = []
298
331
# assignees
299
- if assignees and not pr .assignee :
332
+ if assignees and ( not pr .assignee or args . dry_run ) :
300
333
try :
301
334
for assignee in assignees :
302
335
u = gh .get_user (assignee )
0 commit comments