name: CI

on: [push, pull_request]

jobs:
  lint:
    # Run for PRs only if they come from a forked repo (avoids duplicate runs)
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
    timeout-minutes: 10
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: [3.7]
        toxenv: [flake8, mypy, docs, black]
    steps:
    - uses: actions/checkout@v3
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version }}
    - name: Run tox ${{ matrix.toxenv }}
      run: pipx run tox -e ${{ matrix.toxenv }}

  build:
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
      with:
        fetch-depth: 0  # required for setuptools_scm
    - name: Build sdist and temporary wheel
      run: pipx run build
    - uses: actions/upload-artifact@v3
      with:
        name: sdist
        path: dist/*.tar.gz

  test:
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
    timeout-minutes: 10
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest]
        python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
        include:
        - os: macos-latest
          python-version: "3.10"
        - os: windows-latest
          python-version: "3.10"
    steps:
    - uses: actions/checkout@v3
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version }}
    - name: Test
      run: pipx run tox -e py
    - name: Upload coverage report
      uses: codecov/codecov-action@v3

  wheels:
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
    needs: [lint, build, test]
    timeout-minutes: 20
    strategy:
      matrix:
        os: [ubuntu-20.04, windows-2019]
    runs-on: ${{ matrix.os }}
    steps:
    - uses: actions/checkout@v3
      with:
        fetch-depth: 0  # required for setuptools_scm
    - name: Build wheels
      uses: pypa/cibuildwheel@v2.11.2
      env:
        CIBW_BUILD: "cp*-manylinux_x86_64 cp3*-win_amd64"
    - uses: actions/upload-artifact@v2
      with:
        name: wheels
        path: wheelhouse/*.whl

  publish:
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
    needs: [build, wheels]
    timeout-minutes: 10
    runs-on: ubuntu-latest
    steps:
    - uses: actions/download-artifact@v3
      with:
        name: sdist
        path: dist/
    - uses: actions/download-artifact@v3
      with:
        name: wheels
        path: dist/
    - name: Publish dev release to test PyPI
      if: contains(github.ref, '.dev') || contains(github.ref, 'a')
      uses: pypa/gh-action-pypi-publish@release/v1
      with:
        user: __token__
        password: ${{ secrets.test_pypi_password }}
        repository_url: https://test.pypi.org/legacy/
    - name: Publish to PyPI
      if: "!contains(github.ref, '.dev')"
      uses: pypa/gh-action-pypi-publish@release/v1
      with:
        user: __token__
        password: ${{ secrets.pypi_password }}
