Skip to content

Commit 185b907

Browse files
robertherberclaude
andcommitted
improve CI failure detail collection for better diagnosis
- Increase log capture from 200 to 500 lines, with smart truncation: first 100 lines (setup context) + last 400 lines (actual errors) - Include full logs when under 500 lines - List failed jobs and their failed step names for structure - Fetch GitHub check-run error annotations (file:line: message) which provide precise error locations - Show check state in failed checks list Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 6a697f8 commit 185b907

1 file changed

Lines changed: 66 additions & 7 deletions

File tree

scripts/eternity-loop.sh

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -726,12 +726,12 @@ get_ci_failure_details() {
726726
local branch_name
727727
branch_name=$(gh pr view "$pr_number" --json headRefName --jq '.headRefName' 2>/dev/null) || true
728728

729-
# Get failed check names
730-
local failed_checks
731-
failed_checks=$(gh pr checks "$pr_number" --json name,state,bucket --jq '[.[] | select(.bucket == "fail" or .state == "FAILURE" or .state == "ERROR")] | .[].name' 2>/dev/null) || true
729+
# Get failed check names with detail
730+
local failed_checks_json
731+
failed_checks_json=$(gh pr checks "$pr_number" --json name,state,bucket,detailsUrl 2>/dev/null) || true
732732

733733
echo "## Failed Checks"
734-
echo "$failed_checks"
734+
echo "$failed_checks_json" | jq -r '[.[] | select(.bucket == "fail" or .state == "FAILURE" or .state == "ERROR")] | .[] | "- \(.name) (\(.state // .bucket))"' 2>/dev/null || echo "(could not parse checks)"
735735
echo ""
736736

737737
# Find failed GitHub Actions runs on this branch for the HEAD commit
@@ -762,9 +762,68 @@ get_ci_failure_details() {
762762
local run_name
763763
run_name=$(gh run view "$run_id" --json name --jq '.name' 2>/dev/null) || run_name="Run $run_id"
764764
echo "### $run_name (run $run_id)"
765-
echo '```'
766-
gh run view "$run_id" --log-failed 2>/dev/null | tail -200
767-
echo '```'
765+
echo ""
766+
767+
# List failed jobs within this run for structure
768+
local failed_jobs
769+
failed_jobs=$(gh run view "$run_id" --json jobs --jq '[.jobs[] | select(.conclusion == "failure")] | .[] | "\(.name) (step: \([.steps[] | select(.conclusion == "failure")] | .[0].name // "unknown"))"' 2>/dev/null) || true
770+
if [ -n "$failed_jobs" ]; then
771+
echo "Failed jobs:"
772+
echo "$failed_jobs" | while IFS= read -r job; do echo "- $job"; done
773+
echo ""
774+
fi
775+
776+
# Get failed step logs — capture full output, then intelligently truncate
777+
local full_log
778+
full_log=$(gh run view "$run_id" --log-failed 2>/dev/null) || true
779+
780+
if [ -n "$full_log" ]; then
781+
local line_count
782+
line_count=$(echo "$full_log" | wc -l | tr -d ' ')
783+
log_err " [ci-details] Run $run_id failed log: $line_count lines"
784+
785+
if [ "$line_count" -le 500 ]; then
786+
# Short enough to include in full
787+
echo '```'
788+
echo "$full_log"
789+
echo '```'
790+
else
791+
# For large logs: include first 100 lines (setup/context) and last 400 lines (errors)
792+
echo '```'
793+
echo "--- First 100 lines (setup context) ---"
794+
echo "$full_log" | head -100
795+
echo ""
796+
echo "--- ... ($((line_count - 500)) lines omitted) ... ---"
797+
echo ""
798+
echo "--- Last 400 lines (failure details) ---"
799+
echo "$full_log" | tail -400
800+
echo '```'
801+
fi
802+
else
803+
echo '```'
804+
echo "(no log output available)"
805+
echo '```'
806+
fi
807+
808+
# Also try to get annotations (error/warning messages from the run)
809+
local annotations
810+
annotations=$(gh api "repos/{owner}/{repo}/check-runs" \
811+
--jq "[.check_runs[] | select(.external_id == \"$run_id\" or .name != \"\") | .output.annotations // []] | flatten | .[] | select(.annotation_level == \"failure\" or .annotation_level == \"error\") | \" \(.path):\(.start_line): \(.message)\"" 2>/dev/null) || true
812+
813+
if [ -z "$annotations" ]; then
814+
# Try via check-suites for this commit
815+
annotations=$(gh api "repos/{owner}/{repo}/commits/$head_sha/check-runs" \
816+
--jq "[.check_runs[] | select(.conclusion == \"failure\") | {name: .name, annotations: (.output.annotations // [])}] | .[] | .annotations[] | select(.annotation_level == \"failure\" or .annotation_level == \"error\") | \" \(.path):\(.start_line): \(.message)\"" 2>/dev/null) || true
817+
fi
818+
819+
if [ -n "$annotations" ]; then
820+
echo ""
821+
echo "#### Error Annotations"
822+
echo '```'
823+
echo "$annotations"
824+
echo '```'
825+
fi
826+
768827
echo ""
769828
done
770829
}

0 commit comments

Comments
 (0)