Skip to content

Commit ea76dd8

Browse files
Merge pull request #144 from open-coder-ai/ci/no-email-leaks
ci: narrow the email check to the maintainer's address only
2 parents 66a69f7 + 4000706 commit ea76dd8

3 files changed

Lines changed: 34 additions & 8 deletions

File tree

.github/workflows/ci.yml

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,15 @@ jobs:
6262
env:
6363
BASE_SHA: ${{ github.event.pull_request.base.sha }}
6464
run: |
65-
# Local paths and session identifiers.
6665
local_data='/home/[A-Za-z0-9._-]+/|/Users/[A-Za-z0-9._-]+/|session_[0-9A-Za-z]{12,}|claude\.ai/code/session|/tmp/claude-[0-9]'
67-
# Any address, not a handful of consumer domains: a corporate or self-hosted
68-
# address is somebody's just as much as a gmail one. The last label must look like
69-
# a TLD, so `claude_code@2.1.263.json` and `pkg@1.2.3.tar.gz` are not matches.
7066
email='[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,24}'
71-
# Addresses that identify a service rather than a person.
72-
allowed='@users\.noreply\.github\.com$|^noreply@anthropic\.com$|^support@github\.com$|^noreply@github\.com$'
7367
# Suffixes that make a match a file path rather than an address.
7468
not_mail='\.(json|ya?ml|md|txt|py|js|ts|tsx|sh|toml|cfg|ini|lock|log|csv|tsv|html?|svg|png|jpe?g|gif|pdf|zip|gz|tar|whl|so|dll|exe)$'
69+
# Addresses that identify a service rather than a person.
70+
service='@users\.noreply\.github\.com$|^noreply@anthropic\.com$|^support@github\.com$|^noreply@github\.com$'
71+
# The maintainer's personal address, as a SHA-256 digest: writing it here in the
72+
# clear would publish it more prominently than the commits this check guards.
73+
blocked_digest='ecda4887099c1a8d73af02994c42938dfb0a1857674f6c3a6403af922360104f'
7574
found=0
7675
while read -r sha; do
7776
msg=$(git log -1 --format=%B "$sha")
@@ -80,10 +79,21 @@ jobs:
8079
echo "::error::commit $sha contains a local path or session identifier"
8180
found=1
8281
fi
83-
if printf '%s' "$msg" | grep -oiE "$email" | grep -ivE "$not_mail" | grep -qivE "$allowed"; then
84-
echo "::error::commit $sha contains an email address; sign off with your GitHub noreply address"
82+
# A sign-off is somebody's own attestation, so a contributor's address there is
83+
# their choice and stays allowed. Anywhere else an address arrived by accident --
84+
# pasted from a log, a stack trace, or a quoted report.
85+
body=$(printf '%s' "$msg" | grep -viE '^(Signed-off-by|Co-Authored-By|Reported-by|Reviewed-by|Tested-by|Acked-by):')
86+
if printf '%s' "$body" | grep -oiE "$email" | grep -ivE "$not_mail" | grep -qivE "$service"; then
87+
echo "::error::commit $sha contains an email address outside a sign-off trailer"
8588
found=1
8689
fi
90+
while read -r addr; do
91+
[ -n "$addr" ] || continue
92+
if [ "$(printf '%s' "$addr" | tr '[:upper:]' '[:lower:]' | sha256sum | cut -d' ' -f1)" = "$blocked_digest" ]; then
93+
echo "::error::commit $sha contains the maintainer's personal address; sign off with the GitHub noreply address"
94+
found=1
95+
fi
96+
done <<< "$(printf '%s' "$msg" | grep -oiE "$email")"
8797
done < <(git rev-list --no-merges "$BASE_SHA..HEAD")
8898
exit "$found"
8999

CONTRIBUTING.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,19 @@ vocabulary, why detection must never guess between two adapters, and what each c
205205
tier is defending against. If your change alters any of that, update the document in the
206206
same PR — nothing regenerates it.
207207

208+
## Figures
209+
210+
Every figure under `docs/figures/` is generated from this repository's own data by a script here,
211+
shipped as a light and a dark SVG, and regenerated in CI so a stale figure fails the build. If you
212+
are changing one, read the standard first — it explains the palette, why absence is never drawn as
213+
a weak grade, and why colour is never the only carrier of meaning:
214+
215+
https://github.com/open-coder-ai/.github/blob/main/VISUAL.md
216+
217+
`docs/figures/palette.py` and `make_family.py` are shared across every open-coder-ai repository and
218+
carried byte-identically. Change them at the source and copy them out; never edit one copy, and
219+
never add a per-repo lint or format exclude to work around them.
220+
208221
## Review policy
209222

210223
Adapters and the matrix get the slow path: they decide what downstream tools may claim.

docs/figures/palette.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
"""The one visual language every open-coder-ai figure is drawn in.
22
3+
The standard this implements, and the reasoning behind each rule:
4+
https://github.com/open-coder-ai/.github/blob/main/VISUAL.md
5+
36
Four repositories carry this file byte-identically while configuring `ruff format` at
47
three different line lengths (88, 100 and 120), so no formatted output could satisfy all
58
of them. Every statement here therefore fits on a single line under 88 characters and

0 commit comments

Comments
 (0)