fix(git-tools): ci-queue-wait mishandles Gitea statuses:null — push guard hard-fails on any repo without CI
ci/woodpecker/pr/ci Pipeline failed
ci/woodpecker/pr/ci Pipeline failed
Gitea's combined-status endpoint returns statuses:null (not []) plus a synthetic aggregate state of "pending" for a commit with zero status contexts (captured live 2026-08-09). The bash parser called that payload malformed -> ASSERTED_NOT_READY exit 3, blocking every push to a CI-less repo; hit twice by velma on two independent clones (shared checkout + fresh sparse clone), proving it environment-independent. - treat statuses:null as empty (both .sh and .ps1) - classify zero contexts as no-status BEFORE consulting the synthetic aggregate state (both twins; honoring it would poll to timeout) - no-status on --purpose push without --require-status is now queue-clear exit 0 (a repo with no CI has no queue), mirroring record_cannot_assert dispositions (push=degraded-pass, merge=hold); merge + --require-status stay fail-closed at exit 3 - red-first regression harness test-ci-queue-wait-no-status.sh (5 cases, incl. the verbatim live Gitea payload and a genuine-pending guard); branch-absent harness still green Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_013SAYFkRhQfhguY7AHfiUC8
This commit is contained in:
co-authored by
Claude Fable 5
parent
4df478cdd1
commit
74b3b9e869
@@ -85,10 +85,6 @@ function Get-QueueState {
|
||||
$state = "$($Payload.state)".ToLowerInvariant()
|
||||
}
|
||||
|
||||
if ($pending -contains $state) { return "pending" }
|
||||
if ($failure -contains $state) { return "terminal-failure" }
|
||||
if ($success -contains $state) { return "terminal-success" }
|
||||
|
||||
$values = @()
|
||||
$statuses = @()
|
||||
if ($null -ne $Payload.statuses) { $statuses = @($Payload.statuses) }
|
||||
@@ -101,7 +97,15 @@ function Get-QueueState {
|
||||
if (-not [string]::IsNullOrEmpty($v)) { $values += $v }
|
||||
}
|
||||
|
||||
if ($values.Count -eq 0 -and [string]::IsNullOrEmpty($state)) { return "no-status" }
|
||||
# Zero contexts is classified FIRST: Gitea reports a synthetic aggregate
|
||||
# state of "pending" alongside statuses:null / total_count:0 (a commit
|
||||
# with no CI at all), and honoring that aggregate would poll to the
|
||||
# timeout. With zero contexts there is nothing to wait on.
|
||||
if ($values.Count -eq 0) { return "no-status" }
|
||||
|
||||
if ($pending -contains $state) { return "pending" }
|
||||
if ($failure -contains $state) { return "terminal-failure" }
|
||||
if ($success -contains $state) { return "terminal-success" }
|
||||
if (($values | Where-Object { $pending -contains $_ }).Count -gt 0) { return "pending" }
|
||||
if (($values | Where-Object { $failure -contains $_ }).Count -gt 0) { return "terminal-failure" }
|
||||
if ($values.Count -gt 0 -and ($values | Where-Object { -not ($success -contains $_) }).Count -eq 0) { return "terminal-success" }
|
||||
|
||||
Reference in New Issue
Block a user