name: release run-name: Release on push to main # Builds a wheel + sdist and publishes a Gitea release v on every push to # main. The version comes from pyproject.toml (kept in lockstep with __version__, D19); # if a release for that tag already exists, the job is a no-op — so bump the version # (and CHANGELOG) to cut a new release. on: push: branches: [main] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install (core only) run: python -m pip install -e . - name: Run tests run: python -m unittest discover -s tests -v release: needs: test # don't publish a release if the tests fail runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.12" - name: Build wheel + sdist run: | python -m pip install --upgrade build python -m build - name: Build self-extracting installer (.run) run: python packaging/make_run.py - name: Read version id: ver run: | V=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])") echo "version=$V" >> "$GITHUB_OUTPUT" - name: Build release notes run: | python - <<'PY' import json version = "${{ steps.ver.outputs.version }}" tag = f"v{version}" out, capturing = [], False try: for line in open("CHANGELOG.md", encoding="utf-8").read().splitlines(): if line.startswith("## "): if capturing: break capturing = line.startswith(f"## [{version}]") continue if capturing: out.append(line) except OSError: pass body = "\n".join(out).strip() or f"Release {tag}." payload = {"tag_name": tag, "target_commitish": "${{ github.sha }}", "name": tag, "body": body} open("/tmp/release.json", "w", encoding="utf-8").write(json.dumps(payload)) print(f"release notes: {len(body)} chars") PY - name: Publish Gitea release env: TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -euo pipefail API="${{ github.server_url }}/api/v1/repos/${{ github.repository }}" TAG="v${{ steps.ver.outputs.version }}" code=$(curl -sS -o /tmp/existing.json -w '%{http_code}' \ -H "Authorization: token ${TOKEN}" "${API}/releases/tags/${TAG}") if [ "$code" = "200" ]; then echo "Release ${TAG} already exists — nothing to do." exit 0 fi echo "Creating release ${TAG}…" rid=$(curl -sS -X POST \ -H "Authorization: token ${TOKEN}" \ -H "Content-Type: application/json" \ -d @/tmp/release.json \ "${API}/releases" | python -c "import sys, json; print(json.load(sys.stdin)['id'])") for f in dist/*; do echo "Uploading $(basename "$f")…" curl -sS -X POST \ -H "Authorization: token ${TOKEN}" \ -F "attachment=@${f}" \ "${API}/releases/${rid}/assets?name=$(basename "$f")" >/dev/null done echo "Published ${TAG}."