Skip to content
Open
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
14 changes: 14 additions & 0 deletions oar/cli/cmd_drop_bugs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from oar.core.notification import NotificationManager
from oar.core.operators import BugOperator
from oar.core.worksheet import WorksheetManager
from oar.core.shipment import GitLabServer

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -40,6 +41,19 @@ def drop_bugs(ctx):
logger.info("updating test report")
report.update_bug_list(operator.get_jira_issues(), dropped_bugs)
nm.share_dropped_bugs(dropped_bugs)
# Get drop-bugs MR to notify ART team
try:
gl = GitLabServer(cs.get_gitlab_url(), cs.get_gitlab_token())
mr_title = f"{cs.release} drop bugs"
# Try to scope to shipment project when available
project_name = operator._sd.get_mr().project_name if hasattr(operator, '_sd') and operator._sd.get_mr() else None
mr = gl.get_mr_by_title(mr_title, project_name)
if mr:
nm.share_drop_bugs_mr_for_approval(mr.get_web_url())
else:
logger.warning("drop-bugs MR url not found by title; skipping ART notification")
except Exception as e:
logger.warning("Failed to locate MR url for drop-bugs; skipping ART notification: %s", e)
if len(approved_doc_ads):
for ad in approved_doc_ads:
ad.refresh()
Expand Down
42 changes: 25 additions & 17 deletions oar/core/notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,6 @@ def share_new_report(self, report: TestReport):
NotificationException: error when share this info
"""
try:
# Send email
# mail_subject = self.cs.release + " z-stream errata test status"
# mail_content = self.mh.get_mail_content_for_new_report(report)
# self.mc.send_email(
# self.cs.get_email_contact("qe"), mail_subject, mail_content
# )
# Send slack message
slack_msg = self.mh.get_slack_message_for_new_report(report)
self.sc.post_message(
self.cs.get_slack_channel_from_contact("qe-release"), slack_msg
Expand All @@ -76,7 +69,6 @@ def share_ownership_change_result(
"""

try:
# Send slack message only
slack_msg = self.mh.get_slack_message_for_ownership_change(
updated_ads, abnormal_ads, updated_subtasks, new_owner
)
Expand Down Expand Up @@ -153,7 +145,7 @@ def share_new_cve_tracker_bugs(self, cve_tracker_bugs):
cve_tracker_bugs)
if len(slack_msg):
self.sc.post_message(
self.cs.get_slack_channel_from_contact("art"), slack_msg
self._get_channel("art"), slack_msg
)
except Exception as e:
raise NotificationException(
Expand Down Expand Up @@ -195,13 +187,12 @@ def share_dropped_bugs(self, dropped_bugs):
slack_msg = self.mh.get_slack_message_for_dropped_bugs(dropped_bugs)
if len(slack_msg):
self.sc.post_message(
self.cs.get_slack_channel_from_contact(
self._get_channel(
"qe-release"), slack_msg
)
except Exception as e:
raise NotificationException(
"share dropped bugs failed"
) from e
"share dropped bugs failed") from e


def share_dropped_and_high_severity_bugs(self, dropped_bugs, high_severity_bugs):
Expand All @@ -221,13 +212,12 @@ def share_dropped_and_high_severity_bugs(self, dropped_bugs, high_severity_bugs)
)
if len(slack_msg):
self.sc.post_message(
self.cs.get_slack_channel_from_contact(
self._get_channel(
"qe-release"), slack_msg
)
except Exception as e:
raise NotificationException(
"share dropped and high severity bugs failed"
) from e
"share dropped and high severity bugs failed") from e

def share_doc_prodsec_approval_result(self, doc_appr, prodsec_appr):
"""
Expand All @@ -239,7 +229,7 @@ def share_doc_prodsec_approval_result(self, doc_appr, prodsec_appr):
)
if len(slack_msg):
self.sc.post_message(
self.cs.get_slack_channel_from_contact(
self._get_channel(
"approver"), slack_msg
)
except Exception as e:
Expand Down Expand Up @@ -325,6 +315,24 @@ def share_shipment_mr_and_ad_info(self, mr, updated_ads, abnormal_ads, updated_s
except Exception as e:
raise NotificationException("share shipment MR and AD info failed") from e

def share_drop_bugs_mr_for_approval(self, mr_url: str):
"""
Notify ART forum channel to approve the drop-bugs merge request

Args:
mr_url (str): URL of the drop-bugs merge request

