From 66fc0478635fb17537f5b8abb8d5c4b13b99e84c Mon Sep 17 00:00:00 2001 From: tanjiro Kamado Date: Fri, 2 Oct 2026 09:15:22 +0530 Subject: [PATCH] verify LFX handles against the GitHub API in merge_lfx_contributors --- scripts/gc-elections/README.md | 2 +- scripts/gc-elections/generate-voters-roll.py | 31 ++++++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/scripts/gc-elections/README.md b/scripts/gc-elections/README.md index 3d5b9dd15..69e324a4d 100644 --- a/scripts/gc-elections/README.md +++ b/scripts/gc-elections/README.md @@ -10,7 +10,7 @@ Two environment variables are used across these scripts to configure output file The `generate-voters-roll.py` script generates a CSV file with the GitHub logins and contributions of the eligible voters for the upcoming elections. It works in two steps: 1. Queries the PostgreSQL Data Source backing `opentelemetry.devstats.cncf.io` to get the list of contributors with at least 20 contributions in the last year. It then uses the GitHub REST API to get the GitHub login (capitalized) for each user. -2. Fetches the full contributor list from [LFX Insights](https://insights.linuxfoundation.org/project/opentelemetry/contributors) and adds any contributors that devstats missed. Only contributors with at least 50 contributions are considered. For a contributor with multiple GitHub handles, if any of them is already on the list the contributor is skipped; otherwise only the first handle is added. +2. Fetches the full contributor list from [LFX Insights](https://insights.linuxfoundation.org/project/opentelemetry/contributors) and adds any contributors that devstats missed. Only contributors with at least 50 contributions are considered. For a contributor with multiple GitHub handles, if any of them is already on the list the contributor is skipped; otherwise the handles are resolved through the GitHub REST API and the login of the first one that resolves is added. A contributor whose handles do not resolve to any GitHub account is skipped. The merged list is written sorted case-insensitively by GitHub login. diff --git a/scripts/gc-elections/generate-voters-roll.py b/scripts/gc-elections/generate-voters-roll.py index 145e79bb5..1a0870bd6 100644 --- a/scripts/gc-elections/generate-voters-roll.py +++ b/scripts/gc-elections/generate-voters-roll.py @@ -119,12 +119,28 @@ def get_lfx_contributors(): return contributors +# Resolve an LFX contributor to a canonical GitHub login. +# LFX handle arrays are not validated against GitHub and are not ordered by +# recency, so the first entry is often a retired or renamed account. Return the +# first handle the API resolves, or None if none of them is a live account. +def resolve_lfx_handle(handles): + for handle in handles: + handle = handle.strip() + if not handle: + continue + login = get_github_login(handle) + if login: + return login + return None + + # Merge LFX contributors into the devstats rows. # For each LFX contributor: # - skip if their contribution count is below the threshold (50) # - skip if they have no GitHub handle at all # - skip if any of their handles is already present (case-insensitive) -# - otherwise add only the first handle in the array +# - skip if none of their handles resolves to a GitHub account +# - otherwise add the canonical login of the first handle that resolves def merge_lfx_contributors(rows, lfx_contributors): existing = {row[0].lower() for row in rows} added = 0 @@ -135,11 +151,16 @@ def merge_lfx_contributors(rows, lfx_contributors): handles = c.get("githubHandleArray") or [] if not handles: continue - if any(h.lower() in existing for h in handles): + if any(h.strip().lower() in existing for h in handles): + continue + login = resolve_lfx_handle(handles) + if not login: + print(f"Skipping LFX contributor with no live GitHub account: {handles}") + continue + if login.lower() in existing: continue - primary = handles[0] - rows.append([primary, c["contributions"]]) - existing.add(primary.lower()) + rows.append([login, c["contributions"]]) + existing.add(login.lower()) added += 1 print(f"Added {added} new contributors from LFX")