Show per-job CI progress instead of simple spinner in workflow wait
All checks were successful
Build-Test-Publish / build (linux/amd64) (push) Successful in 5s
Build-Test-Publish / build (linux/arm64) (push) Successful in 11s

This commit is contained in:
j
2026-03-09 07:10:36 +13:00
parent dadbe23169
commit efa946e153

127
gp
View File

@@ -514,7 +514,7 @@ parse_gitea_remote() {
} }
# Function to wait for CI workflow to complete after push # Function to wait for CI workflow to complete after push
# Polls Gitea Actions API, shows spinner, ESC cancels # Polls Gitea Actions API, shows per-job progress, ESC cancels
wait_for_workflow() { wait_for_workflow() {
local head_sha="$1" local head_sha="$1"
local branch="$2" local branch="$2"
@@ -540,7 +540,8 @@ wait_for_workflow() {
# Restore terminal on exit # Restore terminal on exit
trap 'stty "$old_tty" 2>/dev/null; trap - RETURN' RETURN trap 'stty "$old_tty" 2>/dev/null; trap - RETURN' RETURN
local run_url="" status="" conclusion="" found=false local run_url="" run_id="" found=false
local prev_lines=0 # track how many lines we printed last time
while [ "$elapsed" -lt "$max_wait" ]; do while [ "$elapsed" -lt "$max_wait" ]; do
# Check for ESC key # Check for ESC key
@@ -549,15 +550,19 @@ wait_for_workflow() {
if [ "$key" = $'\x1b' ]; then if [ "$key" = $'\x1b' ]; then
# Drain any remaining escape sequence bytes # Drain any remaining escape sequence bytes
dd bs=1 count=5 2>/dev/null >/dev/null || true dd bs=1 count=5 2>/dev/null >/dev/null || true
echo -e "\r\033[K" # Clear the job status lines
local i
for ((i=0; i<prev_lines; i++)); do
printf "\033[A\033[K"
done
print_info "Stopped waiting (CI still running in background)" print_info "Stopped waiting (CI still running in background)"
[ -n "$run_url" ] && print_info "View: $run_url" [ -n "$run_url" ] && print_info "View: $run_url"
return 0 return 0
fi fi
# Poll API # Poll API for the run
local response local response
response=$(curl -sf "${GITEA_API_BASE}/actions/runs?limit=5&token=${GITEA_API_TOKEN}" 2>/dev/null) || true response=$(curl -sf "${GITEA_API_BASE}/actions/runs?limit=5" -H "Authorization: token ${GITEA_API_TOKEN}" 2>/dev/null) || true
if [ -n "$response" ]; then if [ -n "$response" ]; then
# Find the run matching our commit SHA # Find the run matching our commit SHA
@@ -567,44 +572,130 @@ import json, sys
d = json.load(sys.stdin) d = json.load(sys.stdin)
for r in d.get('workflow_runs', []): for r in d.get('workflow_runs', []):
if r.get('head_sha','').startswith('${head_sha}'): if r.get('head_sha','').startswith('${head_sha}'):
print(r['status'], r.get('conclusion',''), r.get('html_url','')) print(r['id'], r['status'], r.get('conclusion',''), r.get('html_url',''))
break break
" 2>/dev/null) || true " 2>/dev/null) || true
if [ -n "$run_info" ]; then if [ -n "$run_info" ]; then
found=true found=true
status=$(echo "$run_info" | awk '{print $1}') run_id=$(echo "$run_info" | awk '{print $1}')
conclusion=$(echo "$run_info" | awk '{print $2}') local run_status
run_url=$(echo "$run_info" | awk '{print $3}') run_status=$(echo "$run_info" | awk '{print $2}')
local run_conclusion
run_conclusion=$(echo "$run_info" | awk '{print $3}')
run_url=$(echo "$run_info" | awk '{print $4}')
if [ "$status" = "completed" ]; then # Fetch per-job status
echo -e "\r\033[K" local jobs_response
if [ "$conclusion" = "success" ]; then jobs_response=$(curl -sf "${GITEA_API_BASE}/actions/runs/${run_id}/jobs" -H "Authorization: token ${GITEA_API_TOKEN}" 2>/dev/null) || true
# Clear previous output
local i
for ((i=0; i<prev_lines; i++)); do
printf "\033[A\033[K"
done
if [ "$run_status" = "completed" ]; then
# Show final job results
if [ -n "$jobs_response" ]; then
echo "$jobs_response" | python3 -c "
import json, sys
d = json.load(sys.stdin)
for j in d.get('jobs', []):
name = j['name']
conclusion = j.get('conclusion', '')
if conclusion == 'success':
icon = '\033[0;32m✓\033[0m'
elif conclusion == 'failure':
icon = '\033[0;31m✗\033[0m'
elif conclusion == 'cancelled':
icon = '\033[1;33m⊘\033[0m'
else:
icon = '\033[1;33m?\033[0m'
print(f' {icon} {name}')
" 2>/dev/null
fi
if [ "$run_conclusion" = "success" ]; then
print_success "CI workflow passed" print_success "CI workflow passed"
else else
print_error "CI workflow failed (conclusion: $conclusion)" print_error "CI workflow failed (conclusion: $run_conclusion)"
[ -n "$run_url" ] && print_info "View: $run_url" [ -n "$run_url" ] && print_info "View: $run_url"
return 1 return 1
fi fi
return 0 return 0
fi fi
# Show per-job progress with spinner
local spin_char="${spinner_chars:$spin_idx:1}"
spin_idx=$(( (spin_idx + 1) % ${#spinner_chars} ))
local mins=$((elapsed / 60))
local secs=$((elapsed % 60))
prev_lines=0
if [ -n "$jobs_response" ]; then
local job_lines
job_lines=$(echo "$jobs_response" | python3 -c "
import json, sys
d = json.load(sys.stdin)
for j in d.get('jobs', []):
name = j['name']
status = j['status']
conclusion = j.get('conclusion', '')
if status == 'completed' and conclusion == 'success':
icon = '\033[0;32m✓\033[0m'
label = ''
elif status == 'completed' and conclusion == 'failure':
icon = '\033[0;31m✗\033[0m'
label = ''
elif status == 'running':
icon = '${spin_char}'
label = ' running'
elif status == 'waiting':
icon = '·'
label = ' queued'
else:
icon = '·'
label = ' ' + status
print(f' {icon} {name}{label}')
" 2>/dev/null) || true
if [ -n "$job_lines" ]; then
echo "$job_lines"
prev_lines=$(echo "$job_lines" | wc -l)
fi
else
printf " %s CI %s (%d:%02d)\n" "$spin_char" "$run_status" "$mins" "$secs"
prev_lines=1
fi
sleep "$poll_interval"
elapsed=$((elapsed + poll_interval))
continue
fi fi
fi fi
# Show spinner # No run found yet - show waiting spinner
local spin_char="${spinner_chars:$spin_idx:1}" local spin_char="${spinner_chars:$spin_idx:1}"
spin_idx=$(( (spin_idx + 1) % ${#spinner_chars} )) spin_idx=$(( (spin_idx + 1) % ${#spinner_chars} ))
local status_msg="waiting"
$found && status_msg="$status"
local mins=$((elapsed / 60)) local mins=$((elapsed / 60))
local secs=$((elapsed % 60)) local secs=$((elapsed % 60))
printf "\r %s CI %s (%d:%02d)" "$spin_char" "$status_msg" "$mins" "$secs"
# Clear previous output
local i
for ((i=0; i<prev_lines; i++)); do
printf "\033[A\033[K"
done
printf " %s waiting for workflow to start (%d:%02d)\n" "$spin_char" "$mins" "$secs"
prev_lines=1
sleep "$poll_interval" sleep "$poll_interval"
elapsed=$((elapsed + poll_interval)) elapsed=$((elapsed + poll_interval))
done done
echo -e "\r\033[K" # Clear previous output
local i
for ((i=0; i<prev_lines; i++)); do
printf "\033[A\033[K"
done
print_warning "Timed out waiting for CI (${max_wait}s)" print_warning "Timed out waiting for CI (${max_wait}s)"
[ -n "$run_url" ] && print_info "View: $run_url" [ -n "$run_url" ] && print_info "View: $run_url"
return 0 return 0