name: CI on: pull_request: branches: - main push: branches: - main jobs: quality: name: Quality Checks runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Install uv run: curl -LsSf https://astral.sh/uv/install.sh | sh - name: Install Python from .python-version run: $HOME/.local/bin/uv python install - name: Sync development dependencies run: $HOME/.local/bin/uv sync --group dev - name: Run quality checks run: PATH="$HOME/.local/bin:$PATH" make ci-check tests: name: Test Suite runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Install uv run: curl -LsSf https://astral.sh/uv/install.sh | sh - name: Install Python from .python-version run: $HOME/.local/bin/uv python install - name: Sync development dependencies run: $HOME/.local/bin/uv sync --group dev - name: Run tests run: PATH="$HOME/.local/bin:$PATH" make test publish: name: Publish to Gitea Packages runs-on: ubuntu-latest needs: [quality, tests] if: github.event_name == 'push' && github.ref == 'refs/heads/main' steps: - name: Checkout code uses: actions/checkout@v4 - name: Install uv run: curl -LsSf https://astral.sh/uv/install.sh | sh - name: Install Python from .python-version run: $HOME/.local/bin/uv python install - name: Sync development dependencies run: $HOME/.local/bin/uv sync --group dev - name: Read package version from pyproject.toml id: package_meta run: | $HOME/.local/bin/uv run python - <<'PY' >> "$GITHUB_OUTPUT" import tomllib from pathlib import Path project = tomllib.loads(Path('pyproject.toml').read_text(encoding='utf-8'))['project'] print(f"name={project['name']}") print(f"version={project['version']}") PY - name: Show package version run: echo "Publishing ${{ steps.package_meta.outputs.name }} version ${{ steps.package_meta.outputs.version }}" - name: Validate package registry configuration env: PYPI_REPOSITORY_URL: ${{ secrets.PYPI_REPOSITORY_URL }} PACKAGE_USERNAME: ${{ secrets.PACKAGE_USERNAME }} PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }} run: | test -n "$PYPI_REPOSITORY_URL" || (echo "PYPI_REPOSITORY_URL secret is required" && exit 1) test -n "$PACKAGE_USERNAME" || (echo "PACKAGE_USERNAME secret is required" && exit 1) test -n "$PACKAGE_TOKEN" || (echo "PACKAGE_TOKEN secret is required" && exit 1) - name: Build distribution run: PATH="$HOME/.local/bin:$PATH" make build - name: Check built artifacts run: PATH="$HOME/.local/bin:$PATH" uv run --with twine twine check dist/* - name: Publish to Gitea PyPI registry env: TWINE_REPOSITORY_URL: ${{ secrets.PYPI_REPOSITORY_URL }} TWINE_USERNAME: ${{ secrets.PACKAGE_USERNAME }} TWINE_PASSWORD: ${{ secrets.PACKAGE_TOKEN }} run: PATH="$HOME/.local/bin:$PATH" uv run --with twine twine upload --skip-existing dist/*