name: CI

on:
  - push
  - pull_request

jobs:
  lint:
    runs-on: ubuntu-latest
    name: Lint

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

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.13"

      - name: Install Poetry
        uses: snok/install-poetry@v1
        with:
          virtualenvs-create: true
          virtualenvs-in-project: true

      - name: Load cached venv
        id: cached-poetry-dependencies
        uses: actions/cache@v4
        with:
          path: .venv
          key: venv-py3.13-${{ hashFiles('poetry.lock') }}

      - name: Install dependencies
        if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
        run: poetry install --no-interaction --no-root

      - name: Lint with black
        run: poetry run black --check --diff .

      - name: Lint with flake8
        run: poetry run flake8 --exclude .venv

      - name: Lint with isort
        run: poetry run isort --check --diff .

      - name: Lint with pylint
        run: poetry run pylint tests timezone_field

  test:
    runs-on: ubuntu-latest
    name: Test py${{ matrix.python-version }}, dj${{ matrix.django-version }}, ${{ matrix.tz-engine}}, ${{ matrix.db-engine }}

    strategy:
      fail-fast: false
      matrix:
        # https://docs.djangoproject.com/en/5.1/faq/install/#what-python-version-can-i-use-with-django
        python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
        django-version: ["4.2", "5.0", "5.1"]
        db-engine: [sqlite, postgres]
        tz-engine: [pytz, zoneinfo]
        exclude:
          - django-version: "4.2"
            python-version: "3.13"
          - django-version: "5.0"
            python-version: "3.8"
          - django-version: "5.0"
            python-version: "3.9"
          - django-version: "5.0"
            python-version: "3.13"
          - django-version: "5.0"
            tz-engine: pytz
          - django-version: "5.1"
            python-version: "3.8"
          - django-version: "5.1"
            python-version: "3.9"
          - django-version: "5.1"
            tz-engine: pytz

    env:
      PYTHON_VERSION: ${{ matrix.python-version }}
      DJANGO_VERSION: ${{ matrix.django-version }}
      DB_ENGINE: ${{ matrix.db-engine }}
      TZ_ENGINE: ${{ matrix.tz-engine }}

    services:
      postgres:
        image: postgres
        env:
          POSTGRES_DB: postgres
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
        ports:
          - 5432:5432
        # Set health checks to wait until postgres has started
        options: >-
          --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

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

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install Poetry
        uses: snok/install-poetry@v1
        with:
          virtualenvs-create: true
          virtualenvs-in-project: true

      - name: Load cached venv
        id: cached-poetry-dependencies
        uses: actions/cache@v4
        with:
          path: .venv
          key: venv-py${{ matrix.python-version}}-dj${{ matrix.django-version }}-${{ matrix.tz-engine }}-${{ hashFiles('poetry.lock') }}

      - name: Install dependencies
        if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
        run: poetry install --no-interaction --no-root

      - name: Install django ${{ matrix.django-version }}
        if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
        run: |
          source .venv/bin/activate
          pip install --pre "Django~=${{ matrix.django-version }}"

      - name: Install pytz
        if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' && matrix.tz-engine == 'pytz'
        run: |
          source .venv/bin/activate
          pip install pytz

      - name: Remove pytz
        if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' && matrix.tz-engine != 'pytz'
        run: |
          source .venv/bin/activate
          pip uninstall --yes pytz

      - name: Test with coverage
        env:
          POSTGRES_HOST: localhost
          POSTGRES_PORT: 5432
          POSTGRES_DB: postgres
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
        run: poetry run pytest --cov=timezone_field

      - name: Generate coverage report
        run: poetry run coverage xml

      - name: Upload coverage report to codecov
        uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          env_vars: PYTHON_VERSION,DJANGO_VERSION,DB_ENGINE
          fail_ci_if_error: true

  build:
    runs-on: ubuntu-latest
    name: Build

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

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.13"

      - name: Install Poetry
        uses: snok/install-poetry@v1
        with:
          virtualenvs-create: true
          virtualenvs-in-project: true

      - name: Load cached venv
        id: cached-poetry-dependencies
        uses: actions/cache@v4
        with:
          path: .venv
          key: venv-py3.13-${{ hashFiles('poetry.lock') }}

      - name: Install dependencies
        if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
        run: poetry install --no-interaction --no-root

      - name: Build with poetry
        run: poetry build
