Skip to content

Commit 46b323f

Browse files
authored
fix(bot): skip tests/ for secret patterns, basename forbidden match (#19)
Co-authored-by: samson910022 <samson910022@users.noreply.github.com>
1 parent fab47e2 commit 46b323f

2 files changed

Lines changed: 34 additions & 4 deletions

File tree

‎github_bot/src/repo_scan.py‎

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434
LOW_RISK_DIRS = ("tests/", "docs/")
3535
LOW_RISK_SUFFIXES = (".yml", ".yaml", ".md")
3636

37+
# Test fixtures are dummy keys by design; pattern-scanning them only produces
38+
# noise. Skipped for secret patterns (forbidden-file names are still checked
39+
# above for every path, so a committed tests/.env still fires as blocking).
40+
PATTERN_SKIP_DIRS = ("tests/",)
41+
3742

3843
def is_low_risk_path(rel: str) -> bool:
3944
"""True for fixture/doc/config paths where quoted hits are usually noise."""
@@ -45,10 +50,15 @@ def is_low_risk_path(rel: str) -> bool:
4550

4651

4752
def is_forbidden_tracked(rel: str) -> bool:
48-
"""True only for real secret files; never for `*.example` templates."""
49-
if rel in FORBIDDEN_TRACKED:
53+
"""True only for real secret files; never for `*.example` templates.
54+
55+
Matched by basename so a committed secret trips in any directory
56+
(including PATTERN_SKIP_DIRS like `tests/`).
57+
"""
58+
base = rel.rsplit("/", 1)[-1]
59+
if base in FORBIDDEN_TRACKED:
5060
return True
51-
if rel == ".env" or (rel.startswith(".env.") and not rel.endswith(".example")):
61+
if base == ".env" or (base.startswith(".env.") and not base.endswith(".example")):
5262
return True
5363
return False
5464
MATRIX_FILES = [
@@ -103,6 +113,11 @@ def scan_worktree(max_files: int = 400) -> list[dict[str, str]]:
103113
# Tracked templates (`.env.example`, `config.json.example`) carry
104114
# placeholder values by design; secret-pattern hits there are noise.
105115
continue
116+
if rel.startswith(PATTERN_SKIP_DIRS):
117+
# Fixture keys under tests/ are dummy by design; skip before any
118+
# I/O so they cost no file budget. Forbidden names already
119+
# checked above, so a committed tests/.env still fires.
120+
continue
106121
path = REPO_ROOT / rel
107122
if not path.is_file() or path.stat().st_size > 300_000:
108123
continue

‎tests/test_ai_bot.py‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ def test_scan_ignores_env_example(self):
106106
self.assertTrue(is_forbidden_tracked(".env"))
107107
self.assertTrue(is_forbidden_tracked(".env.local"))
108108
self.assertTrue(is_forbidden_tracked("config.json"))
109+
# Backstop holds inside skipped dirs: a committed tests/.env still fires.
110+
self.assertTrue(is_forbidden_tracked("tests/.env"))
109111

110112
def test_scrub_covers_full_catalog(self):
111113
from llm_client import INTERNAL_MODEL_NAMES
@@ -354,7 +356,8 @@ def test_low_risk_path_downgrade(self):
354356

355357
def test_prior_dry_run_fps_resolved(self):
356358
# The three dry-run false positives from the first live scan:
357-
# bare-code hit, unquoted yml env hit gone; quoted fixture hit is nit.
359+
# bare-code hit and unquoted yml env hit are gone; tests/ fixtures
360+
# are skipped for patterns (see test_tests_dir_skipped_for_patterns).
358361
from repo_scan import collect_findings, is_low_risk_path
359362
by_loc = {}
360363
for item in collect_findings():
@@ -371,6 +374,18 @@ def test_prior_dry_run_fps_resolved(self):
371374
if slug in ("possible-api-key", "possible-password") and is_low_risk_path(path):
372375
self.assertEqual(item["severity"], "nit", item["location"])
373376

377+
def test_tests_dir_skipped_for_patterns(self):
378+
# Fixture keys under tests/ are dummy by design: no secret-pattern
379+
# findings there (forbidden-file names are still checked).
380+
from repo_scan import PATTERN_SKIP_DIRS, collect_findings
381+
self.assertIn("tests/", PATTERN_SKIP_DIRS)
382+
for item in collect_findings():
383+
path = item["location"].split(":")[0]
384+
slug = item["fingerprint"].split(":")[1]
385+
if slug in ("possible-api-key", "possible-password",
386+
"private-key-material"):
387+
self.assertFalse(path.startswith("tests/"), item["location"])
388+
374389
def test_comment_modes(self):
375390
self.assertEqual(github_runner._resolve_comment_mode("/review please"), "review")
376391
self.assertEqual(github_runner._resolve_comment_mode("/fix this"), "fix-plan")

0 commit comments

Comments
 (0)