Skip to content

Commit 47d1197

Browse files
committed
Allow sorting commitfest entries by "failing since" (#47)
This adds a new column to the `CfbotBranch` model: `failing_since`. This tracks when a patch first started to fail the CI or started requiring a rebase. This value its primary use is to allow people to sort by the "CI status" column in the patch list. This allows people to quickly see what patches are healthy, which require the author to take action, and which might benefit from a reviewer pinging the author that the patch has been broken for a while. Non-failing builds are sorted on their CI build creation time, so patches that are currently running CI are shown at the top, followed by patches for which CI succeeded most recently. The values of needs_rebase_since and failing_since are also shown on hover and on the patch pages. Fixes #42
1 parent 04239d7 commit 47d1197

File tree

5 files changed

+53
-8
lines changed

5 files changed

+53
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Generated by Django 4.2.19 on 2025-03-01 13:53
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("commitfest", "0009_extra_branch_fields"),
9+
]
10+
11+
operations = [
12+
migrations.AddField(
13+
model_name="cfbotbranch",
14+
name="failing_since",
15+
field=models.DateTimeField(blank=True, null=True),
16+
),
17+
]

pgcommitfest/commitfest/models.py

+1
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ class CfbotBranch(models.Model):
469469
# Actually a postgres enum column
470470
status = models.TextField(choices=STATUS_CHOICES, null=False)
471471
needs_rebase_since = models.DateTimeField(null=True, blank=True)
472+
failing_since = models.DateTimeField(null=True, blank=True)
472473
created = models.DateTimeField(auto_now_add=True)
473474
modified = models.DateTimeField(auto_now=True)
474475
version = models.TextField(null=True, blank=True)

pgcommitfest/commitfest/templates/commitfest.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ <h3>{{p.is_open|yesno:"Active patches,Closed patches"}}</h3>
6464
<th><a href="#" style="color:#333333;" onclick="return sortpatches(4);">ID</a>{%if sortkey == 4%}<div style="float:right;"><i class="glyphicon glyphicon-arrow-down"></i></div>{%elif sortkey == -4%}<div style="float:right;"><i class="glyphicon glyphicon-arrow-up"></i></div>{%endif%}</th>
6565
<th>Status</th>
6666
<th>Ver</th>
67-
<th>CI status</th>
67+
<th><a href="#" style="color:#333333;" onclick="return sortpatches(7);">CI status</a>{%if sortkey == 7%}<div style="float:right;"><i class="glyphicon glyphicon-arrow-down"></i></div>{%elif sortkey == -7%}<div style="float:right;"><i class="glyphicon glyphicon-arrow-up"></i></div>{%endif%}</th>
6868
<th><a href="#" style="color:#333333;" onclick="return sortpatches(6);">Stats</a>{%if sortkey == 6%}<div style="float:right;"><i class="glyphicon glyphicon-arrow-down"></i></div>{%elif sortkey == -6%}<div style="float:right;"><i class="glyphicon glyphicon-arrow-up"></i></div>{%endif%}</th>
6969
<th>Author</th>
7070
<th>Reviewers</th>
@@ -94,14 +94,14 @@ <h3>{{p.is_open|yesno:"Active patches,Closed patches"}}</h3>
9494
{%with p.cfbot_results as cfb%}
9595
{%if not cfb %}
9696
<span class="label label-default">Not processed</span>
97-
{%elif cfb.needs_rebase %}
98-
<a href="{{cfb.apply_url}}" title="View git apply logs">
97+
{%elif p.needs_rebase_since %}
98+
<a href="{{cfb.apply_url}}" title="View git apply logs. Needs rebase since {{p.needs_rebase_since|timesince}}. {%if p.failing_since and p.failing_since != p.needs_rebase_since %}Failing since {{p.failing_since|timesince}}.{%endif%}">
9999
<span class="label label-warning">Needs rebase!</span>
100100
</a>
101101
{%else%}
102102
<a href="https://github.com/postgresql-cfbot/postgresql/compare/cf/{{p.id}}~1...cf/{{p.id}}" title="View last patch set on GitHub"><img class="github-logo" src="/media/commitfest/github-mark.svg"/></a>
103103
<a href="https://cirrus-ci.com/github/postgresql-cfbot/postgresql/cf%2F{{p.id}}"
104-
title="View CI history{%if cfb.failed_task_names %}. Failed jobs: {{cfb.failed_task_names}}{%endif%}">
104+
title="View CI history. {%if p.failing_since%}Failing since {{p.failing_since|timesince}}. {%endif%}{%if cfb.failed_task_names %}Failed jobs: {{cfb.failed_task_names}}{%endif%}">
105105
{%if cfb.failed > 0 or cfb.branch_status == 'failed' or cfb.branch_status == 'timeout' %}
106106
<img src="/media/commitfest/new_failure.svg"/>
107107
{%elif cfb.completed < cfb.total %}

