Files
onepager/build.sh
mAi fdac496a6f mAi: #10 - Anti-AI-Text-Lint im Build
tools/anti-ai-lint.py: Python-Linter (stdlib + yq) prueft jede
build/<domain>/index.html gegen die Blacklist in
tools/anti-ai-blacklist.yaml. HTML wird via html.parser auf sichtbaren
Text reduziert (Skripte/Styles werden ignoriert), dann werden Vokabel-
Substrings (DE+EN, case-insensitive) und Regex-Patterns gematcht.
Severity warn = Build geht durch, fail = Build bricht ab.

Whitelist-Mechanismen:
- HTML-Kommentar im Markup: <!-- anti-ai-allow: term1, term2 -->
- Per-Site in site.yaml: anti_ai_allow: [term1, term2]

Integration in build.sh als Schritt 4/4, mit --skip-lint fuer
Notfaelle. Dockerfile installiert python3 zusaetzlich; nur im
Builder-Stage, kein Effekt aufs Caddy-Image.

Tests via tools/test-anti-ai-lint.sh: synthetische AI-Fixture wird
korrekt geflagged, Whitelists unterdruecken Hits, fail-Severity
triggert exit 1, neutraler Text exit 0.

Initial-Lauf auf 59 bestehenden Sites: 2 warn (killusion.de
"revolutionaer" in ironischem Kontext, kilofant.de "robust"),
0 fail. Cleanup ist Folge-Issue.

README + docs/geo-seo-guideline.md aktualisiert mit der konkreten
Tool-Position.
2026-04-30 02:50:50 +02:00

77 lines
2.3 KiB
Bash
Executable File

#!/bin/bash
# Build all sites: generate Caddyfile, render templates, prepare build/ directory
set -euo pipefail
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
BUILD_DIR="$SCRIPT_DIR/build"
skip_lint=0
for arg in "$@"; do
case "$arg" in
--skip-lint) skip_lint=1 ;;
-h|--help)
echo "Usage: $0 [--skip-lint]"
echo " --skip-lint Skip the anti-AI text lint step (emergencies only)."
exit 0
;;
*) echo "Unknown argument: $arg" >&2; exit 2 ;;
esac
done
echo "=== Onepager Build ==="
# Clean build directory
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
# 1. Generate Caddyfile
echo "[1/3] Generating Caddyfile..."
"$SCRIPT_DIR/generate-caddyfile.sh" "$SCRIPT_DIR/sites" > "$SCRIPT_DIR/Caddyfile"
echo " -> Caddyfile written"
# 2. Build each site
echo "[2/3] Building sites..."
count=0
for site_dir in "$SCRIPT_DIR/sites"/*/; do
[ -f "$site_dir/site.yaml" ] || continue
domain=$(basename "$site_dir")
template=$(yq -r '.template // "custom"' "$site_dir/site.yaml")
mkdir -p "$BUILD_DIR/$domain"
if [ "$template" = "custom" ]; then
# Copy everything except site.yaml
find "$site_dir" -maxdepth 1 -not -name site.yaml -not -path "$site_dir" -exec cp -r {} "$BUILD_DIR/$domain/" \;
echo " [custom] $domain"
else
template_file="$SCRIPT_DIR/templates/${template}.html"
if [ ! -f "$template_file" ]; then
echo " [ERROR] Template '$template' not found for $domain — skipping" >&2
continue
fi
"$SCRIPT_DIR/render.sh" "$site_dir/site.yaml" "$template_file" > "$BUILD_DIR/$domain/index.html"
# Copy assets if present
[ -d "$site_dir/assets" ] && cp -r "$site_dir/assets" "$BUILD_DIR/$domain/"
echo " [${template}] $domain"
fi
count=$((count + 1))
done
echo " -> $count sites built"
# 3. Copy shared assets
echo "[3/3] Copying shared assets..."
cp -r "$SCRIPT_DIR/shared" "$BUILD_DIR/shared"
echo " -> shared/ copied"
# 4. Anti-AI text lint
if [ "$skip_lint" -eq 1 ]; then
echo "[4/4] Anti-AI lint skipped (--skip-lint)"
elif ! command -v python3 >/dev/null 2>&1; then
echo "[4/4] python3 not found — skipping anti-AI lint"
else
echo "[4/4] Anti-AI text lint..."
python3 "$SCRIPT_DIR/tools/anti-ai-lint.py" "$BUILD_DIR"
fi
echo "=== Build complete: $count sites ==="