fix(git-tools): ci-queue-wait — Gitea statuses:null no longer malformed; CI-less repos pushable again (#1129)
ci/woodpecker/push/publish Pipeline was successful

Co-authored-by: Ghost <>
This commit was merged in pull request #1129.
This commit is contained in:
Ghost
2026-08-19 22:08:34 +00:00
committed by ops-02
co-authored by Ghost <>
parent 1bdeed62eb
commit d339e8fd21
4 changed files with 213 additions and 10 deletions
@@ -52,7 +52,11 @@ except Exception:
print("malformed")
raise SystemExit(0)
# Gitea returns "statuses": null (not []) for a commit with zero status
# contexts -- e.g. any repo with no CI configured. Treat null as empty.
raw_statuses = payload.get("statuses", [])
if raw_statuses is None:
raw_statuses = []
raw_state = payload.get("state", "")
if not isinstance(raw_statuses, list) or not isinstance(raw_state, str):
print("malformed")
@@ -75,14 +79,18 @@ for item in statuses:
raise SystemExit(0)
values.append(raw_value.lower())
if any(value in pending_values for value in values) or state in pending_values:
# Zero contexts is classified FIRST: Gitea reports a synthetic aggregate
# state of "pending" alongside total_count:0, and an aggregate with no
# contexts behind it must not read as an in-flight pipeline (it would poll
# to the timeout). With zero contexts there is nothing to wait on.
if not values:
print("no-status")
elif any(value in pending_values for value in values) or state in pending_values:
print("pending")
elif any(value in failure_values for value in values) or state in failure_values:
print("terminal-failure")
elif values and all(value in success_values for value in values) and state in {"", "success"}:
elif all(value in success_values for value in values) and state in {"", "success"}:
print("terminal-success")
elif not values:
print("no-status")
else:
print("unknown")
'
@@ -467,6 +475,11 @@ while true; do
echo "Error: ASSERTED_NOT_READY state=no-status; --require-status was set for ${BRANCH}." >&2
exit 3
fi
# A head with zero status contexts has no CI queue to wait on.
# For push, that is queue-clear (a repo with no CI must remain
# pushable) -- mirroring record_cannot_assert's dispositions
# (push=degraded-pass, merge=hold). Merge stays fail-closed:
# no-status there may just mean CI has not reported yet.
if [[ "$PURPOSE" == "push" ]]; then
echo "[ci-queue-wait] queue-clear state=no-status purpose=push branch=${BRANCH}; no queued or running CI."
exit 0