pgcommitfest/commitfest/templates/patch.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
<td>
1818
{%if not cfbot_branch %}
1919
<span class="label label-default">Not processed</span></a>
20-
{%elif not cfbot_branch.commit_id %}
20+
{%elif cfbot_branch.needs_rebase_since %}
2121
<a href="{{cfbot_branch.apply_url}}">
2222
<span class="label label-warning" title="View git apply logs">Needs rebase!</span></a>
23-
Additional links previous successfully applied patch (outdated):
23+
Needs rebase since {{cfbot_branch.needs_rebase_since|timesince}}. {%if cfbot_branch.failing_since and cfbot_branch.failing_since != cfbot_branch.needs_rebase_since %}Failing since {{cfbot_branch.failing_since|timesince}}. {%endif%}<br>Additional links previous successfully applied patch (outdated):<br>
2424
<a href="https://github.com/postgresql-cfbot/postgresql/compare/cf/{{patch.id}}~1...cf/{{patch.id}}" title="View previous successfully applied patch set on GitHub"><img class="github-logo" src="/media/commitfest/github-mark.svg"/></a>
2525
<a href="https://cirrus-ci.com/github/postgresql-cfbot/postgresql/cf%2F{{patch.id}}">
2626
<span class="label label-default">Summary</span></a>

pgcommitfest/commitfest/views.py

+29-2
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@ def commitfest(request, cfid):
265265
)
266266
elif sortkey == -6:
267267
orderby_str = "branch.all_additions + branch.all_deletions DESC NULLS LAST, created DESC"
268+
elif sortkey == 7:
269+
orderby_str = "branch.failing_since DESC NULLS FIRST, branch.created DESC"
270+
elif sortkey == -7:
271+
orderby_str = "branch.failing_since NULLS LAST, branch.created"
268272
else:
269273
orderby_str = "p.id"
270274
sortkey = 0
@@ -294,6 +298,8 @@ def commitfest(request, cfid):
294298
(SELECT string_agg(first_name || ' ' || last_name || ' (' || username || ')', ', ') FROM auth_user INNER JOIN commitfest_patch_authors cpa ON cpa.user_id=auth_user.id WHERE cpa.patch_id=p.id) AS author_names,
295299
(SELECT string_agg(first_name || ' ' || last_name || ' (' || username || ')', ', ') FROM auth_user INNER JOIN commitfest_patch_reviewers cpr ON cpr.user_id=auth_user.id WHERE cpr.patch_id=p.id) AS reviewer_names,
296300
(SELECT count(1) FROM commitfest_patchoncommitfest pcf WHERE pcf.patch_id=p.id) AS num_cfs,
301+
branch.needs_rebase_since,
302+
branch.failing_since,
297303
(
298304
SELECT row_to_json(t) as cfbot_results
299305
from (
@@ -303,7 +309,6 @@ def commitfest(request, cfid):
303309
count(*) FILTER (WHERE task.status in ('ABORTED', 'ERRORED', 'FAILED')) failed,
304310
count(*) total,
305311
string_agg(task.task_name, ', ') FILTER (WHERE task.status in ('ABORTED', 'ERRORED', 'FAILED')) as failed_task_names,
306-
branch.commit_id IS NULL as needs_rebase,
307312
branch.status as branch_status,
308313
branch.apply_url,
309314
branch.patch_count,
@@ -1250,13 +1255,14 @@ def cfbot_ingest(message):
12501255
# CONFLICT does not allow us to return that). We need to know the previous
12511256
# state so we can skip sending notifications if the needs_rebase status did
12521257
# not change.
1258+
needs_save = False
12531259
needs_rebase = branch_status["commit_id"] is None
12541260
if bool(branch_in_db.needs_rebase_since) is not needs_rebase:
12551261
if needs_rebase:
12561262
branch_in_db.needs_rebase_since = datetime.now()
12571263
else:
12581264
branch_in_db.needs_rebase_since = None
1259-
branch_in_db.save()
1265+
needs_save = True
12601266

12611267
if needs_rebase:
12621268
PatchHistory(
@@ -1270,6 +1276,27 @@ def cfbot_ingest(message):
12701276
what="Patch does not need rebase anymore",
12711277
).save_and_notify(authors_only=True)
12721278

1279+
# Similarly, we change the failing_since field using a separate UPDATE
1280+
failing = branch_status["status"] in ("failed", "timeout") or needs_rebase
1281+
finished = branch_status["status"] == "finished"
1282+
1283+
if "task_status" in message and message["task_status"]["status"] in (
1284+
"ABORTED",
1285+
"ERRORED",
1286+
"FAILED",
1287+
):
1288+
failing = True
1289+
1290+
if (failing or finished) and bool(branch_in_db.failing_since) is not failing:
1291+
if failing:
1292+
branch_in_db.failing_since = datetime.now()
1293+
else:
1294+
branch_in_db.failing_since = None
1295+
needs_save = True
1296+
1297+
if needs_save:
1298+
branch_in_db.save()
1299+
12731300

12741301
@csrf_exempt
12751302
def cfbot_notify(request):

0 commit comments

Comments
 (0)