The flow is now: a vX.Y.Z tag starts the pipeline, the pipeline creates the release with the Linux and Windows packages in it, and the macOS package is pushed on top from a Mac with make release. scripts/ci-upload.sh therefore creates the release when the tag has none, taking its body from RELEASE_NOTES.md, instead of requiring one to exist. Also carries a one-off diagnostic in the check step: whether Woodpecker hands steps a forge credential of their own. If it does, the release step needs no secret. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>