Files
EpicNext-Cms/.gitea/workflows/release.yaml
T
Workflow config file is invalid. Please check your config file: go-yaml load error in scanner (while scanning a simple key) at L38.C1-L40.C1: could not find expected ':'
openhands 57ef6289ff
Local Build and Deploy / deploy (push) Successful in 1m26s
fix: generate changelog via Python subprocess for reliability
Previous approaches using temp files or env vars failed in Gitea runner.
Python now runs git commands directly via subprocess, reads stdout,
and builds the JSON payload — no intermediate files or shell escaping.
2026-07-20 15:21:12 +02:00

129 lines
3.5 KiB
YAML

name: Create Release
on:
push:
tags:
- "v*"
jobs:
release:
runs-on: shell
steps:
- name: Build & release
env:
VERSION: ${{ gitea.ref_name }}
GITEA_API: ${{ gitea.api_url }}
GITEA_REPO: ${{ gitea.repository }}
run: |
set -e
LOCAL="/var/www/atom-nexst"
# Shallow clone for build
SRC="/tmp/epicnext-release"
rm -rf "$SRC"
git clone --branch "${VERSION}" --depth 1 \
/docker/gitea/gitea/git/repositories/remco/epicnext-cms.git \
"$SRC"
if [ -f /var/www/atom-nexst/.env ]; then
cp /var/www/atom-nexst/.env "$SRC/.env"
fi
cd "$SRC"
pnpm install --frozen-lockfile
pnpm prisma:generate
export SKIP_ENV_VALIDATION=1
pnpm build
# Create release — Python reads changelog directly from git
python3 << 'PYEOF'
import json, os, subprocess, urllib.request, urllib.error
version = os.environ["VERSION"]
api = os.environ["GITEA_API"]
repo = os.environ["GITEA_REPO"]
token = "${{ secrets.GITEA_TOKEN }}"
local = "/var/www/atom-nexst"
# Get previous tag
tags = subprocess.run(
["git", "-C", local, "tag", "--sort=-creatordate"],
capture_output=True, text=True, check=False,
).stdout.strip().split("\n")
tags = [t for t in tags if t]
prev_tag = tags[1] if len(tags) > 1 else ""
print(f"Tags: {tags}")
print(f"Version: {version}, Previous: {prev_tag}")
if prev_tag and prev_tag != version:
r = subprocess.run(
["git", "-C", local, "log", "--oneline", "--no-decorate", f"{prev_tag}..{version}"],
capture_output=True, text=True, check=False,
)
notes_raw = r.stdout.strip()
print(f"Range: {prev_tag}..{version}, stderr: {r.stderr.strip()}")
else:
r = subprocess.run(
["git", "-C", local, "log", "--oneline", "--no-decorate", version],
capture_output=True, text=True, check=False,
)
notes_raw = r.stdout.strip()
print(f"Single tag {version}, stderr: {r.stderr.strip()}")
if not notes_raw:
notes_raw = "Initial release"
print(f"Notes ({len(notes_raw)} chars):")
print(notes_raw)
print("=== End notes ===")
body = f"""## EpicNext-CMS {version}
### Changes
{notes_raw}
---
*Automated release from Gitea Actions*
"""
payload = json.dumps({
"tag_name": version,
"name": version,
"body": body,
"draft": False,
"prerelease": False,
}).encode("utf-8")
def api_call(method, path, data=None):
url = f"{api}/repos/{repo}/{path}"
print(f"API {method} {url}")
req = urllib.request.Request(
url, data=data,
headers={
"Authorization": f"token {token}",
"Content-Type": "application/json",
},
method=method,
)
resp = urllib.request.urlopen(req)
return json.loads(resp.read().decode("utf-8"))
try:
result = api_call("POST", "releases", payload)
print(f"Release created: {result.get('html_url', result.get('id', '?'))}")
except urllib.error.HTTPError as e:
err_body = e.read().decode("utf-8")
print(f"POST error {e.code}: {err_body}")
if e.code == 409:
releases = api_call("GET", "releases")
for rel in releases:
if rel["tag_name"] == version:
result = api_call("PATCH", f"releases/{rel['id']}", payload)
print(f"Release updated: {result.get('html_url', result.get('id', '?'))}")
break
else:
print(f"ERROR: no existing release found for {version}")
raise
else:
raise
PYEOF