fix: use curl+jq instead of Python for release creation
Local Build and Deploy / deploy (push) Successful in 1m27s

Eliminates potential Python/heredoc issues in Gitea Actions runner.
Full clone guarantees git history is available for changelog.
This commit is contained in:
openhands committed 2026-07-20 15:29:54 +02:00
1 parent 8badcd9c92
commit 26da114e0e
1 file changed
+45 -66
+45 -66
View File
@@ -14,28 +14,28 @@ jobs:
GITEA_REPO: ${{ gitea.repository }} GITEA_REPO: ${{ gitea.repository }}
run: | run: |
set -e set -e
exec 2>&1
echo "=== VERSION=${VERSION} ==="
echo "=== API=${GITEA_API} ==="
echo "=== REPO=${GITEA_REPO} ==="
SRC="/tmp/epicnext-release" SRC="/tmp/epicnext-release"
rm -rf "$SRC" rm -rf "$SRC"
# Full clone for changelog + build (local bare repo = instant)
git clone --branch "${VERSION}" \ git clone --branch "${VERSION}" \
/docker/gitea/gitea/git/repositories/remco/epicnext-cms.git \ /docker/gitea/gitea/git/repositories/remco/epicnext-cms.git \
"$SRC" "$SRC" 2>&1
cd "$SRC" cd "$SRC"
echo "=== Cloned ==="
# Generate changelog
PREV_TAG="$(git tag --sort=-creatordate | head -2 | tail -1 || echo '')" PREV_TAG="$(git tag --sort=-creatordate | head -2 | tail -1 || echo '')"
echo "=== Tags ===" echo "=== Tags ==="
git tag --sort=-creatordate git tag --sort=-creatordate
echo "=== Version=${VERSION} Previous=${PREV_TAG} ===" echo "=== Previous=${PREV_TAG} ==="
if [ -n "$PREV_TAG" ] && [ "$PREV_TAG" != "$VERSION" ]; then if [ -n "$PREV_TAG" ] && [ "$PREV_TAG" != "$VERSION" ]; then
RANGE="${PREV_TAG}..${VERSION}" git log --oneline --no-decorate "${PREV_TAG}..${VERSION}" > /tmp/changelog.txt
echo "=== Range: ${RANGE} ==="
git log --oneline --no-decorate "${RANGE}" > /tmp/changelog.txt
else else
echo "=== First release, showing all commits ==="
git log --oneline --no-decorate "${VERSION}" > /tmp/changelog.txt git log --oneline --no-decorate "${VERSION}" > /tmp/changelog.txt
fi fi
@@ -43,74 +43,53 @@ jobs:
cat /tmp/changelog.txt cat /tmp/changelog.txt
echo "=== End ===" echo "=== End ==="
# Build
if [ -f /var/www/atom-nexst/.env ]; then if [ -f /var/www/atom-nexst/.env ]; then
cp /var/www/atom-nexst/.env "$SRC/.env" cp /var/www/atom-nexst/.env "$SRC/.env"
fi fi
pnpm install --frozen-lockfile pnpm install --frozen-lockfile 2>&1
pnpm prisma:generate pnpm prisma:generate 2>&1
export SKIP_ENV_VALIDATION=1 export SKIP_ENV_VALIDATION=1
pnpm build pnpm build 2>&1
# Create release via API echo "=== Creating release ==="
python3 << 'PYEOF' NOTES="$(cat /tmp/changelog.txt)"
import json, os, urllib.request, urllib.error [ -z "$NOTES" ] && NOTES="Initial release"
version = os.environ["VERSION"] # Build JSON with jq, send with curl
api = os.environ["GITEA_API"] BODY="## EpicNext-CMS ${VERSION}
repo = os.environ["GITEA_REPO"]
token = "${{ secrets.GITEA_TOKEN }}"
with open("/tmp/changelog.txt") as f:
notes = f.read().strip() or "Initial release"
print(f"Changelog: {len(notes)} chars")
body = f"""## EpicNext-CMS {version}
### Changes ### Changes
{notes} ${NOTES}
--- ---
*Automated release from Gitea Actions* *Automated release from Gitea Actions*
""" "
payload = json.dumps({ PAYLOAD="$(echo "$BODY" | jq -Rs '{tag_name: $v, name: $v, body: ., draft: false, prerelease: false}' --arg v "${VERSION}")"
"tag_name": version, echo "Payload length: ${#PAYLOAD}"
"name": version,
"body": body,
"draft": False,
"prerelease": False,
}).encode("utf-8")
def api_call(method, path, data=None): RESP="$(curl -s -w '\n%{http_code}' -X POST \
url = f"{api}/repos/{repo}/{path}" "${GITEA_API}/repos/${GITEA_REPO}/releases" \
print(f"{method} {url}") -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \
req = urllib.request.Request( -H "Content-Type: application/json" \
url, data=data, -d "$PAYLOAD")"
headers={ HTTP_CODE="$(echo "$RESP" | tail -1)"
"Authorization": f"token {token}", RESP_BODY="$(echo "$RESP" | head -n -1)"
"Content-Type": "application/json", echo "HTTP ${HTTP_CODE}: ${RESP_BODY:0:200}"
},
method=method,
)
resp = urllib.request.urlopen(req)
return json.loads(resp.read().decode("utf-8"))
try: if [ "$HTTP_CODE" = "409" ] || [ "$HTTP_CODE" = "409" ]; then
result = api_call("POST", "releases", payload) # Release exists — update it
print(f"OK: {result.get('html_url', result.get('id', '?'))}") RELEASES="$(curl -sf "${GITEA_API}/repos/${GITEA_REPO}/releases" \
except urllib.error.HTTPError as e: -H "Authorization: token ${{ secrets.GITEA_TOKEN }}")"
err_body = e.read().decode("utf-8") REL_ID="$(echo "$RELEASES" | jq -r ".[] | select(.tag_name==\"${VERSION}\") | .id")"
print(f"POST {e.code}") if [ -n "$REL_ID" ] && [ "$REL_ID" != "null" ]; then
if e.code == 409: RESP2="$(curl -s -w '\n%{http_code}' -X PATCH \
releases = api_call("GET", "releases") "${GITEA_API}/repos/${GITEA_REPO}/releases/${REL_ID}" \
for rel in releases: -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \
if rel["tag_name"] == version: -H "Content-Type: application/json" \
result = api_call("PATCH", f"releases/{rel['id']}", payload) -d "$PAYLOAD")"
print(f"Updated: {result.get('html_url', result.get('id', '?'))}") echo "PATCH result: $(echo "$RESP2" | tail -1)"
break fi
else: fi
print(f"API ERROR: {err_body}")
raise echo "=== Done ==="
PYEOF