Raises:
NotificationException: error when posting message
"""
try:
slack_msg = f"ART team, please review and approve the drop-bugs MR: {mr_url}"
# Use forum channel mapping from config
channel = self.cs.get_slack_channel_from_contact("qe-forum")
self.sc.post_message(channel, slack_msg)
except Exception as e:
raise NotificationException("share drop-bugs MR for approval failed") from e

def share_unverified_cve_issues_to_managers(self, unverified_cve_issues):
"""
Share unverified CVE issues to managers of QA contacts
Expand All @@ -340,7 +348,7 @@ def share_unverified_cve_issues_to_managers(self, unverified_cve_issues):
unverified_cve_issues)
if len(slack_msg):
self.sc.post_message(
self.cs.get_slack_channel_from_contact(
self._get_channel(
"qe-forum"), slack_msg
)
except Exception as e:
Expand Down
11 changes: 6 additions & 5 deletions oar/core/shipment.py
Original file line number Diff line number Diff line change
Expand Up @@ -980,17 +980,18 @@ def drop_bugs(self) -> list[str]:
# need to check if MR with above title exists or not
gl = GitLabServer(self._cs.get_gitlab_url(), self._cs.get_gitlab_token())
gh = GitHelper()
mr = gl.get_mr_by_title(mr_title, self._mr.project_name)
# Look up an existing drop-bugs MR by title in the same project as the shipment MR
drop_bugs_mr = gl.get_mr_by_title(mr_title, self._mr.project_name)

# if mr already exists, don't need to create new mr
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
repo_dir = ""
branch = f"drop-bugs-for-{self._cs.release}-{timestamp}"
if mr:
if drop_bugs_mr:
# get source project info from existing mr metadata
# check out the branch from source project
source_project = mr.gl.projects.get(mr.mr.source_project_id)
repo_dir = gh.checkout_repo(source_project.http_url_to_repo, mr.get_source_branch())
source_project = drop_bugs_mr.gl.projects.get(drop_bugs_mr.mr.source_project_id)
repo_dir = gh.checkout_repo(source_project.http_url_to_repo, drop_bugs_mr.get_source_branch())
# configure credential for remote origin, just need to update this branch
gh.configure_remotes("origin", f"https://group_143087_bot_e4ed5153eb7e7dfa7eb3d7901a95a6a7:{self._cs.get_gitlab_token()}@gitlab.cee.redhat.com/rioliu/ocp-shipment-data.git")
else:
Expand Down Expand Up @@ -1042,7 +1043,7 @@ def drop_bugs(self) -> list[str]:
return []


if mr:
if drop_bugs_mr:
gh.push_changes()
else:
# push the local change to forked repo
Expand Down
26 changes: 25 additions & 1 deletion tests/test_notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

class TestNotificationManager(unittest.TestCase):
def setUp(self):
self.cs = ConfigStore("4.13.6")
self.cs = ConfigStore("4.19.14")
self.nm = NotificationManager(self.cs)

@unittest.skip
Expand Down Expand Up @@ -174,3 +174,27 @@ def test_share_unverified_cve_issues_to_managers_error(self):
self.nm.share_unverified_cve_issues_to_managers([test_issue])

self.nm.sc.post_message.assert_called_once()

def test_share_drop_bugs_mr_for_approval_success(self):
"""Ensure MR approval request is posted to forum channel with URL"""
mr_url = "https://gitlab.example.com/mygroup/ocp-shipment-data/-/merge_requests/136"
# Mock channel mapping and Slack posting
self.nm.cs.get_slack_channel_from_contact = unittest.mock.Mock(return_value="#forum-ocp-release")
self.nm.sc.post_message = unittest.mock.Mock()

self.nm.share_drop_bugs_mr_for_approval(mr_url)

# Validate channel and message contents
self.nm.sc.post_message.assert_called_once()
args, kwargs = self.nm.sc.post_message.call_args
self.assertEqual(args[0], "#forum-ocp-release")
self.assertIn(mr_url, args[1])

def test_share_drop_bugs_mr_for_approval_error(self):
"""Ensure NotificationException is raised when Slack post fails"""
mr_url = "https://gitlab.example.com/mygroup/ocp-shipment-data/-/merge_requests/999"
self.nm.cs.get_slack_channel_from_contact = unittest.mock.Mock(return_value="#forum-ocp-release")
self.nm.sc.post_message = unittest.mock.Mock(side_effect=Exception("Slack failure"))

with self.assertRaises(NotificationException):
self.nm.share_drop_bugs_mr_for_approval(mr_url)