Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve auto exclusions based on teams #675

Merged
merged 1 commit into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions release-controller/release_notes.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,12 @@ class Team:
r"rs\/nns.+",
r".+test.+",
r"^bazel$",
r".*boundary.*",
r".*rosetta.*",
]

NON_REPLICA_TEAMS = sorted(list(set(TEAM_PRETTY_MAP.keys()) - REPLICA_TEAMS))

# Completely remove these teams from mentioning in the release notes
DROP_TEAMS = {"Utopia", "Financial Integrations", "IDX", "T&V", "Prodsec", "Support", "SupportEU", "SupportNA"}

# Ownership threshold for analyzing which teams were
# involved in the commit
MAX_OWNERSHIP_AREA = 0.5
Expand Down Expand Up @@ -231,8 +230,8 @@ def parse_conventional_commit(message, pattern):
return {"type": "other", "scope": None, "message": message}


def best_matching_regex(file_path, regex_list):
matches = [(regex, fnmatch.fnmatch(file_path, regex)) for regex in regex_list]
def matched_patterns(file_path, patterns):
matches = [(p, fnmatch.fnmatch(file_path, p)) for p in patterns]
matches = [match for match in matches if match[1]]
if len(matches) == 0:
return None
Expand Down Expand Up @@ -321,40 +320,41 @@ def get_change_description_for_commit(
if any([fnmatch.fnmatch(change["file_path"], pattern) for pattern in ci_patterns]):
continue

key = best_matching_regex(change["file_path"], codeowners.keys())
teams = ["unknown"] if key is None else codeowners[key]
teams = set(sum([codeowners[p] for p in codeowners.keys() if fnmatch.fnmatch(change["file_path"], p)], []))
if not teams:
teams = ["unknown"]

for team in teams:
if team not in ownership:
ownership[team] = change["num_changes"]
continue
ownership[team] += change["num_changes"]

# Non reviewed files
if "ghost" in ownership:
ownership.pop("ghost")
if "owners-owners" in ownership:
ownership.pop("owners-owners")
if "ic-owners-owners" in ownership:
ownership.pop("ic-owners-owners")

# TODO: count max first by replica team then others
teams = set()
if ownership:
max_ownership = max(ownership.items(), key=lambda changed_lines_per_team: changed_lines_per_team[1])[1]
# Since multiple teams can own a path in CODEOWNERS we have to handle what happens if two teams have max changes
for key, value in ownership.items():
if value >= max_ownership * MAX_OWNERSHIP_AREA:
replica_ownership = {team: lines for team, lines in ownership.items() if team in REPLICA_TEAMS}
max_ownership_replica = max([lines for team, lines in ownership.items() if team in REPLICA_TEAMS] or [0])
for key, value in replica_ownership.items():
if value >= max_ownership_replica * MAX_OWNERSHIP_AREA:
teams.add(key)

if "test" in conventional["message"]:
conventional["type"] = "test"
if not teams:
max_ownership = max(ownership.values() or [0])
for key, value in ownership.items():
if value >= max_ownership * MAX_OWNERSHIP_AREA:
teams.add(key)

commit_type = conventional["type"].lower()
commit_type = commit_type if commit_type in TYPE_PRETTY_MAP else "other"

teams = sorted(list(teams - DROP_TEAMS))

if not teams or all([team in NON_REPLICA_TEAMS for team in teams]):
if not REPLICA_TEAMS.intersection(teams):
included = False

teams = sorted(list(teams))

if commit_type not in change_infos:
change_infos[commit_type] = []

Expand Down
Loading
Loading