diff --git a/gp b/gp index c834e16..3a3739a 100755 --- a/gp +++ b/gp @@ -543,6 +543,11 @@ wait_for_workflow() { return 0 # silently skip if not a Gitea remote or no token fi + # Skip if no workflow files exist in the repo + if ! ls .gitea/workflows/*.yml .gitea/workflows/*.yaml .github/workflows/*.yml .github/workflows/*.yaml 2>/dev/null | grep -q .; then + return 0 + fi + local spinner_chars='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏' local spin_idx=0 local poll_interval=3 @@ -581,44 +586,58 @@ wait_for_workflow() { fi # Poll API for the run - local response - response=$(curl -sf "${GITEA_API_BASE}/actions/runs?limit=5" -H "Authorization: ${GITEA_AUTH_HEADER}" 2>/dev/null) || true - - if [ -n "$response" ]; then - # Find the run matching our commit SHA - local run_info - run_info=$(echo "$response" | python3 -c " + local run_info="" + if [ "$found" = true ] && [ -n "$run_id" ]; then + # Already locked onto a run - query it directly by ID + run_info=$(curl -sf "${GITEA_API_BASE}/actions/runs/${run_id}" -H "Authorization: ${GITEA_AUTH_HEADER}" 2>/dev/null \ + | python3 -c " +import json, sys +r = json.load(sys.stdin) +print(r['id'], r['status'], r.get('conclusion',''), r.get('html_url','')) +" 2>/dev/null) || true + else + # Search for a run matching our commit SHA (prefer push events) + local response + response=$(curl -sf "${GITEA_API_BASE}/actions/runs?limit=20" -H "Authorization: ${GITEA_AUTH_HEADER}" 2>/dev/null) || true + if [ -n "$response" ]; then + run_info=$(echo "$response" | python3 -c " import json, sys d = json.load(sys.stdin) -for r in d.get('workflow_runs', []): - if r.get('head_sha','').startswith('${head_sha}'): - print(r['id'], r['status'], r.get('conclusion',''), r.get('html_url','')) - break +runs = [r for r in d.get('workflow_runs', []) if r.get('head_sha','').startswith('${head_sha}')] +# Prefer push-triggered runs over workflow_run-triggered ones +push_runs = [r for r in runs if r.get('event') == 'push'] +pick = push_runs[0] if push_runs else (runs[0] if runs else None) +if pick: + print(pick['id'], pick['status'], pick.get('conclusion',''), pick.get('html_url','')) " 2>/dev/null) || true + fi + fi - if [ -n "$run_info" ]; then + if [ -n "$run_info" ]; then + if [ "$found" = false ]; then found=true run_id=$(echo "$run_info" | awk '{print $1}') - local run_status - 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}') + fi + local run_status + 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}') - # Fetch per-job status - local jobs_response - jobs_response=$(curl -sf "${GITEA_API_BASE}/actions/runs/${run_id}/jobs" -H "Authorization: ${GITEA_AUTH_HEADER}" 2>/dev/null) || true + # Fetch per-job status + local jobs_response + jobs_response=$(curl -sf "${GITEA_API_BASE}/actions/runs/${run_id}/jobs" -H "Authorization: ${GITEA_AUTH_HEADER}" 2>/dev/null) || true - # Clear previous output - local i - for ((i=0; i/dev/null - fi - if [ "$run_conclusion" = "success" ]; then - print_success "CI workflow passed" - else - print_error "CI workflow failed (conclusion: $run_conclusion)" - [ -n "$run_url" ] && print_info "View: $run_url" - return 1 - fi - return 0 fi + if [ "$run_conclusion" = "success" ]; then + print_success "CI workflow passed" + else + print_error "CI workflow failed (conclusion: $run_conclusion)" + [ -n "$run_url" ] && print_info "View: $run_url" + return 1 + fi + return 0 + 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)) + # 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 " + 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', []): @@ -667,7 +686,7 @@ for j in d.get('jobs', []): elif status == 'completed' and conclusion == 'failure': icon = '\033[0;31m✗\033[0m' label = '' - elif status == 'running': + elif status in ('running', 'in_progress'): icon = '${spin_char}' label = ' running' elif status == 'waiting': @@ -678,33 +697,40 @@ for j in d.get('jobs', []): 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 + if [ -n "$job_lines" ]; then + echo "$job_lines" + prev_lines=$(echo "$job_lines" | wc -l) fi - - sleep "$poll_interval" - elapsed=$((elapsed + poll_interval)) - continue + 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 - # No run found yet - show waiting spinner + # No run found yet - give up after 15 seconds (no workflow configured) + if [ "$elapsed" -ge 15 ]; then + local i + for ((i=0; i