fix(tools/git/pr-ci-wait): stdin collision in python3 here-doc caused wrapper to always return unknown #513

Open
jason.woltje wants to merge 1 commits from fix/pr-ci-wait-stdin-collision into main
Owner

See commit a4cbd4b for full diagnosis. Heredoc-bound stdin consumed Python program text; json.load(sys.stdin) then saw EOF and bailed to unknown. Fix: capture stdin to local var before heredoc; pass via PR_CI_STATUS_JSON env. Same fix applied to both extract_state_from_status_json and print_status_summary.

See commit a4cbd4b for full diagnosis. Heredoc-bound stdin consumed Python program text; json.load(sys.stdin) then saw EOF and bailed to unknown. Fix: capture stdin to local var before heredoc; pass via PR_CI_STATUS_JSON env. Same fix applied to both extract_state_from_status_json and print_status_summary.
jason.woltje added 1 commit 2026-05-13 23:31:27 +00:00
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 pull request can be merged automatically.
This branch is out-of-date with the base branch
The changes on this branch are already on the target branch. This will be an empty commit.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin fix/pr-ci-wait-stdin-collision:fix/pr-ci-wait-stdin-collision
git checkout fix/pr-ci-wait-stdin-collision
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#513