From 7f383f3466992495f8b8113578f9a82228fcb814 Mon Sep 17 00:00:00 2001 From: Konstantin Renner Date: Fri, 26 Jun 2026 09:40:18 +0200 Subject: [PATCH] ci(update-audit): surface Gitea API failures in the post step The first smoke run went green but created no issue: the post step used `jq | curl -sf | jq`, so the pipe's exit status came from the trailing jq and a failed POST was swallowed. Rewrite the post step to capture each write's HTTP status explicitly via `-w '%{http_code}'`, print it, and fail the step on any non-2xx (dumping the Gitea error body). Payloads are written to files instead of piped. Co-Authored-By: Claude Opus 4.8 (1M context) --- .woodpecker/update-audit.yml | 44 ++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/.woodpecker/update-audit.yml b/.woodpecker/update-audit.yml index f0297869..91453dd5 100644 --- a/.woodpecker/update-audit.yml +++ b/.woodpecker/update-audit.yml @@ -63,28 +63,44 @@ steps: # Post the report to a single persistent Gitea issue. Find the open # issue by its stable title; update its body and add a dated comment # if it exists, otherwise create it. + # + # Every write captures the HTTP status explicitly and fails the step + # on any non-2xx — a piped `... | curl -sf | jq` would mask a failed + # POST behind the trailing jq's exit code (the pipe's status is the + # LAST command), which is exactly how the first run went green while + # silently creating no issue. + set -eu TITLE="Infrastructure update audit" - BODY=$$(cat /tmp/update-audit.md) STAMP=$$(date -u +%Y-%m-%dT%H:%M:%SZ) API="https://gitea.renner.uno/api/v1/repos/gitea_admin/homelab" + + # write -> prints HTTP code, fails non-2xx + gitea_write() { + code=$$(curl -s -o /tmp/gitea-resp.json -w '%{http_code}' \ + -X "$$1" -H "Authorization: token $$GITEA_TOKEN" \ + -H "Content-Type: application/json" --data @"$$3" "$$2") + echo "$$1 $$2 -> HTTP $$code" + if [ "$$code" -lt 200 ] || [ "$$code" -ge 300 ]; then + echo "Gitea API error body:"; cat /tmp/gitea-resp.json; echo + return 1 + fi + } + ISSUE=$$(curl -sf -H "Authorization: token $$GITEA_TOKEN" \ "$$API/issues?state=open&type=issues&limit=50" \ | jq -r --arg t "$$TITLE" 'map(select(.title == $$t)) | .[0].number // empty') + if [ -n "$$ISSUE" ]; then echo "Updating existing issue #$$ISSUE" - jq -n --arg body "$$BODY" '{body: $$body}' \ - | curl -sf -X PATCH -H "Authorization: token $$GITEA_TOKEN" \ - -H "Content-Type: application/json" --data @- \ - "$$API/issues/$$ISSUE" | jq '{number, html_url}' - jq -n --arg body "🔄 Re-ran $$STAMP — report above refreshed." '{body: $$body}' \ - | curl -sf -X POST -H "Authorization: token $$GITEA_TOKEN" \ - -H "Content-Type: application/json" --data @- \ - "$$API/issues/$$ISSUE/comments" > /dev/null + jq -n --arg body "$$(cat /tmp/update-audit.md)" '{body: $$body}' > /tmp/gitea-patch.json + gitea_write PATCH "$$API/issues/$$ISSUE" /tmp/gitea-patch.json + jq '{number, html_url}' /tmp/gitea-resp.json + jq -n --arg body "🔄 Re-ran $$STAMP — report above refreshed." '{body: $$body}' > /tmp/gitea-comment.json + gitea_write POST "$$API/issues/$$ISSUE/comments" /tmp/gitea-comment.json else echo "Creating new audit issue" - jq -n --arg title "$$TITLE" --arg body "$$BODY" \ - '{title: $$title, body: $$body}' \ - | curl -sf -X POST -H "Authorization: token $$GITEA_TOKEN" \ - -H "Content-Type: application/json" --data @- \ - "$$API/issues" | jq '{number, html_url, title}' + jq -n --arg title "$$TITLE" --arg body "$$(cat /tmp/update-audit.md)" \ + '{title: $$title, body: $$body}' > /tmp/gitea-create.json + gitea_write POST "$$API/issues" /tmp/gitea-create.json + jq '{number, html_url, title}' /tmp/gitea-resp.json fi -- 2.54.0