[llvm] WIP Add check for private emails (PR #156106)

Baranov Victor via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 29 23:35:28 PDT 2025


https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/156106

>From 4428d30c3af97062c56ccd3e0bb02215ff0177d9 Mon Sep 17 00:00:00 2001
From: Victor Baranov <bar.victor.2002 at gmail.com>
Date: Sat, 30 Aug 2025 00:03:34 +0300
Subject: [PATCH 1/5] [GitHub] Check private email via github API

---
 .github/workflows/email-check.yaml   |  42 +++++----
 llvm/utils/git/email-check-helper.py | 123 +++++++++++++++++++++++++++
 2 files changed, 149 insertions(+), 16 deletions(-)
 create mode 100644 llvm/utils/git/email-check-helper.py

diff --git a/.github/workflows/email-check.yaml b/.github/workflows/email-check.yaml
index 9390fba4d4e3b..cf5e774e7ede0 100644
--- a/.github/workflows/email-check.yaml
+++ b/.github/workflows/email-check.yaml
@@ -17,27 +17,37 @@ jobs:
         uses: actions/checkout at 08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
         with:
           ref: ${{ github.event.pull_request.head.sha }}
+          fetch-depth: 2
 
-      - name: Extract author email
-        id: author
-        run: |
-          git log -1
-          echo "EMAIL=$(git show -s --format='%ae' HEAD~0)" >> $GITHUB_OUTPUT
-          # Create empty comment file
-          echo "[]" > comments
+      - name: Fetch email check utils
+        uses: actions/checkout at 08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        with:
+          repository: ${{ github.repository }}
+          ref: ${{ github.base_ref }}
+          sparse-checkout: |
+            llvm/utils/git/requirements_formatting.txt
+            llvm/utils/git/email-check-helper.py
+          sparse-checkout-cone-mode: false
+          path: email-check-tools
+
+      - name: Setup Python env
+        uses: actions/setup-python at 42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
+        with:
+          python-version: '3.11'
+
+      - name: Install python dependencies
+        run: pip install -r email-check-tools/llvm/utils/git/requirements_formatting.txt
 
       - name: Validate author email
-        if: ${{ endsWith(steps.author.outputs.EMAIL, 'noreply.github.com')  }}
         env:
-          COMMENT: >-
-            ⚠️ We detected that you are using a GitHub private e-mail address to contribute to the repo.<br/>
-            Please turn off [Keep my email addresses private](https://github.com/settings/emails) setting in your account.<br/>
-            See [LLVM Developer Policy](https://llvm.org/docs/DeveloperPolicy.html#email-addresses) and
-            [LLVM Discourse](https://discourse.llvm.org/t/hidden-emails-on-github-should-we-do-something-about-it) for more information.
+          GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
+          PR_AUTHOR: ${{ github.event.pull_request.user.login }}
         run: |
-          cat << EOF > comments
-          [{"body" : "$COMMENT"}]
-          EOF
+          echo "[]" > comments &&
+          python ./email-check-tools/llvm/utils/git/email-check-helper.py \
+            --token ${{ secrets.GITHUB_TOKEN }} \
+            --issue-number $GITHUB_PR_NUMBER \
+            --pr-author "$PR_AUTHOR"
 
       - uses: actions/upload-artifact at 26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0
         if: always()
diff --git a/llvm/utils/git/email-check-helper.py b/llvm/utils/git/email-check-helper.py
new file mode 100644
index 0000000000000..f9f07520fd649
--- /dev/null
+++ b/llvm/utils/git/email-check-helper.py
@@ -0,0 +1,123 @@
+#!/usr/bin/env python3
+#
+# ====- email-check-helper, checks for private email usage in PRs --*- python -*--==#
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ==--------------------------------------------------------------------------------------==#
+"""A helper script to detect private email of a Github user
+This script is run by GitHub actions to ensure that contributors to PR's are not
+using GitHub's private email addresses.
+
+The script enforces the LLVM Developer Policy regarding email addresses:
+https://llvm.org/docs/DeveloperPolicy.html#email-addresses
+"""
+
+import argparse
+import json
+import os
+import subprocess
+import sys
+from typing import Optional
+
+
+COMMENT_TAG = "<!--LLVM EMAIL CHECK COMMENT-->"
+
+
+def get_commit_email() -> Optional[str]:
+    proc = subprocess.run(
+        ["git", "show", "-s", "--format=%ae", "HEAD"],
+        stdout=subprocess.PIPE,
+        stderr=subprocess.PIPE,
+        encoding="utf-8",
+        check=False
+    )
+    if proc.returncode == 0:
+        return proc.stdout.strip()
+    return None
+
+
+def is_private_email(email: Optional[str]) -> bool:
+    if not email:
+        return False
+    return (email.endswith("noreply.github.com") or
+            email.endswith("users.noreply.github.com"))
+
+
+def check_user_email(token: str, pr_author: str) -> bool:
+    try:
+        from github import Github
+
+        print(f"Checking email privacy for user: {pr_author}")
+        
+        api = Github(token)
+        user = api.get_user(pr_author)
+        
+        print(f"User public email: {user.email or 'null (private)'}")
+
+        if user.email is not None and is_private_email(user.email):
+            return True
+
+        return is_private_email(get_commit_email())
+    except:
+        return False
+
+
+def generate_comment() -> str:
+    return f"""{COMMENT_TAG}
+⚠️ We detected that you are using a GitHub private e-mail address to contribute to the repo.<br/>
+Please turn off [Keep my email addresses private](https://github.com/settings/emails) setting in your account.<br/>
+See [LLVM Developer Policy](https://llvm.org/docs/DeveloperPolicy.html#email-addresses) and
+[LLVM Discourse](https://discourse.llvm.org/t/hidden-emails-on-github-should-we-do-something-about-it) for more information.
+"""
+
+
+def main():
+    """Main function."""
+    parser = argparse.ArgumentParser(
+        description="Check for private email usage in GitHub PRs"
+    )
+    parser.add_argument(
+        "--token", type=str, required=True, help="GitHub authentication token"
+    )
+    parser.add_argument(
+        "--repo",
+        type=str,
+        default=os.getenv("GITHUB_REPOSITORY", "llvm/llvm-project"),
+        help="The GitHub repository in the form of <owner>/<repo>",
+    )
+    parser.add_argument(
+        "--issue-number",
+        type=int,
+        required=True,
+        help="The PR number to check"
+    )
+    parser.add_argument(
+        "--pr-author",
+        type=str,
+        required=True,
+        help="The GitHub username of the PR author"
+    )
+
+    args = parser.parse_args()
+
+    has_private_email = check_user_email(args.token, args.pr_author)
+
+    comments = []
+    if has_private_email:
+        comments.append({"body": generate_comment()})
+
+    with open("comments", "w", encoding="utf-8") as f:
+        json.dump(comments, f)
+
+    print(f"Wrote {'comment' if has_private_email else 'empty comments'} to file")
+
+    if has_private_email:
+        print("Private email detected")
+        sys.exit(1)
+
+
+if __name__ == "__main__":
+    main()

>From 0f850a1ee785663ab4165216bf9fb6e953068173 Mon Sep 17 00:00:00 2001
From: Victor Baranov <bar.victor.2002 at gmail.com>
Date: Sat, 30 Aug 2025 00:05:56 +0300
Subject: [PATCH 2/5] DELETEME: for testing

---
 .github/workflows/email-check.yaml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/email-check.yaml b/.github/workflows/email-check.yaml
index cf5e774e7ede0..572eb81c96f9a 100644
--- a/.github/workflows/email-check.yaml
+++ b/.github/workflows/email-check.yaml
@@ -22,8 +22,8 @@ jobs:
       - name: Fetch email check utils
         uses: actions/checkout at 08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
         with:
-          repository: ${{ github.repository }}
-          ref: ${{ github.base_ref }}
+          repository: ${{ github.event.pull_request.head.repo.full_name }}
+          ref: ${{ github.event.pull_request.head.ref }}
           sparse-checkout: |
             llvm/utils/git/requirements_formatting.txt
             llvm/utils/git/email-check-helper.py

>From 5720a93b1062f2d251cde7e8068c942062eb0ddb Mon Sep 17 00:00:00 2001
From: Victor Baranov <bar.victor.2002 at gmail.com>
Date: Sat, 30 Aug 2025 09:26:47 +0300
Subject: [PATCH 3/5] WIP

---
 .github/workflows/email-check.yaml   |  2 --
 llvm/utils/git/email-check-helper.py | 10 +++-------
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/.github/workflows/email-check.yaml b/.github/workflows/email-check.yaml
index 572eb81c96f9a..6b2a29d11b107 100644
--- a/.github/workflows/email-check.yaml
+++ b/.github/workflows/email-check.yaml
@@ -40,13 +40,11 @@ jobs:
 
       - name: Validate author email
         env:
-          GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
           PR_AUTHOR: ${{ github.event.pull_request.user.login }}
         run: |
           echo "[]" > comments &&
           python ./email-check-tools/llvm/utils/git/email-check-helper.py \
             --token ${{ secrets.GITHUB_TOKEN }} \
-            --issue-number $GITHUB_PR_NUMBER \
             --pr-author "$PR_AUTHOR"
 
       - uses: actions/upload-artifact at 26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0
diff --git a/llvm/utils/git/email-check-helper.py b/llvm/utils/git/email-check-helper.py
index f9f07520fd649..711b86050f810 100644
--- a/llvm/utils/git/email-check-helper.py
+++ b/llvm/utils/git/email-check-helper.py
@@ -54,10 +54,12 @@ def check_user_email(token: str, pr_author: str) -> bool:
         
         api = Github(token)
         user = api.get_user(pr_author)
+        emails = user.get_emails()
+        print(emails)
         
         print(f"User public email: {user.email or 'null (private)'}")
 
-        if user.email is not None and is_private_email(user.email):
+        if user.email is not None or is_private_email(user.email):
             return True
 
         return is_private_email(get_commit_email())
@@ -88,12 +90,6 @@ def main():
         default=os.getenv("GITHUB_REPOSITORY", "llvm/llvm-project"),
         help="The GitHub repository in the form of <owner>/<repo>",
     )
-    parser.add_argument(
-        "--issue-number",
-        type=int,
-        required=True,
-        help="The PR number to check"
-    )
     parser.add_argument(
         "--pr-author",
         type=str,

>From f63d046f33e8a3fcf461bfe185df1ca2cbacddc2 Mon Sep 17 00:00:00 2001
From: Victor Baranov <bar.victor.2002 at gmail.com>
Date: Sat, 30 Aug 2025 09:28:52 +0300
Subject: [PATCH 4/5] start workflow always

---
 .github/workflows/email-check.yaml | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/email-check.yaml b/.github/workflows/email-check.yaml
index 6b2a29d11b107..c796e14086eea 100644
--- a/.github/workflows/email-check.yaml
+++ b/.github/workflows/email-check.yaml
@@ -2,8 +2,9 @@ name: "Check for private emails used in PRs"
 
 on:
   pull_request:
-    types:
-      - opened
+    branches:
+      - main
+      - 'users/**'
 
 permissions:
   contents: read

>From e00d579621f1119cb19841d665d0c9948f4728f4 Mon Sep 17 00:00:00 2001
From: Victor Baranov <bar.victor.2002 at gmail.com>
Date: Sat, 30 Aug 2025 09:35:14 +0300
Subject: [PATCH 5/5] add exception handler

---
 llvm/utils/git/email-check-helper.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/utils/git/email-check-helper.py b/llvm/utils/git/email-check-helper.py
index 711b86050f810..d0630f45fbe84 100644
--- a/llvm/utils/git/email-check-helper.py
+++ b/llvm/utils/git/email-check-helper.py
@@ -63,7 +63,8 @@ def check_user_email(token: str, pr_author: str) -> bool:
             return True
 
         return is_private_email(get_commit_email())
-    except:
+    except Exception as e:
+        print(f"got exception {e.with_traceback()}")
         return False
 
 



More information about the llvm-commits mailing list