-
Notifications
You must be signed in to change notification settings - Fork 0
ci: enforce anonymous commit author identity #113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,31 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: Author Identity Check | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pull_request: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| branches: [main, master] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| author-check: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Verify commit authors use noreply email | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| set -eu | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| base="${{ github.event.pull_request.base.sha }}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| head="${{ github.event.pull_request.head.sha }}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bad=$(git log --pretty='%h %ae' "${base}..${head}" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | grep -v 'users\.noreply\.github\.com$' || true) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+20
to
+21
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bad=$(git log --pretty='%h %ae' "${base}..${head}" \ | |
| | grep -v 'users\.noreply\.github\.com$' || true) | |
| authors=$(git log --pretty='%h %ae' "${base}..${head}") | |
| bad=$(printf '%s\n' "$authors" | grep -v 'users\.noreply\.github\.com$' || true) |
Copilot
AI
Apr 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remediation hint prints git rebase -i $base, but $base is not defined in a developer’s local shell (it’s only a variable inside this CI step). Consider printing the actual base SHA (expand ${base}) or suggesting a more actionable target like origin/main so the instructions are directly usable.
| echo " git rebase -i \$base # squash/edit to apply new identity" | |
| echo " git rebase -i ${base} # squash/edit to apply new identity" |
Copilot
AI
Apr 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only checks the commit author email (%ae). If the goal is preventing email PII in git metadata, consider also checking the committer email (%ce) since it can differ (e.g., amended/cherry-picked commits) and could still leak a non-noreply address.
| bad=$(git log --pretty='%h %ae' "${base}..${head}" \ | |
| | grep -v 'users\.noreply\.github\.com$' || true) | |
| if [ -n "$bad" ]; then | |
| echo "::error::PR contains commits with non-noreply author email:" | |
| echo "$bad" | |
| echo | |
| echo "Fix locally:" | |
| echo " git config user.email USER@users.noreply.github.com" | |
| echo " git rebase -i \$base # squash/edit to apply new identity" | |
| exit 1 | |
| fi | |
| echo "All commit author emails OK" | |
| bad="" | |
| while read -r hash author_email committer_email; do | |
| case "$author_email" in | |
| *users.noreply.github.com) author_ok=1 ;; | |
| *) author_ok=0 ;; | |
| esac | |
| case "$committer_email" in | |
| *users.noreply.github.com) committer_ok=1 ;; | |
| *) committer_ok=0 ;; | |
| esac | |
| if [ "$author_ok" -eq 0 ] || [ "$committer_ok" -eq 0 ]; then | |
| bad="${bad}${hash} author=${author_email} committer=${committer_email}"$'\n' | |
| fi | |
| done <<EOF | |
| $(git log --pretty='%h %ae %ce' "${base}..${head}") | |
| EOF | |
| if [ -n "$bad" ]; then | |
| echo "::error::PR contains commits with non-noreply author or committer email:" | |
| printf '%s' "$bad" | |
| echo | |
| echo "Fix locally:" | |
| echo " git config user.email USER@users.noreply.github.com" | |
| echo " git rebase -i \$base # squash/edit to apply new identity" | |
| exit 1 | |
| fi | |
| echo "All commit author and committer emails OK" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The regex
users\.noreply\.github\.com$matches any domain that merely ends with that suffix (e.g.,someone@badusers.noreply.github.com). To avoid false passes, anchor it to the domain boundary, e.g. require@users.noreply.github.comat the end (and optionally do a case-insensitive match).