# Run the complete test suite incl. many external command line dependencies (like Openbabel)
# as well as the pymatgen.ext package. Coverage used to be computed based on this workflow.
name: test

on:
  push:
    branches: [master]
    paths:
      [
        "src/**/*.*",
        "tests/**/*.*",
        ".github/workflows/*",
        "pyproject.toml",
      ]
  pull_request:
    branches: [master]
    paths:
      [
        "src/**/*.*",
        "tests/**/*.*",
        ".github/workflows/*",
        "pyproject.toml",
      ]
  workflow_dispatch:
  workflow_call: # make this workflow reusable by release.yml

permissions:
  contents: read

jobs:
  test:
    # Prevent this action from running on forks
    if: github.repository == 'materialsproject/pymatgen'
    defaults:
      run:
        shell: bash -leo pipefail {0} # Enable mamba env activation by reading bash profile
    strategy:
      fail-fast: false
      matrix:
        # Maximize CI coverage of different platforms and Python versions while minimizing the
        # total number of jobs. We run all pytest jobs with the oldest supported Python
        # version on windows (most likely to surface errors) and with
        # newest version on Ubuntu (to get complete coverage).
        config:
          - os: windows-latest
            python: "3.11"  # Test lowest supported Python version
            resolution: lowest-direct
            extras: optional
          - os: macos-latest
            python: "3.13"
            resolution: lowest-direct # test with only required dependencies installed
          - os: ubuntu-latest
            python: "3.14"  # Test highest supported Python version
            resolution: highest
            extras: prototypes,optional

    runs-on: ${{ matrix.config.os }}
    env:
      OPT_BIN_DIR: ${{ github.workspace }}/opt/bin # for optional Ubuntu dependencies
    steps:
      - name: Check out repo
        uses: actions/checkout@v6
        with:
          submodules: true
      - name: Create mamba environment
        uses: mamba-org/setup-micromamba@v2
        with:
          environment-name: pmg
          cache-environment: true
          create-args: >-
            python=${{ matrix.config.python }}

      - name: Install ubuntu-only conda dependencies
        if: matrix.config.os == 'ubuntu-latest'
        run: |
          micromamba install -n pmg -c conda-forge bader enumlib \
            packmol pygraphviz tblite --yes
            # openff-toolkit # TODO: doesn't support Python 3.13 yet

      - name: Install uv
        uses: astral-sh/setup-uv@v7

      - name: Install pymatgen and dependencies via uv
        run: |
          # Install from wheels to test the content
          uv build --wheel --no-build-logs
          WHEEL_FILE=$(ls dist/pymatgen*.whl)
          uv pip install $WHEEL_FILE[${{matrix.config.extras}}] --group test \
            --resolution=${{matrix.config.resolution}}

      - name: Restore cache for optional Ubuntu/MacOS dependencies
        if: matrix.config.os == 'ubuntu-latest' || matrix.config.os == 'macos-latest'
        id: optbin-cache
        uses: actions/cache@v5
        with:
          path: ${{ env.OPT_BIN_DIR }}
          key: opt-bin-${{ runner.os }}-${{ hashFiles('.github/workflows/_install_opt_unit_deps.sh') }}

      - name: Build optional Ubuntu/MacOS dependencies (when cache misses)
        if: (matrix.config.os == 'ubuntu-latest' || matrix.config.os == 'macos-latest') && steps.optbin-cache.outputs.cache-hit != 'true'
        run: bash .github/workflows/_install_opt_unit_deps.sh "$OPT_BIN_DIR"

      - name: pytest
        env:
          MPLBACKEND: Agg # non-interactive backend for matplotlib
          PMG_MAPI_KEY: ${{ secrets.PMG_MAPI_KEY }}
          PMG_TEST_FILES_DIR: "${{ github.workspace }}/test-files"
          PYTHONWARNDEFAULTENCODING: "true" # PEP 597: Enable optional EncodingWarning
        run: |
          pytest tests

  trigger_atomate2_ci:
    needs: test
    runs-on: ubuntu-latest
    # Only run if changes are pushed to master
    if: github.ref == 'refs/heads/master'
    steps:
      - name: Trigger Atomate2 CI
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          curl -L \
            -X POST \
            -H "Accept: application/vnd.github+json" \
            -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
            -H "X-GitHub-Api-Version: 2022-11-28" \
            https://api.github.com/repos/materialsproject/atomate2/dispatches \
            -d '{"event_type": "pymatgen-ci-trigger", "client_payload": {"pymatgen_ref": "${{ github.sha }}"}}'
