diff --git a/bugbot/bzcleaner.py b/bugbot/bzcleaner.py index d4f58efee..311eba288 100644 --- a/bugbot/bzcleaner.py +++ b/bugbot/bzcleaner.py @@ -214,6 +214,9 @@ def get_data(self): def get_summary(self, bug): return "..." if bug["groups"] else bug["summary"] + def get_cc_emails(self, data): + return [] + def has_default_products(self): return True @@ -764,6 +767,8 @@ def send_email(self, date="today"): if data: title, body = self.get_email(date, data) receivers = utils.get_receivers(self.name()) + cc_list = self.get_cc_emails(data) + status = "Success" try: mail.send( @@ -771,6 +776,7 @@ def send_email(self, date="today"): receivers, title, body, + Cc=cc_list, html=True, login=login_info, dryrun=self.dryrun, diff --git a/bugbot/rules/triage_owner_rotations.py b/bugbot/rules/triage_owner_rotations.py index cfd924108..d215d406f 100644 --- a/bugbot/rules/triage_owner_rotations.py +++ b/bugbot/rules/triage_owner_rotations.py @@ -18,6 +18,7 @@ from bugbot import logger from bugbot.bzcleaner import BzCleaner from bugbot.component_triagers import ComponentName, ComponentTriagers, TriageOwner +from bugbot.utils import get_bug_bugdash_url class TriageOwnerRotations(BzCleaner): @@ -95,10 +96,20 @@ def get_email_data(self, date: str) -> List[dict]: ), "new_triage_owner": new_triager.bugzilla_email, "has_put_error": new_triager.component in failures, + "link_to_triage": get_bug_bugdash_url( + new_triager.component, tab_name="triage" + ), } for new_triager in new_triagers ] + def get_cc_emails(self, data: List[dict]) -> List[str]: + cc_emails = set() + for entry in data: + cc_emails.add(entry.get("old_triage_owner", "")) + cc_emails.add(entry.get("new_triage_owner", "")) + return list(cc_emails) + if __name__ == "__main__": TriageOwnerRotations().run() diff --git a/bugbot/utils.py b/bugbot/utils.py index d2e882756..eaab108f2 100644 --- a/bugbot/utils.py +++ b/bugbot/utils.py @@ -9,7 +9,7 @@ import random import re from typing import Iterable, Union -from urllib.parse import urlencode +from urllib.parse import quote_plus, urlencode import dateutil.parser import humanize @@ -765,3 +765,20 @@ def is_keywords_removed_by_bugbot(bug: dict, keywords: Iterable) -> bool: if change["field_name"] == "keywords" for keyword in keywords ) + + +def get_bug_bugdash_url(component, tab_name: str) -> str: + """ + Generate bugdash URL for a component. + + Args: + component: The name of the targeted component. + tab_name: The name of the tab that should be active. + + Returns: + A URL pointing to Bugdash based on the provided component and tab. + """ + # Bugdash uses a single colon instead of a double colon to prefix the product name. + encoded_component = quote_plus(f"{component.product}:{component.name}") + + return f"https://bugdash.moz.tools/?component={encoded_component}#tab.{tab_name}" diff --git a/templates/triage_owner_rotations.html b/templates/triage_owner_rotations.html index cb4ec57f8..687e2ceeb 100644 --- a/templates/triage_owner_rotations.html +++ b/templates/triage_owner_rotations.html @@ -16,7 +16,9 @@ {% for i, row in enumerate(data) -%} - {{ row['component'] }} + + {{ row['component'] }} + {{ row['old_triage_owner'] }} {{ row['new_triage_owner'] }}