name: tox

on:
  create: # is used for publishing to PyPI and TestPyPI
    tags: # any tag regardless of its name, no branches
      - "**"
  push: # only publishes pushes to the main branch to TestPyPI
    branches: # any integration branch but not tag
      - "main"
  pull_request:
  release:
    types:
      - published # It seems that you can publish directly without creating
  schedule:
    - cron: 1 0 * * * # Run daily at 0:01 UTC
  # Run every Friday at 18:02 UTC
  # https://crontab.guru/#2_18_*_*_5
  # - cron: 2 18 * * 5
  workflow_call:

jobs:
  linters:
    name: >-
      ${{ matrix.env.TOXENV }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        python-version:
          - 3.9
        os:
          - ubuntu-20.04
        env:
          - TOXENV: lint
          - TOXENV: docs
          - TOXENV: packaging
    env:
      TOX_PARALLEL_NO_SPINNER: 1
      FORCE_COLOR: 1

    steps:
      - name: Check out src from Git
        uses: actions/checkout@v2
        with:
          fetch-depth: 0 # needed by setuptools-scm
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Pre-commit cache
        uses: actions/cache@v2
        with:
          path: ~/.cache/pre-commit
          key: ${{ runner.os }}-${{ matrix.env.TOXENV }}-pre-commit-${{ hashFiles('setup.cfg', 'tox.ini', 'pyproject.toml', '.pre-commit-config.yaml') }}
      - name: Pip cache
        uses: actions/cache@v2
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-${{ matrix.env.TOXENV }}-pip-${{ hashFiles('setup.cfg', 'tox.ini', 'pyproject.toml', '.pre-commit-config.yaml') }}
      - name: Install tox
        run: |
          python3 -m pip install --upgrade tox
      - name: Log installed dists
        run: >-
          python -m pip freeze --all
      - name: >-
          Initialize tox envs
        run: >-
          python -m
          tox
          --parallel auto
          --parallel-live
          --notest
          --skip-missing-interpreters false
          -vv
        env: ${{ matrix.env }}
      - name: Test with tox
        run: |
          python -m tox --parallel auto --parallel-live
        env: ${{ matrix.env }}
      - name: Archive logs
        uses: actions/upload-artifact@v2
        with:
          name: logs.zip
          path: .tox/**/log/

  unit:
    name: >-
      ${{ matrix.tox_env }}@${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      # fail-fast: false
      # max-parallel: 5
      # The matrix testing goal is to cover the *most likely* environments
      # which are expected to be used by users in production. Avoid adding a
      # combination unless there are good reasons to test it, like having
      # proof that we failed to catch a bug by not running it. Using
      # distribution should be prefferred instead of custom builds.
      matrix:
        python-version:
          # keep list sorted as it determines UI order too
          - 3.8
          - 3.9
          - "3.10"
        # NOTE: Installing ansible under 3.10-dev is currently not
        # NOTE: possible because compiling cffi explodes.
        os:
          # https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners
          - ubuntu-20.04
        # - windows-latest
        # - windows-2016
        include:
          - tox_env: py38
            os: ubuntu-20.04
            python-version: 3.8
            devel: true
          - tox_env: py39
            os: ubuntu-20.04
            python-version: 3.9
            devel: true
          - tox_env: py310
            os: ubuntu-20.04
            python-version: "3.10"
            devel: true
          - tox_env: py38
            os: macOS-latest
            python-version: 3.8
          - tox_env: py310
            os: macOS-latest
            python-version: "3.10"
            devel: true

    env:
      TOX_PARALLEL_NO_SPINNER: 1
      FORCE_COLOR: 1

    steps:
      - name: MacOS workaround for https://github.com/actions/virtual-environments/issues/1187
        if: ${{ matrix.os == 'macOS-latest' }}
        run: |
          sudo sysctl -w net.link.generic.system.hwcksum_tx=0
          sudo sysctl -w net.link.generic.system.hwcksum_rx=0
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0 # needed by setuptools-scm
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: >-
          Log the currently selected Python
          version info (${{ matrix.python-version }})
        run: |
          python --version --version
          which python
      - name: Pip cache
        uses: actions/cache@v2
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-${{ matrix.tox_env }}-pip-${{ hashFiles('constraints.txt', 'setup.cfg', 'tox.ini', 'pyproject.toml', '.pre-commit-config.yaml', 'pytest.ini') }}
      - name: Install tox
        run: |
          python3 -m pip install --upgrade tox 'coverage[toml]'
      - name: Log installed dists
        run: >-
          python3 -m pip freeze --all
      - name: >-
          Initialize tox envs
        run: >-
          python3 -m
          tox
          --parallel auto
          --parallel-live
          --notest
          --skip-missing-interpreters false
          -vv
        env:
          TOXENV: ${{ matrix.tox_env }},${{ matrix.tox_env }}-ansible29,${{ matrix.tox_env }}-ansible212
      # sequential run improves browsing experience (almost no speed impact)
      - name: "Test with tox: ${{ matrix.tox_env }}-ansible29"
        run: python3 -m tox
        env:
          TOXENV: ${{ matrix.tox_env }}-ansible29
      - name: "Test with tox: ${{ matrix.tox_env }}-ansible212"
        run: python3 -m tox
        env:
          TOXENV: ${{ matrix.tox_env }}-ansible212
      - name: "Test with tox: ${{ matrix.tox_env }}-devel"
        if: ${{ matrix.devel }}
        run: |
          python3 -m tox
        env:
          TOXENV: ${{ matrix.tox_env }}-devel
      - name: Combine coverage data
        # produce a single .coverage file at repo root
        run: coverage combine .tox/.coverage.*
      - name: Upload coverage data
        uses: codecov/codecov-action@v1
        with:
          name: ${{ matrix.tox_env }}
          fail_ci_if_error: true # optional (default = false)
          verbose: true # optional (default = false)
      - name: Archive logs
        uses: actions/upload-artifact@v2
        with:
          name: logs.zip
          path: .tox/**/log/
        # https://github.com/actions/upload-artifact/issues/123
        continue-on-error: true
      - name: Report junit failures
        uses: shyim/junit-report-annotations-action@3d2e5374f2b13e70f6f3209a21adfdbc42c466ae
        with:
          path: .tox/junit.*.xml
        if: always()

  check: # This job does nothing and is only used for the branch protection
    if: always()

    needs:
      - linters
      - unit

    runs-on: ubuntu-latest

    steps:
      - name: Decide whether the needed jobs succeeded or failed
        uses: re-actors/alls-green@release/v1
        with:
          jobs: ${{ toJSON(needs) }}
