fix(tools/git/pr-ci-wait): stdin collision in python3 - <<PY made wrapper always return "unknown"
When the wrapper invoked `python3 - <<'PY' ... PY` inside a function that
was being fed JSON via a pipe (`printf '%s' "$STATUS_JSON" |
extract_state_from_status_json`), the heredoc bound stdin to the Python
program text. The `-` argument tells Python to read its program from
stdin, so the program consumed stdin before json.load(sys.stdin) ran —
which then saw EOF and bailed to the "unknown" branch every time.
Result: pr-ci-wait.sh hung the full timeout (default 30 min) even when
the upstream Gitea status was already 'success', because every poll
returned 'unknown' and the loop kept retrying.
Fix: capture the piped JSON into a local variable with `payload=$(cat)`
BEFORE invoking python, then pass it via env (PR_CI_STATUS_JSON). The
heredoc still drives the Python program, but the payload is now read
from the environment instead of a stdin that's already been consumed.
Same fix applied to print_status_summary() which has the identical
pattern.
Verified locally:
$ echo '{"state":"success"}' | extract_state_from_status_json → success
$ echo '' | extract_state_from_status_json → unknown
$ echo '{"state":null,"statuses":[{"state":"success"}]}' | … → success
$ echo '{"state":"pending"}' | extract_state_from_status_json → pending
$ echo '{"state":"failure"}' | extract_state_from_status_json → failure
Reported in screenshot from operator session 2026-05-13 — wrapper was
stuck waiting on a PR whose underlying Gitea status was already
success. Operator workaround was to bypass the wrapper and use the raw
Gitea API.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -30,12 +30,19 @@ EOF
|
|||||||
# get_remote_host and get_gitea_token are provided by detect-platform.sh
|
# get_remote_host and get_gitea_token are provided by detect-platform.sh
|
||||||
|
|
||||||
extract_state_from_status_json() {
|
extract_state_from_status_json() {
|
||||||
python3 - <<'PY'
|
# Capture piped JSON BEFORE invoking `python3 - <<PY`. The heredoc binds
|
||||||
|
# stdin to the Python program text — so json.load(sys.stdin) inside would
|
||||||
|
# try to re-read stdin after `-` already consumed it for the program,
|
||||||
|
# yielding EOF and returning "unknown" every time. Pass payload via env.
|
||||||
|
local payload
|
||||||
|
payload=$(cat)
|
||||||
|
PR_CI_STATUS_JSON="$payload" python3 - <<'PY'
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
try:
|
try:
|
||||||
payload = json.load(sys.stdin)
|
payload = json.loads(os.environ.get("PR_CI_STATUS_JSON", ""))
|
||||||
except Exception:
|
except Exception:
|
||||||
print("unknown")
|
print("unknown")
|
||||||
raise SystemExit(0)
|
raise SystemExit(0)
|
||||||
@@ -66,12 +73,16 @@ PY
|
|||||||
}
|
}
|
||||||
|
|
||||||
print_status_summary() {
|
print_status_summary() {
|
||||||
python3 - <<'PY'
|
# Same stdin-collision fix as extract_state_from_status_json above.
|
||||||
|
local payload
|
||||||
|
payload=$(cat)
|
||||||
|
PR_CI_STATUS_JSON="$payload" python3 - <<'PY'
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
try:
|
try:
|
||||||
payload = json.load(sys.stdin)
|
payload = json.loads(os.environ.get("PR_CI_STATUS_JSON", ""))
|
||||||
except Exception:
|
except Exception:
|
||||||
print("[pr-ci-wait] status payload unavailable")
|
print("[pr-ci-wait] status payload unavailable")
|
||||||
raise SystemExit(0)
|
raise SystemExit(0)
|
||||||
|
|||||||
Reference in New Issue
Block a user