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
This commit is contained in:
Graham McIntire 2026-01-15 13:04:41 -06:00
parent 4fe583b220
commit 82413df58b
No known key found for this signature in database

View file

@ -231,14 +231,36 @@ format_time_ago() {
} }
print_header() { print_header() {
clear # Only clear on first call
echo -e "${CYAN}╔════════════════════════════════════════════════════════════════╗${NC}" if [ -z "$HEADER_PRINTED" ]; then
echo -e "${CYAN}${NC} ${BLUE}${PROJECT_NAME} - CI/CD Monitor${NC} ${CYAN}${NC}" clear
echo -e "${CYAN}╚════════════════════════════════════════════════════════════════╝${NC}" 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 "" echo ""
} }
monitor_pipeline() { 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 branch=$(get_current_branch)
local local_sha=$(git rev-parse HEAD 2>/dev/null | cut -c1-8) local local_sha=$(git rev-parse HEAD 2>/dev/null | cut -c1-8)
@ -258,8 +280,21 @@ monitor_pipeline() {
local start_time=$(date +%s) local start_time=$(date +%s)
# Initialize header flag
HEADER_PRINTED=""
# Monitor until complete # Monitor until complete
while true; do 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 print_header
echo -e "${BLUE}Branch:${NC} $branch" echo -e "${BLUE}Branch:${NC} $branch"
@ -277,10 +312,7 @@ monitor_pipeline() {
echo -e "${BLUE}URL:${NC} $pipeline_web_url" echo -e "${BLUE}URL:${NC} $pipeline_web_url"
echo "" echo ""
# Get and display jobs # Display jobs
local jobs=$(get_pipeline_jobs "$pipeline_id")
local job_count=$(echo "$jobs" | jq '. | length')
echo -e "${CYAN}Jobs (${job_count} total):${NC}" echo -e "${CYAN}Jobs (${job_count} total):${NC}"
echo "$jobs" | jq -r '.[] | "\(.stage)|\(.name)|\(.status)|\(.duration)|\(.id)"' | \ echo "$jobs" | jq -r '.[] | "\(.stage)|\(.name)|\(.status)|\(.duration)|\(.id)"' | \
while IFS='|' read -r stage name status duration job_id; do while IFS='|' read -r stage name status duration job_id; do
@ -290,8 +322,7 @@ monitor_pipeline() {
echo "" echo ""
# Check for failures # Display failures
local failed_jobs=$(echo "$jobs" | jq -r '.[] | select(.status == "failed") | .id')
if [ -n "$failed_jobs" ]; then if [ -n "$failed_jobs" ]; then
echo -e "${RED}Failed Jobs:${NC}" echo -e "${RED}Failed Jobs:${NC}"
for job_id in $failed_jobs; do for job_id in $failed_jobs; do
@ -302,10 +333,6 @@ monitor_pipeline() {
echo "" echo ""
fi fi
# Update pipeline status
pipeline=$(get_latest_pipeline "$branch")
local new_status=$(echo "$pipeline" | jq -r '.status')
if [ "$new_status" != "$pipeline_status" ]; then if [ "$new_status" != "$pipeline_status" ]; then
pipeline_status=$new_status pipeline_status=$new_status
fi fi