返回 last30days-skill
test_security_workflow.py
根目录 / tests / test_security_workflow.py
1 from pathlib import Path
2
3
4 ROOT = Path(__file__).resolve().parents[1]
5 WORKFLOW = ROOT / ".github" / "workflows" / "security.yml"
6 # AGENTS.md is the canonical agent-guidance file; CLAUDE.md is a one-line
7 # pointer (`@AGENTS.md`) so anything Claude Code-shaped reads the same source.
8 AGENTS = ROOT / "AGENTS.md"
9
10
11 def _workflow_text() -> str:
12 return WORKFLOW.read_text(encoding="utf-8")
13
14
15 def test_security_workflow_exists() -> None:
16 assert WORKFLOW.is_file()
17
18
19 def test_security_workflow_runs_dependency_audit_as_blocking_check() -> None:
20 text = _workflow_text()
21 dependency_audit_job = text.split("dependency-audit:", 1)[1].split("secret-scan:", 1)[0]
22
23 assert "dependency-audit:" in text
24 assert "uv audit --locked" in dependency_audit_job
25 assert "continue-on-error: true" not in dependency_audit_job
26
27
28 def test_security_workflow_runs_secret_scan_for_pull_requests_and_main_pushes() -> None:
29 text = _workflow_text()
30 secret_scan_job = text.split("secret-scan:", 1)[1].split("sast-scan:", 1)[0]
31
32 assert "secret-scan:" in text
33 assert "pull_request:" in text
34 assert "push:" in text
35 assert "workflow_dispatch:" in text
36 assert "branches:\n - main" in text
37 assert "trufflesecurity/trufflehog" in secret_scan_job
38 assert "version: 3.95.5" in secret_scan_job
39 assert "extra_args: --results=verified" in secret_scan_job
40 assert "continue-on-error: true" not in secret_scan_job
41 assert "if: github.event_name" not in secret_scan_job
42 assert "path: ./" not in secret_scan_job
43
44
45 def test_security_workflow_runs_sast_without_unused_code_scanning_permission() -> None:
46 text = _workflow_text()
47 sast_job = text.split("sast-scan:", 1)[1]
48
49 assert "semgrep/semgrep@sha256:" in sast_job
50 assert "semgrep scan --config=auto" in sast_job
51 assert "SEMGREP_SEND_METRICS: off" in sast_job
52 assert "continue-on-error: true" in sast_job
53 assert "contents: read" in sast_job
54 assert "security-events: write" not in sast_job
55 assert "--sarif" not in sast_job
56 assert "upload-sarif" not in sast_job
57
58
59 def test_agent_guidance_mentions_secret_hygiene() -> None:
60 text = AGENTS.read_text(encoding="utf-8")
61
62 assert "Security hygiene" in text
63 assert "Never commit real API keys" in text
64 assert "skills/last30days/scripts/lib/env.py" in text
65 assert "fixtures" in text
66
66 lines PYTHON