#!/bin/bash # Environment validation script # Validates all .env files for consistency and completeness set -e print_header() { echo "🔍 Environment Configuration Validation" echo "======================================" echo "" } print_section() { echo "" echo "📋 $1" echo "$(printf '%*s' ${#1} '' | tr ' ' '-')" } print_success() { echo "✅ $1" } print_warning() { echo "⚠️ $1" } print_error() { echo "❌ $1" } # Required variables for each environment CORE_VARS=( "COUCHDB_USER" "COUCHDB_PASSWORD" "VITE_COUCHDB_URL" "VITE_COUCHDB_USER" "VITE_COUCHDB_PASSWORD" "APP_BASE_URL" "MAILGUN_API_KEY" "MAILGUN_DOMAIN" "MAILGUN_FROM_EMAIL" ) K8S_VARS=( "INGRESS_HOST" ) OPTIONAL_VARS=( "NODE_ENV" "VITE_GOOGLE_CLIENT_ID" "VITE_GITHUB_CLIENT_ID" ) validate_file() { local file="$1" local file_type="$2" print_section "Validating $file ($file_type)" if [[ ! -f "$file" ]]; then print_error "File not found: $file" return 1 fi local missing_vars=() local found_vars=() # Check core variables for var in "${CORE_VARS[@]}"; do if grep -q "^${var}=" "$file" || grep -q "^#.*${var}=" "$file"; then found_vars+=("$var") else missing_vars+=("$var") fi done # Check K8s variables for relevant files if [[ "$file_type" != "template" ]]; then for var in "${K8S_VARS[@]}"; do if grep -q "^${var}=" "$file" || grep -q "^#.*${var}=" "$file"; then found_vars+=("$var") else missing_vars+=("$var") fi done fi # Report results print_success "Found ${#found_vars[@]} variables" if [[ ${#missing_vars[@]} -gt 0 ]]; then print_warning "Missing variables:" for var in "${missing_vars[@]}"; do echo " - $var" done fi # Check for old VITE_MAILGUN variables if grep -q "VITE_MAILGUN" "$file"; then print_error "Found deprecated VITE_MAILGUN variables (should be MAILGUN_*)" fi # Check variable format local malformed_vars=() while IFS= read -r line; do if [[ "$line" =~ ^[A-Z_]+=.* ]]; then local var_name="${line%%=*}" if [[ ! "$var_name" =~ ^[A-Z_][A-Z0-9_]*$ ]]; then malformed_vars+=("$var_name") fi fi done < "$file" if [[ ${#malformed_vars[@]} -gt 0 ]]; then print_warning "Malformed variable names:" for var in "${malformed_vars[@]}"; do echo " - $var" done fi echo "" } validate_consistency() { print_section "Cross-file Consistency Check" # Extract variable names from each file local example_vars=() local env_vars=() local prod_vars=() if [[ -f ".env.example" ]]; then while IFS= read -r line; do if [[ "$line" =~ ^[A-Z_]+=.* ]]; then example_vars+=("${line%%=*}") fi done < ".env.example" fi if [[ -f ".env" ]]; then while IFS= read -r line; do if [[ "$line" =~ ^[A-Z_]+=.* ]]; then env_vars+=("${line%%=*}") fi done < ".env" fi if [[ -f ".env.production" ]]; then while IFS= read -r line; do if [[ "$line" =~ ^[A-Z_]+=.* ]]; then prod_vars+=("${line%%=*}") fi done < ".env.production" fi # Check if .env and .env.production have all variables from .env.example local missing_in_env=() local missing_in_prod=() for var in "${example_vars[@]}"; do if [[ ! " ${env_vars[@]} " =~ " ${var} " ]]; then missing_in_env+=("$var") fi if [[ ! " ${prod_vars[@]} " =~ " ${var} " ]]; then missing_in_prod+=("$var") fi done if [[ ${#missing_in_env[@]} -eq 0 ]]; then print_success ".env has all variables from .env.example" else print_warning ".env missing variables from .env.example:" for var in "${missing_in_env[@]}"; do echo " - $var" done fi if [[ ${#missing_in_prod[@]} -eq 0 ]]; then print_success ".env.production has all variables from .env.example" else print_warning ".env.production missing variables from .env.example:" for var in "${missing_in_prod[@]}"; do echo " - $var" done fi echo "" } validate_k8s_template() { print_section "Kubernetes Template Validation" local template_file="k8s/ingress.yaml.template" if [[ ! -f "$template_file" ]]; then print_error "Template file not found: $template_file" return 1 fi # Check for template variables local template_vars=() while IFS= read -r line; do if [[ "$line" =~ \$\{([A-Z_][A-Z0-9_]*)\} ]]; then local var_name="${BASH_REMATCH[1]}" if [[ ! " ${template_vars[@]} " =~ " ${var_name} " ]]; then template_vars+=("$var_name") fi fi done < "$template_file" print_success "Found ${#template_vars[@]} template variables:" for var in "${template_vars[@]}"; do echo " - \${$var}" done # Check if template variables are defined in env files for var in "${template_vars[@]}"; do local found_in_files=() if grep -q "^${var}=" ".env.example" 2>/dev/null; then found_in_files+=(".env.example") fi if grep -q "^${var}=" ".env" 2>/dev/null; then found_in_files+=(".env") fi if grep -q "^${var}=" ".env.production" 2>/dev/null; then found_in_files+=(".env.production") fi if [[ ${#found_in_files[@]} -gt 0 ]]; then print_success "$var defined in: ${found_in_files[*]}" else print_error "$var not defined in any environment file" fi done echo "" } main() { print_header # Validate individual files if [[ -f ".env.example" ]]; then validate_file ".env.example" "template" fi if [[ -f ".env" ]]; then validate_file ".env" "development" fi if [[ -f ".env.production" ]]; then validate_file ".env.production" "production" fi # Cross-file validation validate_consistency # Kubernetes template validation validate_k8s_template print_section "Summary" print_success "Environment validation complete!" echo "" echo "💡 Tips:" echo " - Copy .env.example to .env for local development" echo " - Use .env.production for production deployments" echo " - Run './deploy-k8s.sh --dry-run' to test Kubernetes deployment" echo " - All Mailgun variables use server-side naming (no VITE_ prefix)" echo "" } main "$@"