#!/usr/bin/env bash set -euo pipefail BAR_WIDTH=50 SLEEP_INTERVAL=0.05 CLEAR_LINE="\033[K" GREEN="\033[32m" RESET="\033[0m" # Keep track of Git HEAD for summary OLD_HEAD=$(git rev-parse HEAD 2>/dev/null || echo "") STEPS=( "Pull latest code" "Maintenance mode" "Clear caches" "Optimize app" "Set permissions" "Ensure queue running" "Restart PHP-FPM" "Bring app online" "Check php-fpm" "Check paymenter" ) CMDS=( "git pull --rebase --autostash --quiet" "php artisan down --render='errors::503' --retry=60 --quiet || true" "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" "systemctl restart php8.3-fpm.service" "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" "systemctl restart nginx" ) rollback(){ echo -e "\n\033[31m✘ Deployment failed. Rolling back...\033[0m" git reset --hard HEAD@{1} || true php artisan up || true exit 1 } trap rollback ERR # Draw a progress bar with centered text draw_bar() { local percent=$1 local width=$2 local text="$3" 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 )) # Run the command: output hidden, bar stays clean bash -c "$cmd" > /dev/null 2>&1 & 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" echo -ne "\r$(draw_bar $step_percent_end $BAR_WIDTH "$step_name")$CLEAR_LINE" done # Final green completion bar final_text="Deployment Complete" final_bar=$(draw_bar 100 $BAR_WIDTH "$final_text") # Center green text inside the bar text_len=${#final_text} bar_only=${final_bar:1:BAR_WIDTH} # strip leading '[' start=$(( (BAR_WIDTH - text_len) / 2 )) end=$(( start + text_len )) green_bar="${final_bar:0:start+1}${GREEN}${final_text}${RESET}${final_bar:end+1}" echo -e "\r$green_bar$CLEAR_LINE" # Git summary if [ -n "$OLD_HEAD" ]; then NEW_HEAD=$(git rev-parse HEAD) if [ "$OLD_HEAD" != "$NEW_HEAD" ]; then echo -e "Git changes since last deploy:" git diff --shortstat "$OLD_HEAD" "$NEW_HEAD" else echo -e "No Git changes were applied." fi else echo -e "Git repository initialized." fi } run_deployment