From 892fce4ddfec19396cdfbb9cc8e4e750dbd954a5 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 27 Jan 2025 15:53:45 +0100 Subject: [PATCH] [ADD] forwardport: email reminders After 6 months of sitting unmerged, forward ports will now trigger a monthly email. Or would, if an email server was configured on the mergebot, but adding this now should allow debugging its working and tracking the generation of emails through the "Delivery Failed" collection. This way if we ever decide to actually do the thing we can just enable an SMTP server. Fixes #801 --- forwardport/models/project.py | 38 +++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/forwardport/models/project.py b/forwardport/models/project.py index 94f42426..185199a3 100644 --- a/forwardport/models/project.py +++ b/forwardport/models/project.py @@ -14,6 +14,7 @@ it up), ... from __future__ import annotations import builtins +import collections import datetime import itertools import json @@ -24,6 +25,7 @@ import typing import dateutil.relativedelta import requests +from markupsafe import Markup from odoo import models, fields, api from odoo.exceptions import UserError @@ -522,7 +524,8 @@ stderr: return msg def _reminder(self): - for _, prs in groupby(self.search([ + emails = collections.defaultdict(self.browse) + for source, prs in groupby(self.search([ ('source_id', '!=', False), ('blocked', '!=', False), ('state', 'in', ['opened', 'validated', 'approved', 'ready', 'error']), @@ -532,11 +535,18 @@ stderr: # will most likely lead to their parent being validated (?) for pr in set(prs).difference(p.parent_id for p in prs): # reminder every 7 days for the first 4 weeks, then every 4 weeks - if (pr.reminder_next - pr.create_date) < datetime.timedelta(days=28): + age = pr.reminder_next - pr.create_date + if age < datetime.timedelta(days=28): pr.reminder_next += datetime.timedelta(days=7) else: pr.reminder_next += datetime.timedelta(days=28) + # after 6 months, start sending emails + if age > datetime.timedelta(weeks=26): + if author := source.author.email: + emails[author] |= prs + if reviewer := source.reviewed_by.email: + emails[reviewer] |= prs self.env.ref('runbot_merge.forwardport.reminder')._send( repository=pr.repository, pull_request=pr.number, @@ -544,6 +554,30 @@ stderr: format_args={'pr': pr, 'source': pr.source_id}, ) + try: + self.env['mail.mail'].sudo().create([ + { + 'email_to': email, + 'subject': f"You have {len(prs)} outstanding forward ports", + 'body': Markup( + "

The following forward-ports are more than 6 months old " + "and were either created or approved by you.

" + "

Please process them appropriately (merge or close them)" + "at the earliest.

" + "" + ).format(Markup("").join( + Markup('
  • {name}
  • ').format( + name=pr.display_name, + link=pr.github_url, + ) + for pr in prs + )) + } + for email, prs in emails.items() + ]) + except Exception: + _logger.exception("Failed to create mail") + map_author = operator.itemgetter('name', 'email', 'date') map_committer = operator.itemgetter('name', 'email')