From 15ed8ffbf0a59b54a18a4747da205581e7766479 Mon Sep 17 00:00:00 2001 From: openhands Date: Mon, 20 Jul 2026 15:11:59 +0200 Subject: [PATCH] fix: generate release changelog from full local repo Shallow clone (depth 1) only has one commit, so git log was empty. Now generates changelog from the bare repo before cloning, and uses Python to build the JSON payload for proper multiline escaping. --- .gitea/workflows/release.yaml | 92 +++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml index e0e9f612..dcfee137 100644 --- a/.gitea/workflows/release.yaml +++ b/.gitea/workflows/release.yaml @@ -15,28 +15,27 @@ jobs: run: | set -e - # ── Checkout ──────────────────────────────────────────────── - SRC="/tmp/epicnext-release" - rm -rf "$SRC" - git clone --branch "${VERSION}" --depth 1 \ - /docker/gitea/gitea/git/repositories/remco/epicnext-cms.git \ - "$SRC" - cd "$SRC" + REPO="/docker/gitea/gitea/git/repositories/remco/epicnext-cms.git" - # ── Generate Release Notes ─────────────────────────────────── - PREV_TAG="$(git tag --sort=-creatordate | head -2 | tail -1 || echo '')" + # ── Generate changelog ──────────────────────────────────────── + PREV_TAG="$(git -C "$REPO" tag --sort=-creatordate | head -2 | tail -1 || echo '')" if [ -n "$PREV_TAG" ]; then RANGE="${PREV_TAG}..${VERSION}" - NOTES="$(git log --oneline --no-decorate "${RANGE}" 2>/dev/null || git log --oneline --no-decorate -20)" + git -C "$REPO" log --oneline --no-decorate "${RANGE}" > /tmp/changelog.txt 2>/dev/null || \ + git -C "$REPO" log --oneline --no-decorate -30 > /tmp/changelog.txt else - NOTES="$(git log --oneline --no-decorate -30)" + git -C "$REPO" log --oneline --no-decorate -30 > /tmp/changelog.txt fi - echo "=== Release Notes ===" - echo "$NOTES" + echo "=== Changelog ===" + cat /tmp/changelog.txt + + # ── Build ───────────────────────────────────────────────────── + SRC="/tmp/epicnext-release" + rm -rf "$SRC" + git clone --branch "${VERSION}" --depth 1 "$REPO" "$SRC" + cd "$SRC" - # ── Build ──────────────────────────────────────────────────── - # Copy env for Prisma client generation and build if [ -f /var/www/atom-nexst/.env ]; then cp /var/www/atom-nexst/.env "$SRC/.env" fi @@ -45,28 +44,49 @@ jobs: export SKIP_ENV_VALIDATION=1 pnpm build - # ── Create Gitea Release ───────────────────────────────────── - BODY="## EpicNext-CMS ${VERSION} + # ── Create release (Python handles JSON properly) ───────────── + python3 << 'PYEOF' +import json, os, urllib.request - ### Changes - ${NOTES} +version = os.environ['VERSION'] +api = os.environ['GITEA_API'] +repo = os.environ['GITEA_REPO'] +token = "${{ secrets.GITEA_TOKEN }}" - --- - _Automated release from Gitea Actions_ - " +with open('/tmp/changelog.txt') as f: + notes = f.read() - curl -s -X POST "${GITEA_API}/repos/${GITEA_REPO}/releases" \ - -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ - -H "Content-Type: application/json" \ - -d "$(cat <<-ENDJSON - { - "tag_name": "${VERSION}", - "name": "${VERSION}", - "body": $(echo "$BODY" | jq -Rs '.'), - "draft": false, - "prerelease": false - } - ENDJSON - )" +body = f"""## EpicNext-CMS {version} - echo "Release ${VERSION} created successfully!" +### Changes +{notes} +--- +*Automated release from Gitea Actions* +""" + +payload = json.dumps({ + 'tag_name': version, + 'name': version, + 'body': body, + 'draft': False, + 'prerelease': False, +}).encode('utf-8') + +req = urllib.request.Request( + f'{api}/repos/{repo}/releases', + data=payload, + headers={ + 'Authorization': f'token {token}', + 'Content-Type': 'application/json', + }, + method='POST', +) + +try: + resp = urllib.request.urlopen(req) + result = json.loads(resp.read().decode('utf-8')) + print(f"Release created: {result.get('html_url', result.get('id', '?'))}") +except urllib.error.HTTPError as e: + print(f"API error {e.code}: {e.read().decode('utf-8')}") + raise +PYEOF