diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..bb17849 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,109 @@ +name: Release + +on: + push: + tags: + - "v*" + +jobs: + build: + name: Build distributions + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + python-version: "3.13" + enable-cache: true + + - name: Check tag matches project version + run: | + uv run --no-project python - <<'PY' + import os + import re + import tomllib + from pathlib import Path + + tag = os.environ.get('GITHUB_REF_NAME', '') + tag_version = tag[1:] if tag.startswith('v') else tag + + pyproject = tomllib.loads(Path('pyproject.toml').read_text(encoding='utf-8')) + project_version = pyproject['project']['version'] + + init_version = None + init_path = Path('src') / 'takopi' / '__init__.py' + if init_path.is_file(): + m = re.search(r'__version__\s*=\s*"([^"]+)"', init_path.read_text(encoding='utf-8')) + if m: + init_version = m.group(1) + + if project_version != tag_version: + raise SystemExit(f"Tag {tag!r} does not match pyproject version {project_version!r}") + if init_version and init_version != project_version: + raise SystemExit( + f"src/takopi/__init__.py __version__ {init_version!r} does not match pyproject version {project_version!r}" + ) + + print(f"OK: tag {tag!r} matches version {project_version!r}") + PY + + - name: Run tests + run: uv run pytest + + - name: Build (wheel + sdist) + run: uv build + + - name: Upload dist artifacts + uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ + if-no-files-found: error + + publish: + name: Publish to PyPI (trusted publishing) + needs: build + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/takopi + permissions: + contents: read + id-token: write + steps: + - name: Download dist artifacts + uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ + + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist/ + skip-existing: true + + github-release: + name: Create GitHub Release + needs: publish + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Download dist artifacts + uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ + + - name: Create GitHub release and upload artifacts + uses: softprops/action-gh-release@v2 + with: + generate_release_notes: true + files: | + dist/*