Skip to content

Commit b7da05b

Browse files
committed
Only notify on email if opted in and show warnings on page
1 parent 258701f commit b7da05b

File tree

6 files changed

+114
-8
lines changed

6 files changed

+114
-8
lines changed

pgcommitfest/commitfest/fixtures/commitfest_data.json

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,5 +1351,63 @@
13511351
"created": "2025-01-26T22:11:40.000",
13521352
"modified": "2025-01-26T22:12:00.000"
13531353
}
1354+
},
1355+
{
1356+
"model": "commitfest.patch",
1357+
"pk": 9,
1358+
"fields": {
1359+
"name": "Abandoned patch in closed commitfest",
1360+
"topic": 3,
1361+
"wikilink": "",
1362+
"gitlink": "",
1363+
"targetversion": null,
1364+
"committer": null,
1365+
"created": "2024-10-15T10:00:00",
1366+
"modified": "2024-10-15T10:00:00",
1367+
"lastmail": "2024-10-01T10:00:00",
1368+
"tags": [],
1369+
"authors": [],
1370+
"reviewers": [],
1371+
"subscribers": [],
1372+
"mailthread_set": [
1373+
9
1374+
]
1375+
}
1376+
},
1377+
{
1378+
"model": "commitfest.mailthread",
1379+
"pk": 9,
1380+
"fields": {
1381+
"messageid": "abandoned@message-09",
1382+
"subject": "Abandoned patch in closed commitfest",
1383+
"firstmessage": "2024-10-01T10:00:00",
1384+
"firstauthor": "test@test.com",
1385+
"latestmessage": "2024-10-01T10:00:00",
1386+
"latestauthor": "test@test.com",
1387+
"latestsubject": "Abandoned patch in closed commitfest",
1388+
"latestmsgid": "abandoned@message-09"
1389+
}
1390+
},
1391+
{
1392+
"model": "commitfest.patchoncommitfest",
1393+
"pk": 10,
1394+
"fields": {
1395+
"patch": 9,
1396+
"commitfest": 1,
1397+
"enterdate": "2024-10-15T10:00:00",
1398+
"leavedate": null,
1399+
"status": 1
1400+
}
1401+
},
1402+
{
1403+
"model": "commitfest.patchhistory",
1404+
"pk": 23,
1405+
"fields": {
1406+
"patch": 9,
1407+
"date": "2024-10-15T10:00:00",
1408+
"by": 1,
1409+
"by_cfbot": false,
1410+
"what": "Created patch record"
1411+
}
13541412
}
13551413
]

pgcommitfest/commitfest/models.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,11 +239,17 @@ def send_closure_notifications(self, moved_patch_ids=None):
239239
next_cf_url = "https://commitfest.postgresql.org/"
240240

241241
# Collect unique authors and their patches
242+
# Only include authors who have notify_all_author enabled
242243
authors_patches = {}
243244
for poc in open_pocs:
244245
for author in poc.patch.authors.all():
245246
if not author.email:
246247
continue
248+
try:
249+
if not author.userprofile.notify_all_author:
250+
continue
251+
except UserProfile.DoesNotExist:
252+
continue
247253
if author not in authors_patches:
248254
authors_patches[author] = []
249255
authors_patches[author].append(poc)
@@ -252,11 +258,8 @@ def send_closure_notifications(self, moved_patch_ids=None):
252258
for author, patches in authors_patches.items():
253259
# Get user's notification email preference
254260
email = author.email
255-
try:
256-
if author.userprofile and author.userprofile.notifyemail:
257-
email = author.userprofile.notifyemail.email
258-
except UserProfile.DoesNotExist:
259-
pass
261+
if author.userprofile.notifyemail:
262+
email = author.userprofile.notifyemail.email
260263

