From 82413df58b1b1b9da95c9247128a6449e58e559c Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Thu, 15 Jan 2026 13:04:41 -0600 Subject: [PATCH] Improve monitor script to eliminate screen flicker Instead of clearing the entire screen every 5 seconds, the script now: - Prints the header once and saves cursor position - Fetches all API data before updating display (no blank period) - Restores cursor position and updates only the content area - Hides cursor during display for cleaner look - Shows cursor on exit via cleanup trap Uses tput commands: - sc/rc: Save/restore cursor position - ed: Clear from cursor to end of screen - civis/cnorm: Hide/show cursor --- scripts/monitor-deploy.sh | 55 +++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/scripts/monitor-deploy.sh b/scripts/monitor-deploy.sh index 14e22bfc..144596d9 100755 --- a/scripts/monitor-deploy.sh +++ b/scripts/monitor-deploy.sh @@ -231,14 +231,36 @@ format_time_ago() { } print_header() { - clear - echo -e "${CYAN}╔════════════════════════════════════════════════════════════════╗${NC}" - echo -e "${CYAN}║${NC} ${BLUE}${PROJECT_NAME} - CI/CD Monitor${NC} ${CYAN}║${NC}" - echo -e "${CYAN}╚════════════════════════════════════════════════════════════════╝${NC}" + # Only clear on first call + if [ -z "$HEADER_PRINTED" ]; then + clear + echo -e "${CYAN}╔════════════════════════════════════════════════════════════════╗${NC}" + echo -e "${CYAN}║${NC} ${BLUE}${PROJECT_NAME} - CI/CD Monitor${NC} ${CYAN}║${NC}" + echo -e "${CYAN}╚════════════════════════════════════════════════════════════════╝${NC}" + echo "" + # Save cursor position after header + tput sc + HEADER_PRINTED=1 + else + # Restore cursor to saved position and clear from there to end + tput rc + tput ed + fi +} + +cleanup() { + # Reset cursor visibility and show cursor + tput cnorm echo "" } monitor_pipeline() { + # Trap exit to cleanup terminal state + trap cleanup EXIT INT TERM + + # Hide cursor for cleaner display + tput civis + local branch=$(get_current_branch) local local_sha=$(git rev-parse HEAD 2>/dev/null | cut -c1-8) @@ -258,8 +280,21 @@ monitor_pipeline() { local start_time=$(date +%s) + # Initialize header flag + HEADER_PRINTED="" + # Monitor until complete while true; do + # Fetch fresh data first (before updating display) + local jobs=$(get_pipeline_jobs "$pipeline_id") + local job_count=$(echo "$jobs" | jq '. | length') + local failed_jobs=$(echo "$jobs" | jq -r '.[] | select(.status == "failed") | .id') + + # Update pipeline status + pipeline=$(get_latest_pipeline "$branch") + local new_status=$(echo "$pipeline" | jq -r '.status') + + # Now update the display with all the fetched data print_header echo -e "${BLUE}Branch:${NC} $branch" @@ -277,10 +312,7 @@ monitor_pipeline() { echo -e "${BLUE}URL:${NC} $pipeline_web_url" echo "" - # Get and display jobs - local jobs=$(get_pipeline_jobs "$pipeline_id") - local job_count=$(echo "$jobs" | jq '. | length') - + # Display jobs echo -e "${CYAN}Jobs (${job_count} total):${NC}" echo "$jobs" | jq -r '.[] | "\(.stage)|\(.name)|\(.status)|\(.duration)|\(.id)"' | \ while IFS='|' read -r stage name status duration job_id; do @@ -290,8 +322,7 @@ monitor_pipeline() { echo "" - # Check for failures - local failed_jobs=$(echo "$jobs" | jq -r '.[] | select(.status == "failed") | .id') + # Display failures if [ -n "$failed_jobs" ]; then echo -e "${RED}Failed Jobs:${NC}" for job_id in $failed_jobs; do @@ -302,10 +333,6 @@ monitor_pipeline() { echo "" fi - # Update pipeline status - pipeline=$(get_latest_pipeline "$branch") - local new_status=$(echo "$pipeline" | jq -r '.status') - if [ "$new_status" != "$pipeline_status" ]; then pipeline_status=$new_status fi