Some checks failed
Smoke Test / smoke (push) Failing after 6s
- Check testament-complete.md (actual output) instead of build/the-testament-full.md - Exclude .gitea/workflows/smoke.yml from secret scan (it references patterns in its own grep command) Fixes CI failures on PR #33.
113 lines
3.5 KiB
Bash
Executable File
113 lines
3.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# The Testament — Smoke Test
|
|
# Dead simple CI: parse check + secret scan.
|
|
# Ref: https://forge.alexanderwhitestone.com/Timmy_Foundation/the-testament/issues/27
|
|
set -euo pipefail
|
|
|
|
PASS=0
|
|
FAIL=0
|
|
|
|
pass() { echo " ✓ $1"; PASS=$((PASS + 1)); }
|
|
fail() { echo " ✗ $1"; FAIL=$((FAIL + 1)); }
|
|
|
|
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
cd "$REPO_ROOT"
|
|
|
|
# ─── Section 1: Parse checks ───────────────────────────────────────
|
|
echo "── Parse Checks ──"
|
|
|
|
# 1a. Chapter validation (structure, numbering, headers)
|
|
if python3 compile.py --validate 2>&1; then
|
|
pass "Chapter validation passed"
|
|
else
|
|
fail "Chapter validation failed"
|
|
fi
|
|
|
|
# 1b. Build markdown combination
|
|
if python3 build/build.py --md >/dev/null 2>&1; then
|
|
pass "Markdown build passed"
|
|
else
|
|
fail "Markdown build failed"
|
|
fi
|
|
|
|
# 1c. Verify compiled output exists and is non-empty
|
|
MANUSCRIPT="testament-complete.md"
|
|
if [ -s "$MANUSCRIPT" ]; then
|
|
WORDS=$(wc -w < "$MANUSCRIPT" | tr -d ' ')
|
|
if [ "$WORDS" -gt 10000 ]; then
|
|
pass "Compiled manuscript: $WORDS words"
|
|
else
|
|
fail "Compiled manuscript suspiciously short: $WORDS words"
|
|
fi
|
|
else
|
|
fail "Compiled manuscript missing or empty"
|
|
fi
|
|
|
|
# 1d. Python syntax check on all .py files
|
|
PY_OK=true
|
|
for f in $(find . -name "*.py" -not -path "./.git/*"); do
|
|
if ! python3 -c "import ast; ast.parse(open('$f').read())" 2>/dev/null; then
|
|
fail "Python syntax error in $f"
|
|
PY_OK=false
|
|
fi
|
|
done
|
|
if $PY_OK; then
|
|
pass "All Python files parse cleanly"
|
|
fi
|
|
|
|
# 1e. YAML syntax check on workflow files
|
|
YAML_OK=true
|
|
for f in $(find .gitea -name "*.yml" -o -name "*.yaml" 2>/dev/null); do
|
|
if ! python3 -c "import yaml; yaml.safe_load(open('$f'))" 2>/dev/null; then
|
|
fail "YAML syntax error in $f"
|
|
YAML_OK=false
|
|
fi
|
|
done
|
|
if $YAML_OK; then
|
|
pass "All YAML files parse cleanly"
|
|
fi
|
|
|
|
# ─── Section 2: Secret scan ────────────────────────────────────────
|
|
echo ""
|
|
echo "── Secret Scan ──"
|
|
|
|
# Patterns that should never appear in a book repo
|
|
SECRET_PATTERNS=(
|
|
"sk-ant-"
|
|
"sk-or-"
|
|
"sk-[a-zA-Z0-9]{20,}"
|
|
"ghp_[a-zA-Z0-9]{36}"
|
|
"gho_[a-zA-Z0-9]{36}"
|
|
"AKIA[0-9A-Z]{16}"
|
|
"AKIA[A-Z0-9]{16}"
|
|
"xox[bpsa]-"
|
|
"SG\."
|
|
"-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY"
|
|
)
|
|
|
|
FOUND_SECRETS=false
|
|
for pattern in "${SECRET_PATTERNS[@]}"; do
|
|
# Search text files only, skip .git and binary files
|
|
HITS=$(grep -rn "$pattern" --include="*.md" --include="*.py" --include="*.sh" --include="*.yml" --include="*.yaml" --include="*.json" --include="*.html" --include="*.js" --include="*.css" --include="*.txt" --include="*.cfg" --include="*.ini" --exclude-dir=.git . 2>/dev/null | grep -v "scripts/smoke.sh" | grep -v ".gitea/workflows/smoke.yml" || true)
|
|
if [ -n "$HITS" ]; then
|
|
fail "Possible secret found: $pattern"
|
|
echo "$HITS" | head -5
|
|
FOUND_SECRETS=true
|
|
fi
|
|
done
|
|
if ! $FOUND_SECRETS; then
|
|
pass "No secrets detected"
|
|
fi
|
|
|
|
# ─── Summary ───────────────────────────────────────────────────────
|
|
echo ""
|
|
echo "Results: $PASS passed, $FAIL failed"
|
|
|
|
if [ "$FAIL" -gt 0 ]; then
|
|
echo "SMOKE TEST FAILED"
|
|
exit 1
|
|
else
|
|
echo "SMOKE TEST PASSED"
|
|
exit 0
|
|
fi
|