Skip to content

fix(tooling): prevent run_test from silently hanging during CGO recom… #76

fix(tooling): prevent run_test from silently hanging during CGO recom…

fix(tooling): prevent run_test from silently hanging during CGO recom… #76

Workflow file for this run

name: Doctor
on:
workflow_dispatch:
push:
branches: [ main, staging, canary ]
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
doctor:
runs-on: ubuntu-latest
if: ${{ vars.ENABLE_DOCTOR_SNAPSHOT != 'FALSE' }}
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Run doctor (JSON snapshot)
if: always()
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -euo pipefail
mkdir -p build/doctor
./scripts/doctor.sh --json --allow-ci > build/doctor/doctor.json
- name: Validate doctor JSON (required fields)
if: always()
shell: bash
run: |
set -euo pipefail
json="build/doctor/doctor.json"
# Required top-level keys
required_keys=(
status
os
git_branch
docker_provider
warnings
errors
)
for key in "${required_keys[@]}"; do
if ! jq -e ".${key} != null" "$json" >/dev/null; then
echo "::error::doctor.json missing required key '${key}'"
exit 1
fi
done
# status must be pass|fail|skip
status="$(jq -r '.status' "$json")"
case "$status" in
pass|fail|skip) ;;
*)
echo "::error::invalid doctor status: ${status}"
exit 1
;;
esac
# warnings/errors must be arrays
jq -e '.warnings | type == "array"' "$json" >/dev/null
jq -e '.errors | type == "array"' "$json" >/dev/null
echo "✅ doctor.json structure validated (jq)"
- name: Annotate doctor findings
if: always()
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -euo pipefail
json="build/doctor/doctor.json"
# Cap annotations to avoid noise
max_err=10
max_warn=10
# Emit GitHub annotations for one JSON array key.
# Usage: emit_annotations <key> <level> <max>
emit_annotations() {
local key="$1" level="$2" max="$3"
jq -r --argjson max "$max" ".${key}[:\$max][]" "$json" \
| while IFS= read -r msg; do
[[ -z "${msg//[[:space:]]/}" ]] && continue
printf '::%s::%s\n' "$level" "$msg"
done
}
# Parse once to avoid re-reading the file per field.
doctor=$(cat "$json")
err_count=$(jq -r '.errors | length' <<< "$doctor")
warn_count=$(jq -r '.warnings | length' <<< "$doctor")
[[ "$err_count" -gt 0 ]] && emit_annotations errors error "$max_err"
[[ "$warn_count" -gt 0 ]] && emit_annotations warnings warning "$max_warn"
echo "🔔 annotations emitted: errors=${err_count} warnings=${warn_count} (capped at ${max_err}/${max_warn})"
- name: Doctor summary and status check
if: always()
shell: bash
working-directory: ${{ github.workspace }}
run: |
set -euo pipefail
# Parse once — avoids re-reading the file for each field.
doctor=$(cat build/doctor/doctor.json)
status=$(jq -r '.status // "unknown"' <<< "$doctor")
warn_count=$(jq -r '.warnings | length' <<< "$doctor")
err_count=$(jq -r '.errors | length' <<< "$doctor")
echo "🩺 doctor: status=${status} warnings=${warn_count} errors=${err_count}"
# Write step summary before the potential exit so it is always visible.
{
echo "## 🩺 Doctor snapshot"
echo ""
echo "- **status:** \`${status}\`"
echo "- **warnings:** \`${warn_count}\`"
echo "- **errors:** \`${err_count}\`"
} >> "$GITHUB_STEP_SUMMARY"
if [[ "$status" == "fail" ]]; then
echo "::error::doctor reported status=fail"
exit 1
fi
- name: Upload doctor report
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: doctor-report
path: build/doctor/doctor.json
if-no-files-found: error
retention-days: 14