From 297f6ae0cb845fc32705970b7977678fd0ce53d1 Mon Sep 17 00:00:00 2001 From: Maxwell Elliott Date: Fri, 17 Jul 2026 12:29:07 -0400 Subject: [PATCH] fix: exclude bot accounts from README contributors GitHub Actions and other bots were appearing in the generated contributors table; skip accounts typed as Bot or named with the [bot] suffix. Co-authored-by: Cursor --- README.md | 13 ++++++------- tools/generate_readme.py | 22 +++++++++++++++++++--- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 3870e34..07ee59f 100644 --- a/README.md +++ b/README.md @@ -766,53 +766,52 @@ bazel run @bazel-diff//cli:bazel-diff -- bazel-diff -h Maxwell Elliott
Maxwell Elliott
Honnix
Honnix
- github-actions[bot]
github-actions[bot]
eric wang
eric wang
Eric Wang
Eric Wang
Tianyu Geng
Tianyu Geng
+ Patrick Balestra
Patrick Balestra
- Patrick Balestra
Patrick Balestra
Daniel P. Purkhus
Daniel P. Purkhus
Alex Eagle
Alex Eagle
Anton Malinskiy
Anton Malinskiy
rdark
rdark
Cory Paik
Cory Paik
+ Ted Kaplan
Ted Kaplan
- Ted Kaplan
Ted Kaplan
Sharmila
Sharmila
Dmitrii Kostyrev
Dmitrii Kostyrev
Jérémy Mathevet
Jérémy Mathevet
Nikhil Birmiwal
Nikhil Birmiwal
Sergei Morozov
Sergei Morozov
+ Fahrzin Hemmati
Fahrzin Hemmati
- Fahrzin Hemmati
Fahrzin Hemmati
Jaime Lennox
Jaime Lennox
jmwachtel
jmwachtel
Alex Trotta
Alex Trotta
Johan Mjönes
Johan Mjönes
Lucas Teixeira
Lucas Teixeira
+ Guillaume Van Wassenhove
Guillaume Van Wassenhove
- Guillaume Van Wassenhove
Guillaume Van Wassenhove
Fabian Meumertzheim
Fabian Meumertzheim
Jonathan Block
Jonathan Block
Alex Torok
Alex Torok
Naveen Narayanan
Naveen Narayanan
Mathieu Sabourin
Mathieu Sabourin
+ André
André
- André
André
Boris
Boris
Rui Chen
Rui Chen
Sanju Naik
Sanju Naik
Laurenz
Laurenz
mla
mla
+ tinder-yukisawa
tinder-yukisawa
- tinder-yukisawa
tinder-yukisawa
Kevin Jiao
Kevin Jiao
Vincent Case
Vincent Case
Walt Panfil
Walt Panfil
diff --git a/tools/generate_readme.py b/tools/generate_readme.py index 2a7077c..c8929a2 100644 --- a/tools/generate_readme.py +++ b/tools/generate_readme.py @@ -130,8 +130,11 @@ def fetch_github_email_map(repo: str) -> dict[str, dict]: gh_author = commit.get("author") email = (commit.get("commit") or {}).get("author", {}).get("email", "") if gh_author and email and email not in email_map: + login = gh_author["login"] + if is_bot_account(login=login, account_type=gh_author.get("type", "")): + continue email_map[email] = { - "login": gh_author["login"], + "login": login, "avatar_url": gh_author["avatar_url"], } @@ -152,6 +155,17 @@ def resolve_noreply_username(email: str) -> str | None: return local.split("+")[-1] +def is_bot_account(name: str = "", login: str = "", account_type: str = "") -> bool: + """Return True for GitHub Apps / Actions bots that should not appear as contributors.""" + if account_type == "Bot": + return True + # GitHub bot logins and commit author names conventionally end with "[bot]". + for value in (name, login): + if value.lower().endswith("[bot]"): + return True + return False + + # --------------------------------------------------------------------------- # Contributors section # --------------------------------------------------------------------------- @@ -173,7 +187,7 @@ def build_contributors_section(workspace_dir: Path, email_map: dict[str, dict]) continue name, email = line.split("\t", 1) name, email = name.strip(), email.strip() - if name: + if name and not is_bot_account(name=name): pair_counts[(name, email)] += 1 # Roll up by name: sum counts, pick the email with the highest count. @@ -200,7 +214,7 @@ def build_contributors_section(workspace_dir: Path, email_map: dict[str, dict]) # Fallback: try to extract username from noreply address. if not user: login = resolve_noreply_username(email) - if login: + if login and not is_bot_account(login=login): user = { "login": login, "avatar_url": f"https://avatars.githubusercontent.com/{login}", @@ -208,6 +222,8 @@ def build_contributors_section(workspace_dir: Path, email_map: dict[str, dict]) if user: login = user["login"] + if is_bot_account(name=name, login=login): + continue base_avatar = user["avatar_url"].split("?")[0] avatar = base_avatar + "?s=64" profile = f"https://github.com/{login}"