tempoch-py 0.2.1

Python bindings for tempoch astronomical time primitives
Documentation
name: Tempoch CI

on:
  push:
    branches: [main, master]
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

env:
  CARGO_TERM_COLOR: always
  PACKAGE_NAME: tempoch
  MATURIN_VERSION: v1.15.0

jobs:
  fmt:
    name: Format
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7.0.1
        with:
          fetch-depth: 0
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt
      - uses: actions/setup-python@v7.0.0
        with:
          python-version: "3.14"
          cache: pip
      - name: Install formatter
        run: python -m pip install --upgrade pip ruff
      - name: Check Rust formatting
        run: |
          cargo fmt --check
          cargo fmt --manifest-path tests/fixtures/downstream-extension/Cargo.toml --check
      - name: Check Python formatting
        run: python -m ruff format --check python tests examples

  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7.0.1
        with:
          fetch-depth: 0
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy
      - uses: Swatinem/rust-cache@v2
      - uses: actions/setup-python@v7.0.0
        with:
          python-version: "3.14"
          cache: pip
      - name: Install linters
        run: python -m pip install --upgrade pip ruff
      - name: Run clippy
        run: |
          cargo clippy --all-targets -- -D warnings
          cargo clippy --manifest-path tests/fixtures/downstream-extension/Cargo.toml -- -D warnings
      - name: Run ruff
        run: python -m ruff check python tests examples

  rust-test:
    name: Rust Test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7.0.1
        with:
          fetch-depth: 0
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - uses: actions/setup-python@v7.0.0
        with:
          python-version: "3.14"
      - name: Run Rust tests
        run: cargo test --all-targets

  python-test:
    name: Python Test (3.${{ matrix.python-minor }})
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python-minor: ["8", "9", "10", "11", "12", "13", "14"]
    steps:
      - uses: actions/checkout@v7.0.1
        with:
          fetch-depth: 0
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - name: Set up Python 3.${{ matrix.python-minor }}
        uses: actions/setup-python@v7.0.0
        with:
          python-version: "3.${{ matrix.python-minor }}"
          cache: pip
      - name: Install test dependencies
        run: |
          python -m pip install --upgrade pip
          python -m pip install pytest
          python -m pip install .
      - name: Run Python tests
        run: |
          tmpdir="$(mktemp -d)"
          cd "$tmpdir"
          python -m pytest --rootdir "$GITHUB_WORKSPACE" "$GITHUB_WORKSPACE/tests"

  coverage:
    name: Coverage
    if: ${{ github.event_name == 'push' || github.event.pull_request.draft == false }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7.0.1
        with:
          fetch-depth: 0
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - uses: actions/setup-python@v7.0.0
        with:
          python-version: "3.14"
          cache: pip
      - name: Install coverage dependencies
        run: |
          python -m pip install --upgrade pip
          python -m pip install pytest pytest-cov
          python -m pip install .
      - name: Run coverage
        run: |
          rm -f coverage.xml
          rm -rf htmlcov
          tmpdir="$(mktemp -d)"
          cd "$tmpdir"
          python -m pytest \
            --rootdir "$GITHUB_WORKSPACE" \
            --cov="${PACKAGE_NAME}" \
            --cov-branch \
            --cov-report=term-missing \
            --cov-report=xml:"$GITHUB_WORKSPACE/coverage.xml" \
            --cov-report=html:"$GITHUB_WORKSPACE/htmlcov" \
            "$GITHUB_WORKSPACE/tests"
      - name: Upload coverage artifacts
        if: always()
        uses: actions/upload-artifact@v7.0.1
        with:
          name: tempoch-coverage
          path: |
            coverage.xml
            htmlcov
          retention-days: 7

  downstream-test:
    name: Downstream PyO3 Consumption
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7.0.1
        with:
          fetch-depth: 0
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - uses: actions/setup-python@v7.0.0
        with:
          python-version: "3.14"
          cache: pip
      - name: Install packages
        run: |
          python -m pip install --upgrade pip
          python -m pip install pytest
          python -m pip install .
          python -m pip install ./tests/fixtures/downstream-extension
      - name: Exercise downstream extension
        run: python -m pytest tests/test_downstream_fixture.py -v

  crate-release-validation:
    name: crates.io Package Validation
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7.0.1
        with:
          fetch-depth: 0
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - name: Run Rust doctests
        run: cargo test --doc
      - name: Validate crate package and publish dry-run
        run: bash scripts/publish.sh --dry-run
      - name: Validate packaged downstream consumer
        run: bash scripts/check-packaged-downstream.sh

  distribution-package:
    name: PyPI Distribution Validation
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v7.0.1
        with:
          fetch-depth: 0

      - uses: actions/setup-python@v7.0.0
        with:
          python-version: "3.14"

      - name: Install wheel test dependencies
        run: python -m pip install --upgrade pip pytest

      - name: Build PyPI-compatible wheel
        uses: PyO3/maturin-action@v1.51.0
        with:
          command: build
          maturin-version: ${{ env.MATURIN_VERSION }}
          manylinux: "2_28"
          args: >-
            --release
            --locked
            --compatibility pypi
            --out dist
            -i python3.14

      - name: Install built wheel
        run: python -m pip install --force-reinstall dist/tempoch-*.whl

      - name: Test installed wheel
        run: |
          tmpdir="$(mktemp -d)"
          cd "$tmpdir"
          python -m pytest --rootdir "$GITHUB_WORKSPACE" "$GITHUB_WORKSPACE/tests"

      - name: Build source distribution
        uses: PyO3/maturin-action@v1.51.0
        with:
          command: sdist
          maturin-version: ${{ env.MATURIN_VERSION }}
          args: --out dist

      - uses: actions/upload-artifact@v7.0.1
        with:
          name: tempoch-release-package
          path: |
            dist/*.whl
            dist/*.tar.gz
          if-no-files-found: error
          retention-days: 7