ci(release): push tag to Codeberg before creating the release
All checks were successful
Release — F-Droid repo + Gitea/Codeberg release / detect (push) Successful in 6s
Release — F-Droid repo + Gitea/Codeberg release / release (push) Has been skipped

The first fix didn't help: the pipeline creates the tag via the Gitea
API, and the push mirror (sync_on_commit only fires on real git pushes)
doesn't propagate an API-created tag promptly. So the Codeberg release
POST still raced the mirror and 500'd on a commit/tag Codeberg hadn't
received (0.2.1 and 0.3.0 both shipped everywhere but Codeberg).

Push the tag straight to Codeberg from the runner (guaranteed present),
then attach the release to that existing tag with no target_commitish —
which is what Forgejo 500s on. Race-free.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-19 22:48:29 +02:00
parent a9843e25b7
commit 4aa65edb45

View File

@@ -399,27 +399,27 @@ jobs:
sed -i -e '/./,$!d' release-notes.md sed -i -e '/./,$!d' release-notes.md
fi fi
[ -s release-notes.md ] || echo "_See CHANGELOG.md for ${VERSION}._" > release-notes.md [ -s release-notes.md ] || echo "_See CHANGELOG.md for ${VERSION}._" > release-notes.md
# The push mirror (sync_on_commit) usually syncs the tag to Codeberg # The pipeline creates the tag via the Gitea API, which the push mirror
# before this step runs. Forgejo 500s on POST /releases with a # (sync_on_commit only fires on real git pushes) doesn't propagate
# target_commitish when the tag already exists — so only pass # promptly — so a release POST that carries a target_commitish can
# target_commitish when we actually need the API to create the tag. # outrun the mirror and 500 on a commit/tag Codeberg hasn't received.
TAG_CODE=$(curl -s -o /dev/null -w '%{http_code}' \ # Push the tag straight to Codeberg so it's guaranteed present, then
-H "Authorization: token $TOKEN" "$API/git/refs/tags/$TAG") # attach the release to that existing tag with NO target_commitish
python3 - "$TAG" "$SHA" "$PRERELEASE" "$TAG_CODE" <<'PY' > cb-payload.json # (which is what triggered the 500).
git tag -f "$TAG" "$SHA"
git push -f "https://jlmakiola:${TOKEN}@codeberg.org/jlmakiola/agendula.git" \
"refs/tags/$TAG"
python3 - "$TAG" "$PRERELEASE" <<'PY' > cb-payload.json
import json, sys import json, sys
tag, sha, pre, tag_code = sys.argv[1:5] tag, pre = sys.argv[1:3]
payload = { print(json.dumps({
"tag_name": tag, "tag_name": tag,
"name": tag, "name": tag,
"body": open("release-notes.md").read(), "body": open("release-notes.md").read(),
"draft": False, "draft": False,
# Pre-1.0 releases are flagged as pre-releases (see detect job). # Pre-1.0 releases are flagged as pre-releases (see detect job).
"prerelease": pre == "true", "prerelease": pre == "true",
} }))
# Only create the tag via the release when it isn't mirrored yet.
if tag_code != "200":
payload["target_commitish"] = sha
print(json.dumps(payload))
PY PY
# Upsert (re-run safe). # Upsert (re-run safe).
ID=$(curl -s -H "Authorization: token $TOKEN" "$API/releases/tags/$TAG" | jq -r '.id // empty') ID=$(curl -s -H "Authorization: token $TOKEN" "$API/releases/tags/$TAG" | jq -r '.id // empty')