fix(mosaic-tools): roll up Gitea and Woodpecker wrapper fixes #524

Merged
jason.woltje merged 12 commits from fix/git-wrapper-rollup-20260526 into main 2026-05-26 20:56:10 +00:00
Owner

Summary

Rolls up the pending Mosaic wrapper fixes that are currently split across open PRs #513, #518, #521, #522, and #523.

Includes:

  • pr-ci-wait stdin-collision fix.
  • Gitea PR metadata and merge preflight hardening.
  • Gitea pr-merge empty-UID fallback and unsafe PR-number rejection.
  • Woodpecker legacy mosaic credentials and pagination fixes.
  • Explicit Gitea --repo/--login args for tea commands.
  • pr-create/issue-create eval removal for markdown/body safety.
  • CI Postgres service collision fix from the Woodpecker wrapper branch.

Verification

  • mosaic update checked first: @mosaicstack/mosaic remains 0.0.30/current, so source-side PR is required.
  • bash -n on changed shell wrappers.
  • test-pr-metadata-gitea.sh: pass.
  • test-pr-merge-gitea-empty-uid.sh: pass.
  • pr-list.sh --repo mosaicstack/stack smoke: pass.
  • issue-list.sh --repo mosaicstack/stack smoke: pass.
  • Independent shell-safety review found one blocker: malformed Gitea merge API JSON payload. Fixed and regression test now validates POST body.
  • Pre-push hook passed: typecheck, lint, format:check.

Operational Context

Workers are currently hitting: Remote repository required: Specify ID via --repo or execute from a local git repo.
This rollup is intended to restore reliable wrapper behavior so BMA orchestration can resume without local-only patch drift.

## Summary Rolls up the pending Mosaic wrapper fixes that are currently split across open PRs #513, #518, #521, #522, and #523. Includes: - pr-ci-wait stdin-collision fix. - Gitea PR metadata and merge preflight hardening. - Gitea pr-merge empty-UID fallback and unsafe PR-number rejection. - Woodpecker legacy mosaic credentials and pagination fixes. - Explicit Gitea --repo/--login args for tea commands. - pr-create/issue-create eval removal for markdown/body safety. - CI Postgres service collision fix from the Woodpecker wrapper branch. ## Verification - mosaic update checked first: @mosaicstack/mosaic remains 0.0.30/current, so source-side PR is required. - bash -n on changed shell wrappers. - test-pr-metadata-gitea.sh: pass. - test-pr-merge-gitea-empty-uid.sh: pass. - pr-list.sh --repo mosaicstack/stack smoke: pass. - issue-list.sh --repo mosaicstack/stack smoke: pass. - Independent shell-safety review found one blocker: malformed Gitea merge API JSON payload. Fixed and regression test now validates POST body. - Pre-push hook passed: typecheck, lint, format:check. ## Operational Context Workers are currently hitting: Remote repository required: Specify ID via --repo or execute from a local git repo. This rollup is intended to restore reliable wrapper behavior so BMA orchestration can resume without local-only patch drift.
jason.woltje added 12 commits 2026-05-26 20:37:43 +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>
style(docs): satisfy task table formatting
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
67c1ad155e
jason.woltje merged commit 821e19dcbb into main 2026-05-26 20:56:10 +00:00
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#524