name: Create Gitea Release on: push: tags: - "v*" jobs: release: runs-on: ubuntu-latest steps: - name: Check out repository uses: actions/checkout@v4 - name: Prepare release metadata shell: bash run: | TAG="${GITHUB_REF_NAME:-${GITHUB_REF##refs/tags/}}" VERSION="${TAG#v}" echo "TAG=$TAG" >> "$GITHUB_ENV" echo "VERSION=$VERSION" >> "$GITHUB_ENV" if [[ "$TAG" == *-* ]]; then echo "PRERELEASE=true" >> "$GITHUB_ENV" else echo "PRERELEASE=false" >> "$GITHUB_ENV" fi - name: Extract matching CHANGELOG section shell: bash run: | python <<'PY' import os import re from pathlib import Path version = os.environ["VERSION"] changelog_path = Path("CHANGELOG.md") if not changelog_path.exists(): body = f"# {version}\n\nNo CHANGELOG.md found." Path("release_body.md").write_text(body, encoding="utf-8") raise SystemExit(0) text = changelog_path.read_text(encoding="utf-8") # Matches headings like: # ## 1.2.3 # ## 1.2.3-alpha.0 # ## [1.2.3] pattern = re.compile( rf"^##\s+\[?{re.escape(version)}\]?(?:\s*-.*)?\n(.*?)(?=^##\s|\Z)", re.MULTILINE | re.DOTALL, ) match = pattern.search(text) if match: body = match.group(1).strip() else: body = text.strip() if not body: body = f"Release {version}" Path("release_body.md").write_text(body + "\n", encoding="utf-8") PY - name: Create Gitea release env: RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} GITEA_SERVER_URL: ${{ gitea.server_url }} GITEA_REPOSITORY: ${{ gitea.repository }} shell: bash run: | python <<'PY' import json import os import urllib.request tag = os.environ["TAG"] prerelease = os.environ["PRERELEASE"].lower() == "true" server_url = os.environ["GITEA_SERVER_URL"].rstrip("/") repo = os.environ["GITEA_REPOSITORY"] token = os.environ["RELEASE_TOKEN"] with open("release_body.md", "r", encoding="utf-8") as f: body = f.read() url = f"{server_url}/api/v1/repos/{repo}/releases" payload = { "tag_name": tag, "name": tag, "body": body, "draft": False, "prerelease": prerelease, } data = json.dumps(payload).encode("utf-8") req = urllib.request.Request( url, data=data, method="POST", headers={ "Authorization": f"token {token}", "Content-Type": "application/json", "Accept": "application/json", }, ) try: with urllib.request.urlopen(req) as resp: print(resp.read().decode("utf-8")) except urllib.error.HTTPError as e: details = e.read().decode("utf-8", errors="replace") print(details) raise PY