diff --git a/.github/workflows/qa-analysis.yml b/.github/workflows/qa-analysis.yml new file mode 100644 index 00000000..69f8918d --- /dev/null +++ b/.github/workflows/qa-analysis.yml @@ -0,0 +1,139 @@ +name: Quality Assurance + +on: + workflow_dispatch: + push: + branches: + - main + # PRs trigger for the "opened", "reopened", "synchronize" events (default) and + # "ready_for_review" + pull_request: + types: + - opened + - reopened + - synchronize # when new commits are pushed to the PR + - ready_for_review # when the PR is un-drafted + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + FORCE_COLOR: 3 + COLUMNS: 120 + CPM_USE_LOCAL_PACKAGES: "TRUE" + +jobs: + code-coverage: + # in combination with the PR types selection, this top-level if statement + # skips running the workflow for Draft PRs + if: ${{ github.event_name == 'push' || !github.event.pull_request.draft || contains(github.event.pull_request.labels.*.name, 'test-in-draft') }} + + name: Check code coverage + runs-on: ubuntu-26.04 + env: + SKBUILD_CMAKE_BUILD_TYPE: "Coverage" + + steps: + - uses: actions/checkout@v7.0.1 + with: + fetch-depth: 0 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y libopenmpi-dev openmpi-bin libboost-dev libboost-test-dev libmsgpack-cxx-dev + + - name: Install the latest version of uv + uses: astral-sh/setup-uv@v9.0.0 + with: + enable-cache: true + python-version: "3.11" + + - name: Install package + run: | + uv sync --no-progress --group test --all-extras -v + + - name: Run Python tests + run: | + uv run pytest \ + --cov=src/monoprop \ + --cov-report=xml:python-coverage.xml + + - name: Collect coverage (C++ through Python bindings) + run: | + uvx gcovr \ + --gcov-executable gcov \ + --gcov-ignore-parse-errors \ + --exclude-throw-branches \ + --exclude-unreachable-branches \ + --filter '^(src|include)/' \ + --exclude '^tests/' \ + --merge-lines \ + "build/editable/Coverage" \ + --cobertura cpp-coverage-through-python-bindings.xml + + - name: Run C++ unit tests + run: | + ctest --test-dir build/editable/Coverage --output-on-failure + + - name: Collect coverage (C++ unit tests) + run: | + uvx gcovr \ + --gcov-executable gcov \ + --gcov-ignore-parse-errors \ + --exclude-throw-branches \ + --exclude-unreachable-branches \ + --filter '^(src|include)/' \ + --exclude '^tests/' \ + --merge-lines \ + "build/editable/Coverage" \ + --cobertura cpp-coverage.xml + + - name: Upload C++ coverage to Codecov + uses: codecov/codecov-action@v7.0.0 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: python-coverage.xml, cpp-coverage-through-python-bindings.xml, cpp-coverage.xml + flags: cpp + disable_search: true + fail_ci_if_error: true + + + sonarqube-analysis: + # in combination with the PR types selection, this top-level if statement + # skips running the workflow for Draft PRs + if: ${{ github.event_name == 'push' || !github.event.pull_request.draft || contains(github.event.pull_request.labels.*.name, 'test-in-draft') }} + + name: SonarQube analysis + runs-on: ubuntu-26.04 + env: + SKBUILD_CMAKE_DEFINE: "monoprop_ENABLE_MPI=ON" + + steps: + - uses: actions/checkout@v7.0.1 + with: + fetch-depth: 0 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y ninja-build libopenmpi-dev openmpi-bin libboost-dev libboost-test-dev libmsgpack-cxx-dev + + - name: Install the latest version of uv + uses: astral-sh/setup-uv@v9.0.0 + with: + enable-cache: true + python-version: "3.11" + + - name: Install package + run: | + uv sync --no-progress --all-extras -v + + - name: SonarQube Scan + uses: SonarSource/sonarqube-scan-action@v8.2.1 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + with: + args: > + -Dsonar.cfamily.compile-commands=build/editable/Release/compile_commands.json diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c7e6000a..e3a4b353 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -176,119 +176,3 @@ jobs: report_type: test_results disable_search: true fail_ci_if_error: true - - code-coverage: - # in combination with the PR types selection, this top-level if statement - # skips running the workflow for Draft PRs - if: ${{ github.event_name == 'push' || !github.event.pull_request.draft || contains(github.event.pull_request.labels.*.name, 'test-in-draft') }} - - name: Check code coverage - runs-on: ubuntu-26.04 - env: - SKBUILD_CMAKE_BUILD_TYPE: "Coverage" - - steps: - - uses: actions/checkout@v7.0.1 - with: - fetch-depth: 0 - - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y libopenmpi-dev openmpi-bin libboost-dev libboost-test-dev libmsgpack-cxx-dev - - - name: Install the latest version of uv - uses: astral-sh/setup-uv@v9.0.0 - with: - enable-cache: true - python-version: "3.11" - - - name: Install package - run: | - uv sync --no-progress --group test --all-extras -v - - - name: Run Python tests - run: | - uv run pytest \ - -r aR \ - --cov=src/monoprop \ - --cov-report=xml:python-coverage.xml \ - --durations=50 \ - --durations-min=5.0 - - - name: Collect coverage (C++ through Python bindings) - run: | - uvx gcovr \ - --gcov-executable gcov \ - --gcov-ignore-parse-errors \ - --exclude-throw-branches \ - --exclude-unreachable-branches \ - --filter '^(src|include)/' \ - --exclude '^tests/' \ - --merge-lines \ - "build/editable/Coverage" \ - --cobertura cpp-coverage-through-python-bindings.xml - - - name: Run C++ unit tests - run: | - ctest --test-dir build/editable/Coverage --output-on-failure - - - name: Collect coverage (C++ unit tests) - run: | - uvx gcovr \ - --gcov-executable gcov \ - --gcov-ignore-parse-errors \ - --exclude-throw-branches \ - --exclude-unreachable-branches \ - --filter '^(src|include)/' \ - --exclude '^tests/' \ - --merge-lines \ - "build/editable/Coverage" \ - --cobertura cpp-coverage.xml - - - name: Upload C++ coverage to Codecov - uses: codecov/codecov-action@v7.0.0 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: python-coverage.xml, cpp-coverage-through-python-bindings.xml, cpp-coverage.xml - flags: cpp - disable_search: true - fail_ci_if_error: true - - sonarqube-analysis: - # in combination with the PR types selection, this top-level if statement - # skips running the workflow for Draft PRs - if: ${{ github.event_name == 'push' || !github.event.pull_request.draft || contains(github.event.pull_request.labels.*.name, 'test-in-draft') }} - - name: SonarQube analysis - runs-on: ubuntu-26.04 - env: - SKBUILD_CMAKE_DEFINE: "monoprop_ENABLE_MPI=ON" - - steps: - - uses: actions/checkout@v7.0.1 - with: - fetch-depth: 0 - - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y ninja-build libopenmpi-dev openmpi-bin libboost-dev libboost-test-dev libmsgpack-cxx-dev - - - name: Install the latest version of uv - uses: astral-sh/setup-uv@v9.0.0 - with: - enable-cache: true - python-version: "3.11" - - - name: Install package - run: | - uv sync --no-progress --all-extras -v - - - name: SonarQube Scan - uses: SonarSource/sonarqube-scan-action@v8.2.1 - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - with: - args: > - -Dsonar.cfamily.compile-commands=build/editable/Release/compile_commands.json