Skip to content

Commit e727123

Browse files
authored
PR dashboard: ignore merge-from-base commits made by non-authors (#18485)
1 parent 532aae4 commit e727123

1 file changed

Lines changed: 28 additions & 7 deletions

File tree

.github/scripts/pull-request-dashboard.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -429,12 +429,14 @@ def fetch_pr_context(
429429

430430
# Last substantive event = last event whose body is non-empty OR whose
431431
# kind is not "review:COMMENTED" (state changes always count). Merge
432-
# commits (≥2 parents — e.g. "Update branch" merging base into the PR)
433-
# don't count as substantive: they don't move the conversation forward.
432+
# commits (≥2 parents) by someone *other* than the author — e.g. an
433+
# approver clicking "Update branch" — don't count as substantive: they
434+
# don't move the conversation forward and shouldn't be confused with
435+
# the author addressing feedback.
434436
def is_substantive(e: dict[str, Any]) -> bool:
435437
if e["kind"].startswith("review:") and e["kind"] != "review:COMMENTED":
436438
return True
437-
if e.get("is_merge"):
439+
if e.get("is_merge") and (e.get("login") or "").lower() != author.lower():
438440
return False
439441
return bool((e.get("body") or "").strip())
440442

@@ -443,16 +445,34 @@ def is_substantive(e: dict[str, Any]) -> bool:
443445

444446
# Commit summaries (subject only) for the brief table in the rendered
445447
# context. Full commit messages and diffs travel via timeline events.
448+
# Merge commits authored by someone other than the PR author (e.g. an
449+
# approver clicking "Update branch") are flagged so the model doesn't
450+
# treat them as the author addressing feedback.
446451
commit_rows = []
447452
for c in recent_commits:
448-
sha = (c.get("sha") or "")[:7]
453+
sha_full = c.get("sha") or ""
454+
sha = sha_full[:7]
449455
msg = (c.get("commit") or {}).get("message", "").splitlines()[0] if c.get("commit") else ""
450456
a = c.get("author") or {}
451457
commit_login = a.get("login") or ((c.get("commit") or {}).get("author") or {}).get("name") or "?"
452458
commit_date = ((c.get("commit") or {}).get("author") or {}).get("date") or ""
453-
commit_rows.append({"sha": sha, "msg": msg, "author": commit_login, "date": commit_date})
459+
is_non_author_merge = (
460+
sha_full in merge_shas
461+
and (commit_login or "").lower() != author.lower()
462+
)
463+
commit_rows.append({
464+
"sha": sha,
465+
"msg": msg,
466+
"author": commit_login,
467+
"date": commit_date,
468+
"is_non_author_merge": is_non_author_merge,
469+
})
454470

455-
last_commit_date = parse_ts(commit_rows[-1]["date"]) if commit_rows else None
471+
# "Last commit pushed" is meant to surface real author activity, so
472+
# skip non-author merge commits (e.g. approvers clicking "Update
473+
# branch") when picking the timestamp.
474+
real_rows = [r for r in commit_rows if not r["is_non_author_merge"]]
475+
last_commit_date = parse_ts(real_rows[-1]["date"]) if real_rows else None
456476

457477
# Checks summary.
458478
failing = [c for c in checks if (c.get("state") or "").upper() in ("FAILURE", "ERROR")]
@@ -554,7 +574,8 @@ def render_context(ctx: dict[str, Any]) -> str:
554574
# Commits
555575
lines.append(f"Last {len(ctx['commits'])} commits (oldest first):")
556576
for c in ctx["commits"]:
557-
lines.append(f" {c['sha']} {c['date'][:10]} @{c['author']}: {truncate(c['msg'], 120)}")
577+
suffix = " [merge from base by non-author — not substantive activity]" if c.get("is_non_author_merge") else ""
578+
lines.append(f" {c['sha']} {c['date'][:10]} @{c['author']}: {truncate(c['msg'], 120)}{suffix}")
558579
lines.append("")
559580

560581
# Last substantive event highlight

0 commit comments

Comments
 (0)