Resolved multiple critical discovery system issues: ## Discovery System Fixes - Fixed console commands not being discovered on first run - Implemented fallback discovery for empty caches - Added context-aware caching with separate cache keys - Fixed object serialization preventing __PHP_Incomplete_Class ## Cache System Improvements - Smart caching that only caches meaningful results - Separate caches for different execution contexts (console, web, test) - Proper array serialization/deserialization for cache compatibility - Cache hit logging for debugging and monitoring ## Object Serialization Fixes - Fixed DiscoveredAttribute serialization with proper string conversion - Sanitized additional data to prevent object reference issues - Added fallback for corrupted cache entries ## Performance & Reliability - All 69 console commands properly discovered and cached - 534 total discovery items successfully cached and restored - No more __PHP_Incomplete_Class cache corruption - Improved error handling and graceful fallbacks ## Testing & Quality - Fixed code style issues across discovery components - Enhanced logging for better debugging capabilities - Improved cache validation and error recovery Ready for production deployment with stable discovery system. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
459 lines
18 KiB
Bash
Executable File
459 lines
18 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# Deployment CLI - Unified Interface for Custom PHP Framework Deployment
|
||
# Provides easy access to all deployment tools and workflows
|
||
# Domain: michaelschiemer.de | Email: kontakt@michaelschiemer.de | PHP: 8.4
|
||
|
||
set -euo pipefail
|
||
|
||
# Script configuration
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../" && pwd)"
|
||
|
||
# Colors
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
PURPLE='\033[0;35m'
|
||
CYAN='\033[0;36m'
|
||
WHITE='\033[1;37m'
|
||
NC='\033[0m'
|
||
|
||
# Logging
|
||
log() { echo -e "${GREEN}[CLI] ✅ $1${NC}"; }
|
||
warn() { echo -e "${YELLOW}[CLI] ⚠️ $1${NC}"; }
|
||
error() { echo -e "${RED}[CLI] ❌ $1${NC}"; }
|
||
info() { echo -e "${BLUE}[CLI] ℹ️ $1${NC}"; }
|
||
success() { echo -e "${WHITE}[CLI] 🎉 $1${NC}"; }
|
||
|
||
# Show main help
|
||
show_help() {
|
||
cat << 'EOF'
|
||
|
||
██████╗ ███████╗██████╗ ██╗ ██████╗ ██╗ ██╗ ██████╗██╗ ██╗
|
||
██╔══██╗██╔════╝██╔══██╗██║ ██╔═══██╗╚██╗ ██╔╝ ██╔════╝██║ ██║
|
||
██║ ██║█████╗ ██████╔╝██║ ██║ ██║ ╚████╔╝ ██║ ██║ ██║
|
||
██║ ██║██╔══╝ ██╔═══╝ ██║ ██║ ██║ ╚██╔╝ ██║ ██║ ██║
|
||
██████╔╝███████╗██║ ███████╗╚██████╔╝ ██║ ╚██████╗███████╗██║
|
||
╚═════╝ ╚══════╝╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═════╝╚══════╝╚═╝
|
||
|
||
EOF
|
||
cat << EOF
|
||
${WHITE}Custom PHP Framework Deployment CLI${NC}
|
||
${CYAN}Domain: michaelschiemer.de | Email: kontakt@michaelschiemer.de | PHP: 8.4${NC}
|
||
|
||
${WHITE}Usage:${NC} $0 <command> [options]
|
||
|
||
${YELLOW}🚀 QUICK START COMMANDS${NC}
|
||
${GREEN}wizard${NC} Interactive setup wizard for new deployments
|
||
${GREEN}production${NC} One-command production setup and deployment
|
||
${GREEN}deploy <env>${NC} Deploy to specific environment (dev/staging/prod)
|
||
${GREEN}status <env>${NC} Check deployment status and health
|
||
|
||
${YELLOW}📋 SETUP & CONFIGURATION${NC}
|
||
${GREEN}setup${NC} Run initial project setup (dependencies, configs)
|
||
${GREEN}config <env>${NC} Configure environment settings
|
||
${GREEN}validate <env>${NC} Validate environment configuration
|
||
${GREEN}credentials <env>${NC} Generate secure credentials for environment
|
||
|
||
${YELLOW}🔐 SECURITY TOOLS${NC}
|
||
${GREEN}password [length]${NC} Generate secure password
|
||
${GREEN}ssh-key [name]${NC} Generate SSH key pair for deployment
|
||
${GREEN}security-scan${NC} Run security vulnerability scan
|
||
${GREEN}security-report <env>${NC} Generate comprehensive security report
|
||
|
||
${YELLOW}🐳 DOCKER & INFRASTRUCTURE${NC}
|
||
${GREEN}build <env>${NC} Build Docker containers for environment
|
||
${GREEN}up <env>${NC} Start Docker containers
|
||
${GREEN}down <env>${NC} Stop Docker containers
|
||
${GREEN}logs <env> [service] [--follow]${NC} Show Docker container logs
|
||
${CYAN}$0 logs production${NC} # All services (last 50 lines)
|
||
${CYAN}$0 logs production php${NC} # PHP service (last 100 lines)
|
||
${CYAN}$0 logs production nginx --follow${NC}# Follow nginx logs live
|
||
${GREEN}shell <env>${NC} Open shell in PHP container
|
||
|
||
${YELLOW}🗄️ DATABASE OPERATIONS${NC}
|
||
${GREEN}db:migrate <env>${NC} Run database migrations
|
||
${GREEN}db:status <env>${NC} Show migration status
|
||
${GREEN}db:backup <env>${NC} Create database backup
|
||
${GREEN}db:restore <env> <file>${NC} Restore from backup
|
||
|
||
${YELLOW}🔄 MAINTENANCE${NC}
|
||
${GREEN}update <env>${NC} Update deployment to latest code
|
||
${GREEN}rollback <env>${NC} Rollback to previous deployment
|
||
${GREEN}cleanup${NC} Clean up old files and containers
|
||
${GREEN}health <env>${NC} Run comprehensive health check
|
||
|
||
${YELLOW}ℹ️ INFORMATION${NC}
|
||
${GREEN}info <env>${NC} Show environment information
|
||
${GREEN}list${NC} List all available environments
|
||
${GREEN}version${NC} Show version information
|
||
${GREEN}help [command]${NC} Show help for specific command
|
||
|
||
${WHITE}Examples:${NC}
|
||
${CYAN}$0 wizard${NC} # Interactive setup for new deployment
|
||
${CYAN}$0 production --auto-yes${NC} # Automated production setup
|
||
${CYAN}$0 deploy staging --verbose${NC} # Deploy to staging with verbose output
|
||
${CYAN}$0 security-scan${NC} # Run security vulnerability scan
|
||
${CYAN}$0 credentials production${NC} # Generate production credentials
|
||
${CYAN}$0 logs production php --follow${NC} # Follow PHP logs in production
|
||
|
||
${WHITE}Environment Variables:${NC}
|
||
${YELLOW}DEPLOY_ENV${NC} Default environment (development/staging/production)
|
||
${YELLOW}DEPLOY_VERBOSE${NC} Enable verbose output (true/false)
|
||
${YELLOW}DEPLOY_DRY_RUN${NC} Enable dry-run mode (true/false)
|
||
|
||
${WHITE}Configuration Files:${NC}
|
||
${YELLOW}deployment/applications/environments/${NC} Environment configurations
|
||
${YELLOW}deployment/infrastructure/inventories/${NC} Ansible inventory files
|
||
${YELLOW}deployment/.credentials/${NC} Secure credential storage
|
||
|
||
EOF
|
||
}
|
||
|
||
# Execute command
|
||
execute_command() {
|
||
local command="$1"
|
||
shift
|
||
local args=("$@")
|
||
|
||
case $command in
|
||
# Quick start commands
|
||
"wizard")
|
||
info "Starting setup wizard..."
|
||
"${SCRIPT_DIR}/setup-wizard.sh" "${args[@]}"
|
||
;;
|
||
|
||
"production")
|
||
info "Starting one-command production setup..."
|
||
"${SCRIPT_DIR}/setup-production.sh" "${args[@]}"
|
||
;;
|
||
|
||
"deploy")
|
||
local env="${args[0]:-staging}"
|
||
info "Deploying to $env environment..."
|
||
"${SCRIPT_DIR}/deploy.sh" "$env" "${args[@]:1}"
|
||
;;
|
||
|
||
"status")
|
||
local env="${args[0]:-staging}"
|
||
info "Checking status for $env environment..."
|
||
"${SCRIPT_DIR}/deploy.sh" "$env" --dry-run --verbose "${args[@]:1}"
|
||
;;
|
||
|
||
# Setup & configuration
|
||
"setup")
|
||
info "Running initial project setup..."
|
||
"${SCRIPT_DIR}/setup.sh" "${args[@]}"
|
||
;;
|
||
|
||
"config")
|
||
local env="${args[0]:-production}"
|
||
info "Configuring $env environment..."
|
||
"${SCRIPT_DIR}/lib/config-manager.sh" apply-config "$env" \
|
||
"${args[1]:-$env.michaelschiemer.de}" \
|
||
"${args[2]:-kontakt@michaelschiemer.de}" \
|
||
"${args[3]:-}"
|
||
;;
|
||
|
||
"validate")
|
||
local env="${args[0]:-production}"
|
||
info "Validating $env configuration..."
|
||
"${SCRIPT_DIR}/lib/config-manager.sh" validate "$env"
|
||
;;
|
||
|
||
"credentials")
|
||
local env="${args[0]:-production}"
|
||
info "Generating credentials for $env environment..."
|
||
"${SCRIPT_DIR}/lib/config-manager.sh" generate-credentials "$env"
|
||
;;
|
||
|
||
# Security tools
|
||
"password")
|
||
local length="${args[0]:-32}"
|
||
"${SCRIPT_DIR}/lib/security-tools.sh" generate-password "$length"
|
||
;;
|
||
|
||
"ssh-key")
|
||
local name="${args[0]:-production}"
|
||
"${SCRIPT_DIR}/lib/security-tools.sh" generate-ssh "$name"
|
||
;;
|
||
|
||
"security-scan")
|
||
"${SCRIPT_DIR}/lib/security-tools.sh" scan "${args[0]:-$SCRIPT_DIR}"
|
||
;;
|
||
|
||
"security-report")
|
||
local env="${args[0]:-production}"
|
||
"${SCRIPT_DIR}/lib/security-tools.sh" report "$env"
|
||
;;
|
||
|
||
# Docker & infrastructure
|
||
"build")
|
||
local env="${args[0]:-development}"
|
||
info "Building Docker containers for $env..."
|
||
cd "$PROJECT_ROOT"
|
||
docker-compose -f docker-compose.yml \
|
||
-f "deployment/applications/docker-compose.${env}.yml" \
|
||
build "${args[@]:1}"
|
||
;;
|
||
|
||
"up")
|
||
local env="${args[0]:-development}"
|
||
info "Starting Docker containers for $env..."
|
||
cd "$PROJECT_ROOT"
|
||
docker-compose -f docker-compose.yml \
|
||
-f "deployment/applications/docker-compose.${env}.yml" \
|
||
up -d "${args[@]:1}"
|
||
;;
|
||
|
||
"down")
|
||
local env="${args[0]:-development}"
|
||
info "Stopping Docker containers for $env..."
|
||
cd "$PROJECT_ROOT"
|
||
docker-compose -f docker-compose.yml \
|
||
-f "deployment/applications/docker-compose.${env}.yml" \
|
||
down "${args[@]:1}"
|
||
;;
|
||
|
||
"logs")
|
||
local env="${args[0]:-development}"
|
||
local service="${args[1]:-}"
|
||
local follow="${args[2]:-}"
|
||
|
||
cd "$PROJECT_ROOT"
|
||
|
||
if [[ -z "$service" ]]; then
|
||
info "Showing logs for all services in $env environment..."
|
||
echo -e "${YELLOW}Available services: web, php, db, redis, queue-worker${NC}"
|
||
echo -e "${YELLOW}Usage: $0 logs $env [service] [--follow]${NC}"
|
||
echo -e "${YELLOW}Example: $0 logs production php --follow${NC}"
|
||
echo ""
|
||
|
||
docker-compose -f docker-compose.yml \
|
||
-f "deployment/applications/docker-compose.${env}.yml" \
|
||
logs --tail=50
|
||
else
|
||
if [[ "$follow" == "--follow" || "$follow" == "-f" ]]; then
|
||
info "Following logs for $service in $env environment (Press Ctrl+C to exit)..."
|
||
docker-compose -f docker-compose.yml \
|
||
-f "deployment/applications/docker-compose.${env}.yml" \
|
||
logs -f "$service"
|
||
else
|
||
info "Showing recent logs for $service in $env environment..."
|
||
docker-compose -f docker-compose.yml \
|
||
-f "deployment/applications/docker-compose.${env}.yml" \
|
||
logs --tail=100 "$service"
|
||
fi
|
||
fi
|
||
;;
|
||
|
||
"shell")
|
||
local env="${args[0]:-development}"
|
||
local service="${args[1]:-php}"
|
||
info "Opening shell in $service container ($env)..."
|
||
cd "$PROJECT_ROOT"
|
||
docker-compose -f docker-compose.yml \
|
||
-f "deployment/applications/docker-compose.${env}.yml" \
|
||
exec "$service" bash
|
||
;;
|
||
|
||
# Database operations
|
||
"db:migrate")
|
||
local env="${args[0]:-development}"
|
||
info "Running database migrations for $env..."
|
||
cd "$PROJECT_ROOT"
|
||
docker-compose -f docker-compose.yml \
|
||
-f "deployment/applications/docker-compose.${env}.yml" \
|
||
exec -T php php console.php db:migrate
|
||
;;
|
||
|
||
"db:status")
|
||
local env="${args[0]:-development}"
|
||
info "Showing migration status for $env..."
|
||
cd "$PROJECT_ROOT"
|
||
docker-compose -f docker-compose.yml \
|
||
-f "deployment/applications/docker-compose.${env}.yml" \
|
||
exec -T php php console.php db:status
|
||
;;
|
||
|
||
"db:backup")
|
||
local env="${args[0]:-development}"
|
||
local backup_file="backup_${env}_$(date +%Y%m%d_%H%M%S).sql"
|
||
info "Creating database backup for $env: $backup_file"
|
||
cd "$PROJECT_ROOT"
|
||
docker-compose -f docker-compose.yml \
|
||
-f "deployment/applications/docker-compose.${env}.yml" \
|
||
exec -T db mysqldump -u root -p\$DB_ROOT_PASSWORD --all-databases > "$backup_file"
|
||
success "Database backup created: $backup_file"
|
||
;;
|
||
|
||
"db:restore")
|
||
local env="${args[0]:-development}"
|
||
local backup_file="${args[1]:-}"
|
||
if [[ -z "$backup_file" ]]; then
|
||
error "Backup file required for restore"
|
||
exit 1
|
||
fi
|
||
warn "Restoring database from: $backup_file"
|
||
printf "Are you sure? [y/N]: "
|
||
read -r confirm
|
||
if [[ $confirm =~ ^[Yy]$ ]]; then
|
||
cd "$PROJECT_ROOT"
|
||
docker-compose -f docker-compose.yml \
|
||
-f "deployment/applications/docker-compose.${env}.yml" \
|
||
exec -T db mysql -u root -p\$DB_ROOT_PASSWORD < "$backup_file"
|
||
success "Database restored from: $backup_file"
|
||
fi
|
||
;;
|
||
|
||
# Maintenance
|
||
"update")
|
||
local env="${args[0]:-staging}"
|
||
info "Updating $env deployment to latest code..."
|
||
"${SCRIPT_DIR}/deploy.sh" "$env" --skip-backup "${args[@]:1}"
|
||
;;
|
||
|
||
"rollback")
|
||
local env="${args[0]:-staging}"
|
||
warn "Rolling back $env deployment..."
|
||
printf "Are you sure you want to rollback? [y/N]: "
|
||
read -r confirm
|
||
if [[ $confirm =~ ^[Yy]$ ]]; then
|
||
# Implementation depends on your rollback strategy
|
||
info "Rollback functionality - implementation needed"
|
||
fi
|
||
;;
|
||
|
||
"cleanup")
|
||
info "Cleaning up old Docker images and containers..."
|
||
docker system prune -f
|
||
docker image prune -f
|
||
"${SCRIPT_DIR}/lib/security-tools.sh" cleanup "${args[0]:-30}"
|
||
success "Cleanup completed"
|
||
;;
|
||
|
||
"health")
|
||
local env="${args[0]:-development}"
|
||
info "Running health check for $env environment..."
|
||
|
||
# Check Docker containers
|
||
cd "$PROJECT_ROOT"
|
||
echo -e "\n${CYAN}Docker Container Status:${NC}"
|
||
docker-compose -f docker-compose.yml \
|
||
-f "deployment/applications/docker-compose.${env}.yml" ps
|
||
|
||
# Check application health
|
||
echo -e "\n${CYAN}Application Health:${NC}"
|
||
if command -v curl >/dev/null 2>&1; then
|
||
local domain
|
||
case $env in
|
||
production) domain="https://michaelschiemer.de" ;;
|
||
staging) domain="https://staging.michaelschiemer.de" ;;
|
||
*) domain="https://localhost" ;;
|
||
esac
|
||
|
||
if curl -sf "$domain/api/health" >/dev/null 2>&1; then
|
||
success "Application health check passed"
|
||
else
|
||
warn "Application health check failed"
|
||
fi
|
||
fi
|
||
;;
|
||
|
||
# Information
|
||
"info")
|
||
local env="${args[0]:-production}"
|
||
"${SCRIPT_DIR}/lib/config-manager.sh" info "$env"
|
||
;;
|
||
|
||
"list")
|
||
"${SCRIPT_DIR}/lib/config-manager.sh" list
|
||
;;
|
||
|
||
"version")
|
||
cat << EOF
|
||
${WHITE}Custom PHP Framework Deployment CLI${NC}
|
||
Version: 1.0.0
|
||
Domain: michaelschiemer.de
|
||
Email: kontakt@michaelschiemer.de
|
||
PHP Version: 8.4
|
||
Built: $(date +'%Y-%m-%d')
|
||
EOF
|
||
;;
|
||
|
||
"help")
|
||
if [[ ${#args[@]} -gt 0 ]]; then
|
||
# Show specific command help
|
||
local help_command="${args[0]}"
|
||
case $help_command in
|
||
"wizard")
|
||
"${SCRIPT_DIR}/setup-wizard.sh" --help || true
|
||
;;
|
||
"production")
|
||
"${SCRIPT_DIR}/setup-production.sh" --help || true
|
||
;;
|
||
"deploy")
|
||
"${SCRIPT_DIR}/deploy.sh" --help || true
|
||
;;
|
||
*)
|
||
echo "No specific help available for: $help_command"
|
||
echo "Run '$0 help' for general help"
|
||
;;
|
||
esac
|
||
else
|
||
show_help
|
||
fi
|
||
;;
|
||
|
||
*)
|
||
error "Unknown command: $command"
|
||
echo
|
||
echo "Available commands:"
|
||
echo " wizard, production, deploy, status, setup, config, validate"
|
||
echo " credentials, password, ssh-key, security-scan, security-report"
|
||
echo " build, up, down, logs, shell, db:migrate, db:status, db:backup"
|
||
echo " update, rollback, cleanup, health, info, list, version, help"
|
||
echo
|
||
echo "Run '$0 help' for detailed usage information."
|
||
exit 1
|
||
;;
|
||
esac
|
||
}
|
||
|
||
# Main execution
|
||
main() {
|
||
if [[ $# -eq 0 ]]; then
|
||
show_help
|
||
exit 0
|
||
fi
|
||
|
||
local command="$1"
|
||
shift
|
||
|
||
# Apply environment variables
|
||
if [[ -n "${DEPLOY_VERBOSE:-}" ]]; then
|
||
set -x
|
||
fi
|
||
|
||
execute_command "$command" "$@"
|
||
}
|
||
|
||
# Error handling
|
||
cleanup() {
|
||
local exit_code=$?
|
||
if [[ $exit_code -ne 0 ]]; then
|
||
error "Command failed with exit code: $exit_code"
|
||
echo
|
||
echo -e "${CYAN}For help, run: $0 help${NC}"
|
||
echo -e "${CYAN}For verbose output, set: DEPLOY_VERBOSE=true${NC}"
|
||
fi
|
||
}
|
||
|
||
trap cleanup EXIT
|
||
|
||
# Execute if run directly
|
||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||
main "$@"
|
||
fi |