name: Hypothesis CI

env:
  # Tell pytest and other tools to produce coloured terminal output.
  # Make sure this is also in the "passenv" section of the tox config.
  PY_COLORS: 1

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]
  workflow_dispatch:

# Cancel in-progress PR builds if another commit is pushed.
# On non-PR builds, fall back to the globally-unique run_id and don't cancel.
concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        task:
          - check-whole-repo-tests
          - lint
          - check-format
          - check-coverage
          - check-conjecture-coverage
          - check-py37-cover
          - check-pypy37-cover
          - check-py38-cover
          - check-py38-nocover
          - check-py38-niche
          - check-pypy38-cover
          - check-py39-cover
          - check-pypy39-cover
          - check-py310-cover
          - check-py310-nocover
          - check-py310-niche
          # - check-py310-pyjion  # see notes in tox.ini
          - check-py311-cover
          - check-py311-nocover
          - check-py311-niche
          - check-py312-cover
          - check-py312-nocover
          - check-py312-niche
          - check-quality
          ## Skip all the (inactive/old) Rust and Ruby tests pending fixes
          # - lint-ruby
          # - check-ruby-tests
          # - check-rust-in-ruby-format
          # - lint-rust-in-ruby
          # - audit-rust-in-ruby
          # - check-conjecture-rust-format
          # - check-rust-tests
          # - audit-conjecture-rust
          # - lint-conjecture-rust
          - check-py39-nose
          - check-py39-pytest46
          - check-py39-pytest54
          - check-pytest62
          - check-django41
          - check-django40
          - check-django32
          - check-pandas15
          - check-pandas14
          - check-pandas13
          - check-pandas12
          - check-pandas11
          - check-py39-pandas10
      fail-fast: false
    steps:
    - uses: actions/checkout@v3
      with:
        fetch-depth: 0
    - name: Set up Python 3.10
      uses: actions/setup-python@v2
      with:
        python-version: "3.10"
    - name: Restore cache
      uses: actions/cache@v2
      with:
        path: |
          ~/.cache
          ~/wheelhouse
          ~/.local
          vendor/bundle
          .tox/
        key: deps-${{ runner.os }}-${{ hashFiles('requirements/*.txt') }}-${{ matrix.task }}
        restore-keys: |
          deps-${{ runner.os }}-${{ hashFiles('requirements/*.txt') }}
          deps-${{ runner.os }}
    - name: Install dotnet6 for Pyjion
      if: ${{ endsWith(matrix.task, '-pyjion') }}
      run: |
        wget https://packages.microsoft.com/config/ubuntu/21.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
        sudo dpkg -i packages-microsoft-prod.deb
        rm packages-microsoft-prod.deb
        sudo apt-get update
        sudo apt-get install -y apt-transport-https && \
          sudo apt-get update && \
          sudo apt-get install -y dotnet-sdk-6.0
    - name: Run tests
      run: TASK=${{ matrix.task }} ./build.sh
    - name: Upload coverage data
      uses: actions/upload-artifact@v2
      # Invoke the magic `always` function to run on both success and failure.
      if: ${{ always() && endsWith(matrix.task, '-coverage') }}
      with:
        name: ${{ matrix.task }}-data
        path: |
          hypothesis-python/.coverage*
          !hypothesis-python/.coveragerc
          hypothesis-python/branch-check

  test-win:
    runs-on: windows-latest
    strategy:
      matrix:
        include:
          - task: check-py37-cover
          - task: check-py37-niche
          - task: check-py310-cover
          - task: check-py310-niche
          - task: check-py310-x86-cover
            python.architecture: "x86"
          - task: check-py310-x86-nocover
            python.architecture: "x86"
          - task: check-py310-x86-niche
            python.architecture: "x86"
          - task: check-py311-cover
          - task: check-py311-niche
      fail-fast: false
    steps:
    - uses: actions/checkout@v3
      with:
        fetch-depth: 0
    - name: Set up Python 3.10
      uses: actions/setup-python@v2
      with:
        python-version: "3.10"
        architecture: ${{ matrix.python-architecture }}
    - name: Restore cache
      uses: actions/cache@v2
      with:
        path: |
          ~\appdata\local\pip\cache
          vendor\bundle
          .tox
        key: deps-${{ runner.os }}-${{ matrix.python-architecture }}-${{ hashFiles('requirements/*.txt') }}-${{ matrix.task }}
        restore-keys: |
          deps-${{ runner.os }}-${{ matrix.python-architecture }}-${{ hashFiles('requirements/*.txt') }}
          deps-${{ runner.os }}-${{ matrix.python-architecture }}
    - name: Install dependencies
      run: |
        pip install --upgrade setuptools pip wheel
        pip install -r requirements/coverage.txt
        pip install hypothesis-python/[all]
    - name: Run tests
      run: python -m pytest --numprocesses auto hypothesis-python/tests/ --ignore=hypothesis-python/tests/quality/ --ignore=hypothesis-python/tests/ghostwriter/

  test-osx:
    runs-on: macos-latest
    strategy:
      matrix:
        task:
          - check-py37-cover
          - check-py310-cover
          - check-py310-nocover
          - check-py310-niche
          - check-py311-cover
      fail-fast: false
    steps:
    - uses: actions/checkout@v3
      with:
        fetch-depth: 0
    - name: Set up Python 3.10
      uses: actions/setup-python@v2
      with:
        python-version: "3.10"
    - name: Restore cache
      uses: actions/cache@v2
      with:
        path: |
          ~/.cache
          ~/Library/Caches/pip
          .tox/
        key: deps-${{ runner.os }}-${{ hashFiles('requirements/*.txt') }}-${{ matrix.task }}
    - name: Run tests
      run: TASK=${{ matrix.task }} ./build.sh

  deploy:
    if: "github.event_name == 'push' && github.repository == 'HypothesisWorks/hypothesis'"
    runs-on: ubuntu-latest
    needs: [test, test-win, test-osx]
    strategy:
      matrix:
        task:
          - deploy
      fail-fast: false
    steps:
    - uses: actions/checkout@v3
      with:
        fetch-depth: 0
        token: ${{ secrets.GH_TOKEN }}
    - name: Set up Python 3.10
      uses: actions/setup-python@v2
      with:
        python-version: "3.10"
    - name: Restore cache
      uses: actions/cache@v2
      with:
        path: |
          ~/.cache
          ~/wheelhouse
          ~/.local
          vendor/bundle
        key: deps-${{ runner.os }}-${{ hashFiles('requirements/*.txt') }}-${{ matrix.task }}
        restore-keys: |
          deps-${{ runner.os }}-${{ hashFiles('requirements/*.txt') }}
          deps-${{ runner.os }}
    - name: Deploy package
      env:
        GH_TOKEN: ${{ secrets.GH_TOKEN }}
        TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
        GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_TOKEN }}
        CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
      run: TASK=${{ matrix.task }} ./build.sh
