From f5a537c77bf2db6f81731a4523ec0a18376d43b4 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 27 Apr 2026 14:16:25 +0000
Subject: [PATCH 1/7] Add contributor avatars above username in leaderboard
tables
Agent-Logs-Url: https://github.com/NextCommunity/.github/sessions/204ccf11-afe1-4fcc-80b2-68d5ae9a73b1
Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com>
---
scripts/leaderboard.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/scripts/leaderboard.py b/scripts/leaderboard.py
index ef54f57..aa87550 100644
--- a/scripts/leaderboard.py
+++ b/scripts/leaderboard.py
@@ -767,8 +767,9 @@ def generate_markdown(contributors, levels_data):
commits_display += f" ยท ๐ค {coauthored}"
commits_display += f" ยท ๐ฆ {repos_count}"
+ avatar = f'
'
lines.append(
- f"| {rank} | [@{login}](https://github.com/{login})"
+ f"| {rank} | {avatar}[@{login}](https://github.com/{login})"
f" | {level} | {rarity_display} | {commits_display}"
f" | {prog} | {streak_display}"
f" | {badges} | {points_display} |"
@@ -812,8 +813,9 @@ def generate_markdown(contributors, levels_data):
breakdown_parts.append(f"๐ {other_c}")
breakdown = " ยท ".join(breakdown_parts) if breakdown_parts else "โ"
+ avatar = f'
'
lines.append(
- f"| {i} | [@{login}](https://github.com/{login})"
+ f"| {i} | {avatar}[@{login}](https://github.com/{login})"
f" | {first_date} | {last_date}"
f" | {days_active} | {cpd}"
f" | {breakdown} | Top {pctile}% |"
From 10ab2bf3ca6719acfd273ec54ed25baf4b4679af Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 27 Apr 2026 14:22:58 +0000
Subject: [PATCH 2/7] Use avatars.githubusercontent.com URL to avoid redirect
Agent-Logs-Url: https://github.com/NextCommunity/.github/sessions/7dd9fc60-ee05-4510-97b0-a8ff60efb3ae
Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com>
---
scripts/leaderboard.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/leaderboard.py b/scripts/leaderboard.py
index aa87550..d80282c 100644
--- a/scripts/leaderboard.py
+++ b/scripts/leaderboard.py
@@ -767,7 +767,7 @@ def generate_markdown(contributors, levels_data):
commits_display += f" ยท ๐ค {coauthored}"
commits_display += f" ยท ๐ฆ {repos_count}"
- avatar = f'
'
+ avatar = f'
'
lines.append(
f"| {rank} | {avatar}[@{login}](https://github.com/{login})"
f" | {level} | {rarity_display} | {commits_display}"
@@ -813,7 +813,7 @@ def generate_markdown(contributors, levels_data):
breakdown_parts.append(f"๐ {other_c}")
breakdown = " ยท ".join(breakdown_parts) if breakdown_parts else "โ"
- avatar = f'
'
+ avatar = f'
'
lines.append(
f"| {i} | {avatar}[@{login}](https://github.com/{login})"
f" | {first_date} | {last_date}"
From 88b407327f7c8a477b6926554e6bd80d442b28fa Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 27 Apr 2026 14:32:27 +0000
Subject: [PATCH 3/7] Replace mixed HTML/Markdown contributor cells with pure
HTML anchor tags
Agent-Logs-Url: https://github.com/NextCommunity/.github/sessions/e5a9c6c2-cf01-4bd4-acc7-5545e5855fdd
Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com>
---
scripts/leaderboard.py | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/scripts/leaderboard.py b/scripts/leaderboard.py
index d80282c..a95b540 100644
--- a/scripts/leaderboard.py
+++ b/scripts/leaderboard.py
@@ -767,9 +767,13 @@ def generate_markdown(contributors, levels_data):
commits_display += f" ยท ๐ค {coauthored}"
commits_display += f" ยท ๐ฆ {repos_count}"
- avatar = f'
'
+ contributor_cell = (
+ f''
+ f'
'
+ f"@{login}"
+ )
lines.append(
- f"| {rank} | {avatar}[@{login}](https://github.com/{login})"
+ f"| {rank} | {contributor_cell}"
f" | {level} | {rarity_display} | {commits_display}"
f" | {prog} | {streak_display}"
f" | {badges} | {points_display} |"
@@ -813,9 +817,13 @@ def generate_markdown(contributors, levels_data):
breakdown_parts.append(f"๐ {other_c}")
breakdown = " ยท ".join(breakdown_parts) if breakdown_parts else "โ"
- avatar = f'
'
+ contributor_cell = (
+ f''
+ f'
'
+ f"@{login}"
+ )
lines.append(
- f"| {i} | {avatar}[@{login}](https://github.com/{login})"
+ f"| {i} | {contributor_cell}"
f" | {first_date} | {last_date}"
f" | {days_active} | {cpd}"
f" | {breakdown} | Top {pctile}% |"
From 65248351d8eba4e7e36112f8e04eea9916f07354 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 27 Apr 2026 14:43:02 +0000
Subject: [PATCH 4/7] Add alt attribute, ?s=64 to avatar URLs, and extract
_contributor_cell helper
Agent-Logs-Url: https://github.com/NextCommunity/.github/sessions/466e64a0-98f9-4911-8d6f-64ee775320b7
Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com>
---
scripts/leaderboard.py | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/scripts/leaderboard.py b/scripts/leaderboard.py
index a95b540..6cb8b98 100644
--- a/scripts/leaderboard.py
+++ b/scripts/leaderboard.py
@@ -707,6 +707,16 @@ def build_leaderboard(token=None):
return sorted_contributors, had_errors, levels_data
+def _contributor_cell(login):
+ """Return a pure-HTML table cell with avatar and username link."""
+ return (
+ f''
+ f'
'
+ f"@{login}"
+ )
+
+
def generate_markdown(contributors, levels_data):
"""Generate a gamified markdown leaderboard from contributor data."""
rank_badges = {1: "๐ฅ", 2: "๐ฅ", 3: "๐ฅ"}
@@ -767,11 +777,7 @@ def generate_markdown(contributors, levels_data):
commits_display += f" ยท ๐ค {coauthored}"
commits_display += f" ยท ๐ฆ {repos_count}"
- contributor_cell = (
- f''
- f'
'
- f"@{login}"
- )
+ contributor_cell = _contributor_cell(login)
lines.append(
f"| {rank} | {contributor_cell}"
f" | {level} | {rarity_display} | {commits_display}"
@@ -817,11 +823,7 @@ def generate_markdown(contributors, levels_data):
breakdown_parts.append(f"๐ {other_c}")
breakdown = " ยท ".join(breakdown_parts) if breakdown_parts else "โ"
- contributor_cell = (
- f''
- f'
'
- f"@{login}"
- )
+ contributor_cell = _contributor_cell(login)
lines.append(
f"| {i} | {contributor_cell}"
f" | {first_date} | {last_date}"
From ca235122db71396ab1e2a6ba054ec352167cb086 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 27 Apr 2026 15:11:27 +0000
Subject: [PATCH 5/7] Validate, URL-encode, and HTML-escape login in
_contributor_cell()
Agent-Logs-Url: https://github.com/NextCommunity/.github/sessions/4027e7e9-1711-46a1-be39-aa77e1751a77
Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com>
---
scripts/leaderboard.py | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/scripts/leaderboard.py b/scripts/leaderboard.py
index 6cb8b98..54e67b6 100644
--- a/scripts/leaderboard.py
+++ b/scripts/leaderboard.py
@@ -1,9 +1,11 @@
"""Fetch contributor stats from all NextCommunity repos and update the leaderboard."""
+import html
import os
import re
import sys
import urllib.error
+import urllib.parse
import urllib.request
import json
from bisect import bisect_right
@@ -16,6 +18,9 @@
LEADERBOARD_START = ""
LEADERBOARD_END = ""
SITE_REPO_NAME = "NextCommunity.github.io"
+
+# GitHub usernames: alphanumeric and single hyphens, 1-39 characters.
+_GITHUB_LOGIN_RE = re.compile(r"^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$")
DOTGITHUB_REPO_NAME = ".github"
# Self-documenting record for each commit entry collected across all repos.
@@ -708,12 +713,20 @@ def build_leaderboard(token=None):
def _contributor_cell(login):
- """Return a pure-HTML table cell with avatar and username link."""
+ """Return a pure-HTML table cell with avatar and username link.
+
+ ``login`` is validated against GitHub's username pattern before use.
+ Raises ``ValueError`` if the login contains unexpected characters.
+ """
+ if not _GITHUB_LOGIN_RE.match(login):
+ raise ValueError(f"Invalid GitHub login: {login!r}")
+ safe_login = urllib.parse.quote(login, safe="")
+ escaped_login = html.escape(login)
return (
- f''
- f'
'
- f"@{login}"
+ f''
+ f'
'
+ f"@{escaped_login}"
)
From c945a26bdbae00d582818e2a0a203b71ee18fa70 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 27 Apr 2026 15:49:26 +0000
Subject: [PATCH 6/7] Tighten _GITHUB_LOGIN_RE to reject consecutive hyphens
Agent-Logs-Url: https://github.com/NextCommunity/.github/sessions/01d6fd0f-7d87-4442-97a6-a4884d35e36a
Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com>
---
scripts/leaderboard.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/leaderboard.py b/scripts/leaderboard.py
index 54e67b6..9b652cd 100644
--- a/scripts/leaderboard.py
+++ b/scripts/leaderboard.py
@@ -19,8 +19,8 @@
LEADERBOARD_END = ""
SITE_REPO_NAME = "NextCommunity.github.io"
-# GitHub usernames: alphanumeric and single hyphens, 1-39 characters.
-_GITHUB_LOGIN_RE = re.compile(r"^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$")
+# GitHub usernames: 1-39 alphanumeric chars, interior single hyphens only (no consecutive hyphens).
+_GITHUB_LOGIN_RE = re.compile(r"^(?=.{1,39}$)[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$")
DOTGITHUB_REPO_NAME = ".github"
# Self-documenting record for each commit entry collected across all repos.
From cf616180a7b9740a57edf91a1c9b6f43666739ac Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 27 Apr 2026 16:11:57 +0000
Subject: [PATCH 7/7] Handle invalid logins gracefully in _contributor_cell()
Agent-Logs-Url: https://github.com/NextCommunity/.github/sessions/54ce91a8-a4b5-4ab0-811e-00db602a7025
Co-authored-by: jbampton <418747+jbampton@users.noreply.github.com>
---
scripts/leaderboard.py | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/scripts/leaderboard.py b/scripts/leaderboard.py
index 9b652cd..eddcde4 100644
--- a/scripts/leaderboard.py
+++ b/scripts/leaderboard.py
@@ -716,10 +716,12 @@ def _contributor_cell(login):
"""Return a pure-HTML table cell with avatar and username link.
``login`` is validated against GitHub's username pattern before use.
- Raises ``ValueError`` if the login contains unexpected characters.
+ Returns ``None`` and logs a warning if the login contains unexpected
+ characters, so callers can skip the row rather than crashing.
"""
if not _GITHUB_LOGIN_RE.match(login):
- raise ValueError(f"Invalid GitHub login: {login!r}")
+ print(f"WARNING: skipping contributor with invalid GitHub login: {login!r}")
+ return None
safe_login = urllib.parse.quote(login, safe="")
escaped_login = html.escape(login)
return (
@@ -791,6 +793,8 @@ def generate_markdown(contributors, levels_data):
commits_display += f" ยท ๐ฆ {repos_count}"
contributor_cell = _contributor_cell(login)
+ if contributor_cell is None:
+ continue
lines.append(
f"| {rank} | {contributor_cell}"
f" | {level} | {rarity_display} | {commits_display}"
@@ -837,6 +841,8 @@ def generate_markdown(contributors, levels_data):
breakdown = " ยท ".join(breakdown_parts) if breakdown_parts else "โ"
contributor_cell = _contributor_cell(login)
+ if contributor_cell is None:
+ continue
lines.append(
f"| {i} | {contributor_cell}"
f" | {first_date} | {last_date}"