The push mirror (sync_on_commit) syncs the tag to Codeberg before the publish step runs, and Forgejo returns HTTP 500 on POST /releases with a target_commitish when the tag already exists — so the release was never created (v0.2.1 shipped to Gitea/F-Droid but not Codeberg). Only pass target_commitish when the tag isn't mirrored yet; otherwise attach the release to the existing tag. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>