#!/usr/bin/env bash set -euo pipefail BAR_WIDTH=50 SLEEP_INTERVAL=0.05 CLEAR_LINE="\033[K" LOG_FILE="/var/log/laravel_deploy.log" GREEN="\033[32m" RESET="\033[0m" STEPS=( "Pull latest code" "Maintenance mode" "Restart PHP-FPM" "Clear caches" "Optimize app" "Set permissions" "Ensure queue running" "Reset OPcache" "Bring app online" "Check php-fpm" "Check paymenter" ) CMDS=( "git pull --rebase --autostash --quiet" "php artisan down --render='errors::503' --retry=60 --quiet || true" "systemctl restart php8.3-fpm.service" "php artisan optimize:clear --quiet" "php artisan optimize --quiet" "find storage bootstrap/cache -not -perm 775 -type d -exec chmod 775 {} + -o -not -perm 664 -type f -exec chmod 664 {} +; chown -R www-data:www-data storage bootstrap/cache" "if ! pgrep -f 'artisan queue:work' >/dev/null; then nohup php artisan queue:work --daemon --quiet >> /dev/null 2>&1 & fi" "php -r 'if(function_exists(\"opcache_reset\")) opcache_reset();' 2>/dev/null || true" "php artisan up --quiet" "systemctl is-active --quiet php8.3-fpm || systemctl restart php8.3-fpm" "systemctl is-active --quiet paymenter.service || systemctl restart paymenter.service" ) rollback(){ echo -e "\n\033[31m✘ Deployment failed. Rolling back...\033[0m" git reset --hard HEAD@{1} >> "$LOG_FILE" 2>&1 php artisan up || true exit 1 } trap rollback ERR draw_bar() { local percent=$1 local width=$2 local text="$3" # Strip color codes for length calculation local clean_text=$(echo -ne "$text" | sed 's/\x1b\[[0-9;]*m//g') [ ${#clean_text} -gt $width ] && clean_text="${clean_text:0:$width}" local filled=$(( percent * width / 100 )) [ $filled -gt $width ] && filled=$width local text_start=$(( (width - ${#clean_text}) / 2 )) local text_end=$(( text_start + ${#clean_text} )) local bar="" for ((i=0;i= text_start && i < text_end )); then bar+="${clean_text:i-text_start:1}" else if (( i < filled )); then bar+="#" else bar+="-" fi fi done printf "[%s] %3d%%" "$bar" "$percent" } run_deployment() { local total_steps=${#STEPS[@]} for i in "${!STEPS[@]}"; do step_name="${STEPS[$i]}" cmd="${CMDS[$i]}" step_percent_start=$(( i * 100 / total_steps )) step_percent_end=$(( (i+1) * 100 / total_steps )) bash -c "$cmd" > >(tee -a "$LOG_FILE") 2> >(tee -a "$LOG_FILE" >&2) & pid=$! percent=$step_percent_start while kill -0 "$pid" 2>/dev/null; do [ "$percent" -lt "$step_percent_end" ] && percent=$((percent+1)) echo -ne "\r$(draw_bar $percent $BAR_WIDTH "$step_name")$CLEAR_LINE" sleep "$SLEEP_INTERVAL" done wait "$pid" # Fill bar to end of step echo -ne "\r$(draw_bar $step_percent_end $BAR_WIDTH "$step_name")$CLEAR_LINE" done # Final green completion bar final_text="Deployment Complete" # Construct bar normally bar=$(draw_bar 100 $BAR_WIDTH "$final_text") # Replace the visible text in the middle with green text clean_text_len=${#final_text} start=$(( (BAR_WIDTH - clean_text_len) / 2 + 1 )) # +1 for the [ end=$(( start + clean_text_len - 1 )) colored_bar="${bar:0:start-1}${GREEN}${final_text}${RESET}${bar:end}" echo -e "\r$colored_bar$CLEAR_LINE" echo "Log: $LOG_FILE" } run_deployment