name: Coverage report
on:
  push:
  pull_request:
    branches: ['main']
concurrency:
  group: ${{ github.repository }}-${{ github.ref }}-${{ github.head_ref }}-${{ github.workflow }}
  # Only cancel in PR mode.  In push mode, don't cancel so we don't see spurious test "failures",
  # and we get coverage reports on Coveralls for every push.
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
  coverage:
    if: github.repository_owner == 'Qiskit'
    name: Coverage
    runs-on: ubuntu-latest
    env:
      # Override the `rust-toolchain.toml` file because `grcov` has greater requirements.
      RUSTUP_TOOLCHAIN: stable

    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        name: Install Python
        with:
          python-version: '3.8'

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          components: llvm-tools-preview

      - name: Install dependencies
        run: |
            cargo install grcov
            sudo apt-get install lcov

      # This is needed to support any requirements, particularly in the `optionals` set,
      # that might not have 'pyproject.toml' files specifying their build requirements.
      # Modern pip (23.1+) can error out if it doesn't have `wheel` and we ask for one
      # of these legacy packages.
      - name: Ensure basic build requirements
        run: python -m pip install -c constraints.txt --upgrade pip setuptools wheel

      - name: Build and install qiskit-terra
        run: python -m pip install -c constraints.txt -e .
        env:
          CARGO_INCREMENTAL: 0
          RUSTFLAGS: "-Cinstrument-coverage"
          LLVM_PROFILE_FILE: "qiskit-%p-%m.profraw"
          SETUPTOOLS_ENABLE_FEATURES: "legacy-editable"

      - name: Generate unittest coverage report
        run: |
          set -e
          python -m pip install -c constraints.txt -r requirements-dev.txt -r requirements-optional.txt
          stestr run
          # We set the --source-dir to '.' because we want all paths to appear relative to the repo
          # root (we need to combine them with the Python ones), but we only care about `grcov`
          # keeping the `crates/*` files; we don't care about coverage in dependencies.
          grcov . --binary-path target/debug/ --source-dir . --output-type lcov --output-path rust.info --llvm --branch --parallel --keep-only 'crates/*'
        env:
          QISKIT_TEST_CAPTURE_STREAMS: 1
          QISKIT_PARALLEL: FALSE
          PYTHON: "coverage run --source qiskit --parallel-mode"

      - name: Convert to lcov and combine data
        run: |
          set -e
          coverage combine
          coverage lcov -o python.info
          lcov --add-tracefile python.info --add-tracefile rust.info --output-file coveralls.info

      - name: Coveralls
        uses: coverallsapp/github-action@master
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          path-to-lcov: coveralls.info