From 4400b05418ef0d7a07100eabe9c970e475516f3f Mon Sep 17 00:00:00 2001 From: Vitor Hugo Date: Tue, 30 Jun 2026 21:25:51 -0300 Subject: [PATCH 1/4] ci: add SonarCloud analysis with coverage - Add sonar-project.properties for Python (pytest-cov coverage.xml) - Generate coverage.xml in the test job (Python 3.12 matrix entry) - Add SonarCloud job that uploads coverage and enforces quality gate - Excludes tests/examples/docs/scripts/docker/freeswitch from analysis --- .github/workflows/main.yml | 43 ++++++++++++++++++++++++++++++++++++-- sonar-project.properties | 17 +++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 sonar-project.properties diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 05d2a54..182f035 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -98,8 +98,47 @@ jobs: - name: Run Type Checker (Mypy) run: poetry run mypy - - name: Run tests - run: poetry run py.test + - name: Run tests (with coverage) + run: poetry run pytest --cov=genesis --cov-report=xml:coverage.xml --cov-report=term + + - name: Upload coverage report + if: matrix.python-version == '3.12' + uses: actions/upload-artifact@v4 + with: + name: coverage-xml + path: coverage.xml + if-no-files-found: warn + retention-days: 3 + + # SonarCloud analysis. Fails the job if the quality gate fails. + sonar: + name: SonarCloud + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + needs: [check-commit, test] + if: | + needs.check-commit.outputs.should-run == 'true' && + (github.event_name == 'pull_request' || github.event_name == 'push' || github.event_name == 'workflow_dispatch') + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Download coverage report + uses: actions/download-artifact@v4 + with: + name: coverage-xml + + - name: SonarCloud Scan + uses: SonarSource/sonarcloud-github-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + with: + args: > + -Dsonar.qualitygate.wait=true # Version bump (only runs on push to main, not on PRs) # Runs after contributors to avoid infinite loops diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..169d0b2 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,17 @@ +sonar.projectKey=Otoru_Genesis +sonar.organization=otoru +sonar.projectName=Genesis + +# Source + tests +sonar.sources=genesis +sonar.tests=tests,examples +sonar.tests.inclusions=tests/**/*.py,examples/**/*.py + +# Python +sonar.python.version=3.12 +sonar.sourceEncoding=UTF-8 +sonar.python.coverage.reportPaths=coverage.xml + +# Exclude non-source paths from analysis/coverage +sonar.exclusions=**/__pycache__/**,**/*.pyc,tests/**,examples/**,docs/**,scripts/**,docker/**,freeswitch/**,.github/** +sonar.coverage.exclusions=tests/**,examples/**,docs/**,scripts/**,docker/**,freeswitch/**,genesis/cli/** \ No newline at end of file From b45308e91daef095cfa662f6271bd8482613d867 Mon Sep 17 00:00:00 2001 From: Vitor Hugo Date: Tue, 30 Jun 2026 21:27:00 -0300 Subject: [PATCH 2/4] ci(sonar): use projectKey Genesis (org otoru) --- sonar-project.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonar-project.properties b/sonar-project.properties index 169d0b2..5dd320f 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,4 +1,4 @@ -sonar.projectKey=Otoru_Genesis +sonar.projectKey=Genesis sonar.organization=otoru sonar.projectName=Genesis From e2a384f88ceac0f2a80562ac6b723a2e5c817bbf Mon Sep 17 00:00:00 2001 From: Vitor Hugo Date: Tue, 30 Jun 2026 21:36:28 -0300 Subject: [PATCH 3/4] fix(coverage): emit relative paths in coverage.xml The existing .coveragerc had no relative_files setting, so coverage.py wrote absolute paths (e.g. /home/runner/work/Genesis/Genesis/ genesis) into coverage.xml. SonarCloud cannot resolve those paths and drops all coverage measures with 'Invalid directory path in source element' / 'Cannot resolve the file path'. Set relative_files = true in .coveragerc so the XML uses genesis with relative filenames, matching sonar.sources=genesis. --- .coveragerc | 1 + 1 file changed, 1 insertion(+) diff --git a/.coveragerc b/.coveragerc index c1d8fcf..ceb7787 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,4 +1,5 @@ [run] +relative_files = true source = genesis/ omit = tests/* From 5b99e6aae1e3839d1a16834ef187dbeda815ff3c Mon Sep 17 00:00:00 2001 From: Vitor Hugo Date: Tue, 30 Jun 2026 21:40:19 -0300 Subject: [PATCH 4/4] fix(sonar): use sonar.test.inclusions (singular) per spec --- sonar-project.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonar-project.properties b/sonar-project.properties index 5dd320f..2fc7e00 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -5,7 +5,7 @@ sonar.projectName=Genesis # Source + tests sonar.sources=genesis sonar.tests=tests,examples -sonar.tests.inclusions=tests/**/*.py,examples/**/*.py +sonar.test.inclusions=tests/**/*.py,examples/**/*.py # Python sonar.python.version=3.12