saal 0.1.2

Wrappers for the Standardized Astrodynamics Algorithms Library (SAAL)
name: Release

on:
  push:
    tags:
      - 'v*.*.*'

env:
  PYTHON_VERSION: '3.10'

jobs:
  build-wheels:
    name: Build wheels (${{ matrix.name }})
    runs-on: ${{ matrix.runner }}
    permissions:
      contents: read
    defaults:
      run:
        shell: bash
    strategy:
      fail-fast: false
      matrix:
        include:
          - name: linux-x86_64-gnu
            runner: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            manylinux: 2_24
            container: ''
          - name: linux-aarch64-gnu
            runner: ubuntu-24.04-arm
            target: aarch64-unknown-linux-gnu
            manylinux: 2_24
            container: quay.io/pypa/manylinux_2_24_aarch64
          - name: macos-x86_64
            runner: macos-15-intel
            target: x86_64-apple-darwin
          - name: macos-aarch64
            runner: macos-latest
            target: aarch64-apple-darwin
          - name: windows-x86_64
            runner: windows-latest
            target: x86_64-pc-windows-msvc

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Validate tag
        run: |
          tag="${GITHUB_REF_NAME}"
          if ! [[ "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
            echo "Tag $tag does not match v.x.y.z"
            exit 1
          fi
          echo "VERSION=${tag#v}" >> "$GITHUB_ENV"

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Build wheel (linux)
        if: ${{ startsWith(matrix.name, 'linux-') }}
        uses: PyO3/maturin-action@v1
        with:
          target: ${{ matrix.target }}
          manylinux: ${{ matrix.manylinux }}
          container: ${{ matrix.container }}
          args: --release

      - name: Build wheel
        if: ${{ !startsWith(matrix.name, 'linux-') }}
        run: |
          python -m pip install --upgrade pip maturin
          maturin build --release --target ${{ matrix.target }}

      - name: Upload wheels
        uses: actions/upload-artifact@v4
        with:
          name: pypi-${{ matrix.name }}
          path: target/wheels/*.whl

  build-sdist:
    name: Build sdist
    runs-on: ubuntu-latest
    permissions:
      contents: read
    defaults:
      run:
        shell: bash
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Validate tag
        run: |
          tag="${GITHUB_REF_NAME}"
          if ! [[ "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
            echo "Tag $tag does not match v.x.y.z"
            exit 1
          fi
          echo "VERSION=${tag#v}" >> "$GITHUB_ENV"

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Build sdist
        run: |
          python -m pip install --upgrade pip maturin
          maturin build --release --sdist

      - name: Upload sdist
        uses: actions/upload-artifact@v4
        with:
          name: pypi-sdist
          path: target/wheels/*.tar.gz

  publish-pypi:
    name: Publish to PyPI
    runs-on: ubuntu-latest
    needs:
      - build-wheels
      - build-sdist
    permissions:
      contents: read
      id-token: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Validate PyPI version matches tag
        run: |
          tag="${GITHUB_REF_NAME}"
          if ! [[ "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
            echo "Tag $tag does not match v.x.y.z"
            exit 1
          fi
          version="${tag#v}"
          py_version="$(awk -F' = ' '
            $0=="[project]"{in_project=1;next}
            /^\[/{if(in_project)exit}
            in_project && $1=="version"{gsub(/"/,"",$2);print $2;exit}
          ' pyproject.toml)"
          if [ -z "$py_version" ]; then
            echo "version not found in pyproject.toml"
            exit 1
          fi
          if [ "$py_version" != "$version" ]; then
            echo "pyproject.toml version $py_version does not match tag $version"
            exit 1
          fi

      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          pattern: pypi-*
          path: dist
          merge-multiple: true

      - name: Publish via Trusted Publisher
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          packages-dir: dist
          skip-existing: true

  create-github-release:
    name: Create GitHub release
    runs-on: ubuntu-latest
    needs:
      - build-wheels
      - build-sdist
    permissions:
      contents: write
    steps:
      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          pattern: pypi-*
          path: dist
          merge-multiple: true

      - name: Create release
        uses: softprops/action-gh-release@v2
        with:
          files: dist/*
          generate_release_notes: true

  publish-crates:
    name: Publish to crates.io
    runs-on: ubuntu-latest
    permissions:
      contents: read
    defaults:
      run:
        shell: bash
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Validate tag and Cargo version
        run: |
          tag="${GITHUB_REF_NAME}"
          if ! [[ "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
            echo "Tag $tag does not match v.x.y.z"
            exit 1
          fi
          version="${tag#v}"
          cargo_version="$(awk -F' = ' '
            $0=="[package]"{in_pkg=1;next}
            /^\[/{if(in_pkg)exit}
            in_pkg && $1=="version"{gsub(/"/,"",$2);print $2;exit}
          ' Cargo.toml)"
          if [ -z "$cargo_version" ]; then
            echo "version not found in Cargo.toml [package]"
            exit 1
          fi
          if [ "$cargo_version" != "$version" ]; then
            echo "Cargo.toml version $cargo_version does not match tag $version"
            exit 1
          fi
          echo "VERSION=$version" >> "$GITHUB_ENV"

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Publish to crates.io
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: cargo publish --locked