261264
send_template_mail(
262265
settings.NOTIFICATION_FROM,

pgcommitfest/commitfest/templates/commitfest.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
{%load commitfest %}
33
{%block contents%}
44

5+
{%if cf.is_closed%}
6+
<div class="alert alert-warning" role="alert">
7+
<strong>This commitfest is closed.</strong> Open patches in this commitfest are no longer being picked up by CI. If you want CI to run on your patch, move it to an open commitfest.
8+
</div>
9+
{%endif%}
10+
511
<button type="button" class="btn btn-secondary active" id="filterButton" onClick="togglePatchFilterButton('filterButton', 'collapseFilters')">Search/filter</button>
612
<a class="btn btn-secondary{% if request.GET.reviewer == '-2' %} active{% endif %}" href="?reviewer=-2">No reviewers</a>
713
<a class="btn btn-secondary{% if request.GET.author == '-3' %} active{% endif %}" href="?author=-3">My patches</a>

pgcommitfest/commitfest/templates/help.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ <h2>Commitfest</h2>
1515
</p>
1616
<p>There are 5 Commitfests per year. The first one is "In Progress" in <em>July</em> and starts the nine months feature development cycle of PostgreSQL. The next three are "In Progress" in <em>September</em>, <em>November</em> and <em>January</em>. The last Commitfest of the feature development cycle is "In Progress" in <em>March</em>, and ends a when the feature freeze starts. The exact date of the feature freeze depends on the year, but it's usually in early April.</p>
1717

18+
<h3>Commitfest closure</h3>
19+
<p>
20+
When a Commitfest closes, patches that have been active recently are automatically moved to the next Commitfest. A patch is considered "active" if it has had email activity in the past 30 days and has not been failing CI for more than 21 days. Patches that are not automatically moved will stay in the closed Commitfest, where they will no longer be picked up by CI. Authors of such patches that have enabled "Notify on all where author" in their profile settings will receive an email notification asking them to either move the patch to the next Commitfest or close it with an appropriate status.
21+
</p>
22+
1823
<h2>Patches</h2>
1924
<p>
2025
A "patch" is a bit of an overloaded term in the PostgreSQL community. Email threads on the mailing list often contain "patch files" as attachments, such a file is often referred to as a "patch". A single email can even contain multiple related "patch files", which are called a "patchset". However, in the context of a Commitfest app a "patch" usually means a "patch entry" in the Commitfest app. Such a "patch entry" is a reference to a mailinglist thread on which change to PostgreSQL has been proposed, by someone sending an email that contain one or more "patch files". The Commitfest app will automatically detect new versions of the patch files and update the "patch entry" accordingly.

pgcommitfest/commitfest/templates/patch.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
{%extends "base.html"%}
22
{%load commitfest%}
33
{%block contents%}
4+
{%with current_poc=patch_commitfests.0%}
5+
{%if cf.is_closed and not current_poc.is_closed%}
6+
<div class="alert alert-warning" role="alert">
7+
<strong>This patch is part of a closed commitfest.</strong> It is no longer being picked up by CI. If you want CI to run on this patch, move it to an open commitfest.
8+
</div>
9+
{%endif%}
10+
{%endwith%}
411
{%include "patch_commands.inc"%}
512
<table class="table table-bordered">
613
<tbody>

pgcommitfest/commitfest/tests/test_closure_notifications.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
Topic,
1717
)
1818
from pgcommitfest.mailqueue.models import QueuedMail
19+
from pgcommitfest.userprofile.models import UserProfile
1920

2021
pytestmark = pytest.mark.django_db
2122

@@ -129,7 +130,10 @@ def test_one_email_per_author_with_multiple_patches(alice, in_progress_cf, topic
129130

130131

131132
def test_multiple_authors_receive_separate_emails(alice, bob, in_progress_cf, topic):
132-
"""Each author of open patches should receive their own notification."""
133+
"""Each author of open patches should receive their own notification (if opted in)."""
134+
# Bob also needs notify_all_author enabled to receive closure emails
135+
UserProfile.objects.create(user=bob, notify_all_author=True)
136+
133137
patch1 = Patch.objects.create(name="Alice Patch", topic=topic)
134138
patch1.authors.add(alice)
135139
PatchOnCommitFest.objects.create(
@@ -176,7 +180,10 @@ def test_notification_includes_next_commitfest_info(
176180

177181

178182
def test_coauthors_both_receive_notification(alice, bob, in_progress_cf, topic):
179-
"""Both co-authors of a patch should receive notifications."""
183+
"""Both co-authors of a patch should receive notifications (if opted in)."""
184+
# Bob also needs notify_all_author enabled to receive closure emails
185+
UserProfile.objects.create(user=bob, notify_all_author=True)
186+
180187
patch = Patch.objects.create(name="Coauthored Patch", topic=topic)
181188
patch.authors.add(alice)
182189
patch.authors.add(bob)
@@ -195,7 +202,8 @@ def test_coauthors_both_receive_notification(alice, bob, in_progress_cf, topic):
195202

196203

197204
def test_no_notification_for_author_without_email(bob, in_progress_cf, topic):
198-
"""Authors without email addresses should be skipped."""
205+
"""Authors without email addresses should be skipped even if opted in."""
206+
UserProfile.objects.create(user=bob, notify_all_author=True)
199207
bob.email = ""
200208
bob.save()
201209

@@ -213,6 +221,25 @@ def test_no_notification_for_author_without_email(bob, in_progress_cf, topic):
213221
assert QueuedMail.objects.count() == 0
214222

215223

224+
def test_no_notification_for_author_without_notify_all_author(
225+
bob, in_progress_cf, topic
226+
):
227+
"""Authors without notify_all_author enabled should not receive closure notifications."""
228+
# bob has no UserProfile, so notify_all_author is not enabled
229+
patch = Patch.objects.create(name="Test Patch", topic=topic)
230+
patch.authors.add(bob)
231+
PatchOnCommitFest.objects.create(
232+
patch=patch,
233+
commitfest=in_progress_cf,
234+
enterdate=datetime.now(),
235+
status=PatchOnCommitFest.STATUS_REVIEW,
236+
)
237+
238+
in_progress_cf.send_closure_notifications()
239+
240+
assert QueuedMail.objects.count() == 0
241+
242+
216243
# Auto-move tests
217244

218245

0 commit comments

Comments
 (0)