The macOS and Linux release scripts called the Gitea API with
`curl -sf`, which discards the response on failure. A rejected token
surfaced only as a JSON decode error from the release id lookup.
- Route API calls through gitea_api, which keeps the HTTP status and
the response body
- On failure print the status and Gitea's message, with a hint about
the token scope on 401/403, and exit
- Look up the release first and create it only on 404 instead of
ignoring every creation error
- Check the status of each asset upload