ci(release): show the error body, and retry the release POST #23
Reference in New Issue
Block a user
No description provided.
Delete Branch "ci/release-post-retry-and-error-body"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What happened
The release run for #22 (run 75) built everything and then failed at the last step. Steps 1–12 green, including Push the release tag; then Create Gitea release and upload assets took a
500fromPOST /releasesone second later and exited 22.That left tag
v0.1.1at9cc1099with no release and no binaries — so the handoff fix in #22 reached no operator at all, andv0.1.0stayed the current download. Found while writing runicgateway.com's installation docs, where I went to write "fixed in v0.1.1" and there was no such release.Re-running the workflow published it — same four assets, untouched, via the orphan-tag recovery the plan step already has. So the
500was a race with the tag push, not a bad request: Gitea had not finished processing the pushed tag when the POST arrived. v0.1.1 is now live.The two gaps that made it worse than it needed to be
1. The failure was unreadable.
curl -sSfprints no response body on an error status, so the entire log was:The cause had to be inferred from timestamps. Every call in this step now captures the body and prints it on failure.
2. Nothing retried, and the recovery does not fire on its own. The plan step can adopt an orphan tag — but only on a run that reaches it, and a later push with no releasable commits sets
RELEASE=falseand stands down first. In practice the tag sits there until a human notices, which is exactly what happened. The POST now retries 5 times with a 5/10/15/20s backoff.4xxis deliberately not retried — a bad token or a malformed body does not improve by being sent again, and retrying only turns a clear failure into a slow one. The give-up message names the orphan tag and says that a re-run republishes it.The asset uploads get the same treatment: a release whose
SHA256SUMSdoes not cover every binary it advertises is worse than no release, because that file is the trust anchor for an unsigned download.Verification
No Rust changed. The step's shell was extracted from the YAML and the loop run against a stubbed
curl:bash -nclean, YAML parses, and the step contains no empty${{ }}token — the trap that silently skipped three workflows for months.Two notes
Typed
ci(...)rather thanfix(...)on purpose. The plan step bumps onfeat/fixsubjects; this changes no binary, so afix(...)here would cut an empty v0.1.2 (and turn runicgateway.com'scheckFactsred for nothing). Merging this should cut no release.This file is
link'srelease.ymlretargeted, as its own header says — so the same two gaps very likely exist inlinkandservuo-plugins. Not touched here; say the word and it is a small pass across both.AI-assisted: written with Claude Code (Opus 5).
🤖 Generated with Claude Code