  test-{{ lowercase_group }}-{{ category }}:
    name: {{ group }} ({{ category }})
    timeout-minutes: 30
    runs-on: {% raw %}${{ matrix.os }}{% endraw %}
    strategy:
      fail-fast: false
      matrix:
        python-version: [{{ py_versions.get(category)|join(",") }}]
        # python3.6 reached EOL and is no longer being supported on
        # new versions of hosted runners on Github Actions
        # ubuntu-20.04 is the last version that supported python3.6
        # see https://github.com/actions/setup-python/issues/544#issuecomment-1332535877
        os: [ubuntu-20.04]

    {% if needs_github_secrets %}
    needs: check-permissions
    {% endif %}

    {% if needs_postgres %}
    services:
      postgres:
        image: postgres
        env:
          POSTGRES_PASSWORD: sentry
        # Set health checks to wait until postgres has started
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        # Maps tcp port 5432 on service container to the host
        ports:
          - 5432:5432
    env:
      SENTRY_PYTHON_TEST_POSTGRES_HOST: localhost
      SENTRY_PYTHON_TEST_POSTGRES_USER: postgres
      SENTRY_PYTHON_TEST_POSTGRES_PASSWORD: sentry

    {% endif %}

    steps:
      - uses: actions/checkout@v4.2.2
      {% if needs_github_secrets %}
      {% raw %}
        with:
          ref: ${{ github.event.pull_request.head.sha || github.ref }}
      {% endraw %}
      {% endif %}
      - uses: actions/setup-python@v5
        with:
          python-version: {% raw %}${{ matrix.python-version }}{% endraw %}
          allow-prereleases: true
      {% if needs_clickhouse %}
      - uses: getsentry/action-clickhouse-in-ci@v1.1
      {% endif %}

      {% if needs_redis %}
      - name: Start Redis
        uses: supercharge/redis-github-action@1.8.0
      {% endif %}

      - name: Setup Test Env
        run: |
          pip install "coverage[toml]" tox
      - name: Erase coverage
        run: |
          coverage erase

      {% for framework in frameworks %}
      - name: Test {{ framework }} {{ category }}
        run: |
          set -x # print commands that are executed
          {% if category == "pinned" %}
          ./scripts/runtox.sh --exclude-latest "{% raw %}py${{ matrix.python-version }}{% endraw %}-{{ framework }}"
          {% elif category == "latest" %}
          ./scripts/runtox.sh "{% raw %}py${{ matrix.python-version }}{% endraw %}-{{ framework }}-latest"
          {% endif %}
      {% endfor %}

      - name: Generate coverage XML (Python 3.6)
        if: {% raw %}${{ !cancelled() && matrix.python-version == '3.6' }}{% endraw %}
        run: |
          export COVERAGE_RCFILE=.coveragerc36
          coverage combine .coverage-sentry-*
          coverage xml --ignore-errors

      - name: Generate coverage XML
        if: {% raw %}${{ !cancelled() && matrix.python-version != '3.6' }}{% endraw %}
        run: |
          coverage combine .coverage-sentry-*
          coverage xml

      - name: Upload coverage to Codecov
        if: {% raw %}${{ !cancelled() }}{% endraw %}
        uses: codecov/codecov-action@v5.3.1
        with:
          token: {% raw %}${{ secrets.CODECOV_TOKEN }}{% endraw %}
          files: coverage.xml
          # make sure no plugins alter our coverage reports
          plugin: noop
          verbose: true

      - name: Upload test results to Codecov
        if: {% raw %}${{ !cancelled() }}{% endraw %}
        uses: codecov/test-results-action@v1
        with:
          token: {% raw %}${{ secrets.CODECOV_TOKEN }}{% endraw %}
          files: .junitxml
          verbose: true
