name: Release and Publish

on:
  push:
    branches:
      - master
  workflow_dispatch:

jobs:
  release:
    name: Create Release and Publish to PyPI
    runs-on: ubuntu-latest

    steps:
      - name: Check out repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0  # ensure full history & tags

      - name: Fetch tags
        run: |
          git fetch --tags --force

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: "3.12"

      - name: Install tooling (packaging)
        run: |
          python -m pip install --upgrade pip
          pip install packaging

      # 1) Extract the new version from pyproject.toml
      - name: Extract version from pyproject.toml
        id: get_version
        shell: bash
        run: |
          python - << 'PY' > version.txt
          import tomllib
          from pathlib import Path

          data = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8"))
          version = data["project"]["version"]
          print(version)
          PY
          version="$(cat version.txt)"
          echo "New version from pyproject.toml: $version"
          echo "version=$version" >> "$GITHUB_OUTPUT"

      # 2) Get the previous tag in format "x.x.x"
      - name: Get previous semantic tag
        id: get_prev_tag
        shell: bash
        run: |
          # Look for tags that look like x.x.x (no leading "v")
          prev_tag="$(git tag --list '[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname | head -n 1 || true)"

          if [ -z "$prev_tag" ]; then
            echo "No previous semantic tag found (x.x.x). Exiting workflow."
            exit 1
          else
            echo "Found previous tag: $prev_tag"
            echo "previous_tag=$prev_tag" >> "$GITHUB_OUTPUT"
            echo "previous_version=$prev_tag" >> "$GITHUB_OUTPUT"
          fi

      # 3) Ensure the new version is greater than the previous tag's version
      - name: Ensure new version is greater than previous
        if: steps.get_prev_tag.outputs.previous_version != ''
        env:
          NEW_VERSION: ${{ steps.get_version.outputs.version }}
          OLD_VERSION: ${{ steps.get_prev_tag.outputs.previous_version }}
        shell: python
        run: |
          import os
          import sys
          from packaging.version import Version

          new = Version(os.environ["NEW_VERSION"])
          old = Version(os.environ["OLD_VERSION"])

          print(f"Previous version: {old}")
          print(f"New version:      {new}")

          if new <= old:
            print(f"Error: new version {new} is not greater than previous {old}.")
            sys.exit(1)
          else:
            print(f"OK: new version {new} is greater than previous {old}.")

      - name: Install build dependencies
        run: |
          python -m pip install --upgrade pip
          pip install build

      - name: Build distribution
        run: |
          python -m build

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v3
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: "${{ steps.get_version.outputs.version }}"  # e.g. "1.2.3"
          name: "${{ steps.get_version.outputs.version }}"
          generate_release_notes: true
          draft: false
          prerelease: false
          files: |
            dist/*

      - name: Publish to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          password: ${{ secrets.PYPI_API_TOKEN }}
          # skip-existing: true

      - name: Configure Git for mike
        run: |
          git config user.name github-actions
          git config user.email github-actions@github.com

      - name: Fetch gh-pages branch for mike
        run: |
          git fetch origin gh-pages --depth=1 || true

      - name: Install documentation dependencies
        run: |
          pip install .[docs]

      - name: Deploy documentation with mike
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          mike deploy --push --update-aliases ${{ steps.get_version.outputs.version }} latest
          mike set-default --push latest
