- Docker must be running and functional before push is allowed - Added comprehensive Docker status checks (info + hello-world test) - Enhanced error messages with platform-specific Docker start instructions - Improved build error reporting with detailed log output - Added common troubleshooting tips for Docker build failures - Push will fail if Docker is not available or build fails
202 lines
5.5 KiB
Bash
Executable File
202 lines
5.5 KiB
Bash
Executable File
#!/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
|
|
chmod +x scripts/check-secrets.sh
|
|
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 if Docker is running and ready
|
|
print_status "Checking Docker status..."
|
|
if ! docker info > /dev/null 2>&1; then
|
|
print_error "Docker is not running! Please start Docker before pushing."
|
|
print_status "To start Docker:"
|
|
print_status " - macOS: Open Docker Desktop application"
|
|
print_status " - Linux: sudo systemctl start docker"
|
|
print_status " - Windows: Start Docker Desktop application"
|
|
print_status ""
|
|
print_status "Wait for Docker to fully start before trying again."
|
|
exit 1
|
|
fi
|
|
|
|
# Test Docker functionality
|
|
if ! docker run --rm hello-world > /dev/null 2>&1; then
|
|
print_error "Docker is running but not functional!"
|
|
print_status "Docker might still be starting up. Please wait and try again."
|
|
print_status "Or restart Docker if the issue persists."
|
|
exit 1
|
|
fi
|
|
|
|
print_success "Docker is running and functional"
|
|
|
|
# Check Docker image can be built
|
|
print_status "Testing Docker build..."
|
|
|
|
# Create a temporary log file for build output
|
|
BUILD_LOG=$(mktemp)
|
|
|
|
if docker build -t portfolio-app:test . > "$BUILD_LOG" 2>&1; then
|
|
print_success "Docker build test passed"
|
|
docker rmi portfolio-app:test > /dev/null 2>&1
|
|
rm -f "$BUILD_LOG"
|
|
else
|
|
print_error "Docker build test failed!"
|
|
print_status "Build errors:"
|
|
echo "----------------------------------------"
|
|
cat "$BUILD_LOG"
|
|
echo "----------------------------------------"
|
|
print_status "Please fix Docker build issues before pushing."
|
|
print_status "Common issues:"
|
|
print_status " - Missing files referenced in Dockerfile"
|
|
print_status " - Network issues during npm install"
|
|
print_status " - Insufficient disk space"
|
|
rm -f "$BUILD_LOG"
|
|
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..." |