Files
wehub-resource-sync 2860fb5d18
Security / Dependency review (push) Has been skipped
Scorecard / Scorecard analysis (push) Failing after 0s
Validate / eval (push) Failing after 0s
Security / Dependency audit (push) Failing after 1s
Security / Secret scan (push) Failing after 1s
Validate / tests (push) Failing after 0s
Validate / mcp-tests (push) Failing after 1s
GitHub Actions Security Analysis with zizmor 🌈 / zizmor (push) Failing after 1s
Security / SAST scan (push) Failing after 13m52s
chore: import upstream snapshot with attribution
2026-07-13 12:05:33 +08:00

66 lines
2.3 KiB
Python

from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
WORKFLOW = ROOT / ".github" / "workflows" / "security.yml"
# AGENTS.md is the canonical agent-guidance file; CLAUDE.md is a one-line
# pointer (`@AGENTS.md`) so anything Claude Code-shaped reads the same source.
AGENTS = ROOT / "AGENTS.md"
def _workflow_text() -> str:
return WORKFLOW.read_text(encoding="utf-8")
def test_security_workflow_exists() -> None:
assert WORKFLOW.is_file()
def test_security_workflow_runs_dependency_audit_as_blocking_check() -> None:
text = _workflow_text()
dependency_audit_job = text.split("dependency-audit:", 1)[1].split("secret-scan:", 1)[0]
assert "dependency-audit:" in text
assert "uv audit --locked" in dependency_audit_job
assert "continue-on-error: true" not in dependency_audit_job
def test_security_workflow_runs_secret_scan_for_pull_requests_and_main_pushes() -> None:
text = _workflow_text()
secret_scan_job = text.split("secret-scan:", 1)[1].split("sast-scan:", 1)[0]
assert "secret-scan:" in text
assert "pull_request:" in text
assert "push:" in text
assert "workflow_dispatch:" in text
assert "branches:\n - main" in text
assert "trufflesecurity/trufflehog" in secret_scan_job
assert "version: 3.95.5" in secret_scan_job
assert "extra_args: --results=verified" in secret_scan_job
assert "continue-on-error: true" not in secret_scan_job
assert "if: github.event_name" not in secret_scan_job
assert "path: ./" not in secret_scan_job
def test_security_workflow_runs_sast_without_unused_code_scanning_permission() -> None:
text = _workflow_text()
sast_job = text.split("sast-scan:", 1)[1]
assert "semgrep/semgrep@sha256:" in sast_job
assert "semgrep scan --config=auto" in sast_job
assert "SEMGREP_SEND_METRICS: off" in sast_job
assert "continue-on-error: true" in sast_job
assert "contents: read" in sast_job
assert "security-events: write" not in sast_job
assert "--sarif" not in sast_job
assert "upload-sarif" not in sast_job
def test_agent_guidance_mentions_secret_hygiene() -> None:
text = AGENTS.read_text(encoding="utf-8")
assert "Security hygiene" in text
assert "Never commit real API keys" in text
assert "skills/last30days/scripts/lib/env.py" in text
assert "fixtures" in text