#!/bin/bash # Pre-push hook for Portfolio # Runs CI/CD checks before allowing push set -e echo "🚀 Running pre-push checks..." # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Function to print colored output print_status() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # Check if we're in the right directory if [ ! -f "package.json" ]; then print_error "Not in project root directory!" exit 1 fi # Check if Node.js is available if ! command -v node &> /dev/null; then print_error "Node.js is not installed!" exit 1 fi # Check Node.js version NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1) if [ "$NODE_VERSION" -lt 20 ]; then print_error "Node.js version 20+ required, found: $(node --version)" exit 1 fi print_success "Node.js version: $(node --version)" # Install dependencies if node_modules doesn't exist if [ ! -d "node_modules" ]; then print_status "Installing dependencies..." npm ci else print_status "Dependencies already installed" fi # Run linting print_status "Running ESLint..." if npm run lint; then print_success "Linting passed" else print_error "Linting failed! Please fix the issues before pushing." exit 1 fi # Run tests print_status "Running tests..." if npm run test; then print_success "Tests passed" else print_error "Tests failed! Please fix the issues before pushing." exit 1 fi # Build application print_status "Building application..." if npm run build; then print_success "Build successful" else print_error "Build failed! Please fix the issues before pushing." exit 1 fi # Security audit print_status "Running security audit..." if npm audit --audit-level=high; then print_success "Security audit passed" else print_warning "Security audit found issues. Consider running 'npm audit fix'" # Don't fail the push for security warnings, just warn fi # Check for secrets in code print_status "Checking for secrets in code..." if [ -f "scripts/check-secrets.sh" ]; then if ./scripts/check-secrets.sh; then print_success "No secrets found in code" else print_error "Secrets detected in code! Please remove them before pushing." exit 1 fi else print_warning "Secret check script not found, skipping..." fi # Check Docker configuration print_status "Checking Docker configuration..." if [ -f "Dockerfile" ]; then print_success "Dockerfile found" else print_error "Dockerfile not found!" exit 1 fi if [ -f "docker-compose.yml" ]; then print_success "Docker Compose configuration found" else print_error "Docker Compose configuration not found!" exit 1 fi # Check if we're pushing to production branch CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) if [ "$CURRENT_BRANCH" = "production" ]; then print_warning "Pushing to production branch - this will trigger deployment!" # Additional production checks print_status "Running production-specific checks..." # Check if environment file exists if [ ! -f ".env" ]; then print_warning "No .env file found. Make sure secrets are configured in Gitea." fi # Check Docker image can be built print_status "Testing Docker build..." if docker build -t portfolio-app:test . > /dev/null 2>&1; then print_success "Docker build test passed" docker rmi portfolio-app:test > /dev/null 2>&1 else print_error "Docker build test failed!" exit 1 fi fi # Final success message echo "" print_success "All pre-push checks passed! ✅" print_status "Ready to push to: $CURRENT_BRANCH" # Show what will be pushed echo "" print_status "Files to be pushed:" git diff --name-only HEAD~1 2>/dev/null || git diff --cached --name-only echo "" print_success "🚀 Push will proceed..."