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" DEBUG="/tmp/release-debug.log" : > "$DEBUG" debug() { echo "[$(date '+%H:%M:%S')] $*" >> "$DEBUG"; } debug "=== RELEASE WORKFLOW START ===" debug "VERSION=${VERSION}" debug "PWD=$(pwd)" debug "LOCAL=${LOCAL}" debug "git -C ${LOCAL} tag list:" git -C "$LOCAL" tag --sort=-creatordate >> "$DEBUG" 2>&1 debug "git -C ${LOCAL} log -1:" git -C "$LOCAL" log --oneline -1 >> "$DEBUG" 2>&1 # Generate changelog to a temp file PREV_TAG="$(git -C "$LOCAL" tag --sort=-creatordate | head -2 | tail -1 || echo '')" debug "PREV_TAG=${PREV_TAG}" if [ -n "$PREV_TAG" ] && [ "$PREV_TAG" != "$VERSION" ]; then RANGE="${PREV_TAG}..${VERSION}" debug "RANGE=${RANGE}" git -C "$LOCAL" log --oneline --no-decorate "${RANGE}" > /tmp/changelog.txt 2>>"$DEBUG" else debug "First tag or same tag, using ${VERSION}" git -C "$LOCAL" log --oneline --no-decorate "${VERSION}" > /tmp/changelog.txt 2>>"$DEBUG" fi NOTES="$(cat /tmp/changelog.txt)" debug "NOTES length: ${#NOTES}" debug "NOTES first 200 chars: ${NOTES:0:200}" # 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" 2>>"$DEBUG" cd "$SRC" if [ -f /var/www/atom-nexst/.env ]; then cp /var/www/atom-nexst/.env "$SRC/.env" fi pnpm install --frozen-lockfile 2>>"$DEBUG" pnpm prisma:generate 2>>"$DEBUG" export SKIP_ENV_VALIDATION=1 pnpm build 2>>"$DEBUG" # Create release via API debug "Creating release..." python3 /dev/stdin << 'PYEOF' 2>>"$DEBUG" import json, os version = os.environ["VERSION"] api = os.environ["GITEA_API"] repo = os.environ["GITEA_REPO"] token = "${{ secrets.GITEA_TOKEN }}" with open("/tmp/changelog.txt") as f: notes_raw = f.read().strip() print(f"Read {len(notes_raw)} chars from /tmp/changelog.txt") print(f"Token set: {bool(token)}") print(f"API URL: {api}") if not notes_raw: notes_raw = "Initial release" 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") import urllib.request, urllib.error def api_call(method, path, data=None): url = f"{api}/repos/{repo}/{path}" print(f"{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"Created: {result.get('html_url', result.get('id', '?'))}") except urllib.error.HTTPError as e: err = e.read().decode("utf-8") print(f"POST {e.code}: {err}") 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"Updated: {result.get('html_url', result.get('id', '?'))}") break else: raise else: raise PYEOF debug "=== RELEASE WORKFLOW END ===" echo "Debug log: $DEBUG"