#!/usr/bin/env bash # Advanced Pre-Push Security and Quality Check Script # Fail fast on any error set -euo pipefail # Color codes readonly RED='\033[0;31m' readonly GREEN='\033[0;32m' readonly YELLOW='\033[1;33m' readonly NC='\033[0m' # Paths REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" LOG_DIR="${REPO_ROOT}/.checks/logs" # Ensure log directory exists mkdir -p "$LOG_DIR" # Logging functions log_error() { echo -e "${RED}[ERROR] $*${NC}" >&2 } log_info() { echo -e "${GREEN}[INFO] $*${NC}" } log_warning() { echo -e "${YELLOW}[WARNING] $*${NC}" } # Vulnerability Scanning with Trivy run_trivy_scan() { # Check if Trivy is installed if ! command -v trivy &>/dev/null; then log_warning "Trivy not installed. Skipping vulnerability scan." return 0 fi # Ensure we have files to scan local files mapfile -t files < <(git ls-files) if [[ ${#files[@]} -eq 0 ]]; then log_warning "No files to scan with Trivy" return 0 fi log_info "Running Trivy vulnerability scan..." # Run Trivy scan if ! trivy fs "${files[@]}" \ --exit-code 1 \ --severity CRITICAL,HIGH,MEDIUM,LOW,UNKNOWN \ --no-progress \ >"$LOG_DIR/trivy.log" 2>&1; then log_error "Trivy scan failed. See $LOG_DIR/trivy.log" return 1 fi } # Secrets Detection with Trufflehog run_trufflehog_scan() { # Check if Trufflehog and jq are installed if ! (command -v trufflehog &>/dev/null && command -v jq &>/dev/null); then log_warning "TruffleHog or jq not installed. Skipping secrets scan." return 0 fi log_info "Running TruffleHog secrets scan..." local tmpf tmpf="$(mktemp)" # Scan files if ! trufflehog filesystem . --json >"$tmpf" 2>"$LOG_DIR/trufflehog.log"; then log_error "Trufflehog scan failed" rm -f "$tmpf" return 1 fi # Check for verified secrets local verified verified=$(jq 'select(.verified==true)' "$tmpf" | wc -l | tr -d ' ') if [[ "$verified" -gt 0 ]]; then cp "$tmpf" "$LOG_DIR/trufflehog-findings.json" log_error "Verified secrets found. See $LOG_DIR/trufflehog-findings.json" rm -f "$tmpf" return 1 fi rm -f "$tmpf" } # Main execution function main() { local failed=0 # Run each check and track failures run_trivy_scan || failed=1 run_trufflehog_scan || failed=1 # Exit with error if any checks failed if [[ $failed -eq 1 ]]; then log_error "Some pre-push checks failed. Aborting push." exit 1 fi log_info "All pre-push checks passed successfully!" } # Run the main function main "$@"