#!/usr/bin/env bash # PRE-PUSH # Check the repo for dependency, language, vulnerability, and build issues set -euo pipefail # Setting log colours RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m' echo -e "${GREEN}Running pre-push checks...${NC}" # Start time tracking START_TIME=$(date +%s) # Setting paths REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" CONTENT_DIR="$REPO_ROOT/content" ZENSICAL_CFG_PATH="$REPO_ROOT/zensical.toml" SITE_DIR="$REPO_ROOT/deploy" LOG_DIR="$REPO_ROOT/.checks/logs" mkdir -p "$LOG_DIR" # Cleanup old logs rm -f "$LOG_DIR/*" # Cleanup function cleanup() { trap - EXIT INT TERM if [[ -n "${SERVER_PID:-}" ]] && ps -p "$SERVER_PID" >/dev/null 2>&1; then kill "$SERVER_PID" >/dev/null 2>&1 || true for _ in {1..30}; do ps -p "$SERVER_PID" >/dev/null 2>&1 || break; sleep 0.1; done fi } trap cleanup EXIT INT TERM # Function to run commands and log output run_command() { local cmd="$1" local logfile="$2" echo -e "${GREEN}Running ${cmd}...${NC}" $cmd >"$logfile" 2>&1 || { echo -e "${RED}${cmd} failed. See $logfile${NC}"; exit 1; } } # Running independent checks in parallel { # Trivy check for vulnerabilities if command -v trivy &>/dev/null; then run_command "trivy fs . --exit-code 1 --severity CRITICAL,HIGH,MEDIUM,LOW,UNKNOWN --no-progress --scanners vuln" "$LOG_DIR/trivy.log" else echo -e "${YELLOW}Trivy not installed. Skipping vulnerability scan.${NC}" fi } & { # Trufflehog check for passwords and secrets if command -v trufflehog &>/dev/null && command -v jq &>/dev/null; then TMPF="$(mktemp)" trufflehog filesystem . --json >"$TMPF" 2>"$LOG_DIR/trufflehog.log" || true if jq -e 'select(.verified==true)' "$TMPF" | grep -q .; then cp "$TMPF" "$LOG_DIR/trufflehog-findings.json" echo -e "${RED}Verified secrets found. See $LOG_DIR/trufflehog-findings.json${NC}" rm -f "$TMPF"; exit 1 fi rm -f "$TMPF" else echo -e "${YELLOW}TruffleHog or jq not installed. Skipping secrets scan.${NC}" fi } & { # Dependabot dependency vulnerability check if command -v npm &>/dev/null && [[ -f package.json ]]; then run_command "npm audit --audit-level=high" "$LOG_DIR/npm-audit.log" elif command -v pip &>/dev/null && [[ -f requirements.txt ]]; then run_command "pip list --outdated" "$LOG_DIR/pip-outdated.log" if grep -q "upgradable" "$LOG_DIR/pip-outdated.log"; then echo -e "${YELLOW}Outdated Python dependencies found. See $LOG_DIR/pip-outdated.log${NC}" fi else echo -e "${YELLOW}No dependency management files found. Skipping dependency checks.${NC}" fi } & # Wait for all background jobs to finish wait # # Build the site using Zensical to check for build errors # if ! command -v zensical >/dev/null 2>&1; then # echo -e "${RED}Zensical not installed; cannot build docs.${NC}"; exit 1 # fi # run_command "zensical build --clean" "$LOG_DIR/zensical-build.log" # End time tracking and calculate duration END_TIME=$(date +%s) DURATION=$((END_TIME - START_TIME)) echo -e "${GREEN}Push checks completed in $DURATION seconds.${NC}"