Files
wevads-platform/scripts/deploy-validator.sh
2026-02-26 04:53:11 +01:00

109 lines
4.6 KiB
Bash
Executable File

#!/bin/bash
# ╔═══════════════════════════════════════════════════════════════╗
# ║ 🔐 DEPLOY VALIDATOR — Pre-deploy integrity check ║
# ║ Usage: deploy-validator.sh <file> [target_dir] ║
# ║ Returns 0 if safe, 1 if blocked ║
# ║ Must pass ALL checks before any file is deployed ║
# ╚═══════════════════════════════════════════════════════════════╝
FILE="$1"
TARGET="${2:-/opt/wevads/public}"
VAULT="/opt/wevads/vault"
LOG="/opt/wevads/logs/deploy-validator.log"
if [ -z "$FILE" ]; then
echo '{"ok":false,"error":"Usage: deploy-validator.sh <file> [target_dir]"}'
exit 1
fi
fname=$(basename "$FILE")
ext="${fname##*.}"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
ERRORS=""
WARNINGS=""
new_size=$(wc -c < "$FILE" 2>/dev/null || echo 0)
log() { echo "[$TIMESTAMP] $1" >> "$LOG"; }
# ═══════════════════════════════════════
# CHECK 1: File exists and has content
# ═══════════════════════════════════════
if [ ! -f "$FILE" ]; then
echo '{"ok":false,"error":"File not found: '"$FILE"'"}'
exit 1
fi
if [ "$new_size" -lt 100 ]; then
echo '{"ok":false,"error":"File too small: '"$new_size"'B (min 100B)"}'
exit 1
fi
# ═══════════════════════════════════════
# CHECK 2: HTML-specific validations
# ═══════════════════════════════════════
if [ "$ext" = "html" ]; then
# Must have closing tags
if [ "$new_size" -gt 5000 ]; then
has_close_html=$(grep -c '</html>' "$FILE")
has_style=$(grep -c '<style' "$FILE")
has_script=$(grep -c '<script' "$FILE")
has_close_script=$(grep -c '</script>' "$FILE")
[ "$has_close_html" -eq 0 ] && ERRORS="${ERRORS}missing_close_html "
[ "$has_style" -eq 0 ] && WARNINGS="${WARNINGS}no_css "
[ "$has_script" -gt 0 ] && [ "$has_close_script" -eq 0 ] && ERRORS="${ERRORS}unclosed_script "
# Check onclick without script
has_onclick=$(grep -cE 'onclick|oninput' "$FILE")
[ "$has_onclick" -gt 0 ] && [ "$has_script" -eq 0 ] && ERRORS="${ERRORS}onclick_no_script "
fi
# Size regression check vs gold
gold="$VAULT/${fname}.gold"
if [ -f "$gold" ]; then
gold_size=$(wc -c < "$gold")
if [ "$gold_size" -gt 1000 ] && [ "$new_size" -lt "$((gold_size * 50 / 100))" ]; then
ERRORS="${ERRORS}size_regression(gold=${gold_size}B,new=${new_size}B) "
fi
fi
fi
# ═══════════════════════════════════════
# CHECK 3: PHP syntax validation
# ═══════════════════════════════════════
if [ "$ext" = "php" ]; then
result=$(php -l "$FILE" 2>&1)
if echo "$result" | grep -q 'Parse error\|Fatal'; then
ERRORS="${ERRORS}php_syntax_error "
fi
# Size regression vs gold
goldname=$(echo "$TARGET/$fname" | sed 's|/|__|g' | sed 's|^__||').gold
gold="$VAULT/$goldname"
if [ -f "$gold" ]; then
gold_size=$(wc -c < "$gold")
if [ "$gold_size" -gt 1000 ] && [ "$new_size" -lt "$((gold_size * 50 / 100))" ]; then
ERRORS="${ERRORS}size_regression(gold=${gold_size}B,new=${new_size}B) "
fi
fi
fi
# ═══════════════════════════════════════
# VERDICT
# ═══════════════════════════════════════
if [ -n "$ERRORS" ]; then
log "BLOCKED: $fname$ERRORS"
echo '{"ok":false,"file":"'"$fname"'","size":'"$new_size"',"errors":"'"$ERRORS"'","warnings":"'"$WARNINGS"'"}'
exit 1
else
log "APPROVED: $fname (${new_size}B) $WARNINGS"
# Auto-backup current live before deploy
target_file="$TARGET/$fname"
if [ -f "$target_file" ]; then
cp "$target_file" "$target_file.bak-$(date +%Y%m%d%H%M%S)" 2>/dev/null
fi
echo '{"ok":true,"file":"'"$fname"'","size":'"$new_size"',"warnings":"'"$WARNINGS"'"}'
exit 0
fi