fix(sonar): generic test execution duration must be positive for SQ 26.x
CI / Rust Format (pull_request) Successful in 23s
CI / TypeScript Lint + Typecheck (pull_request) Successful in 26s
CI / TypeScript Tests + Coverage (pull_request) Successful in 38s
CI / Rust Tests + Coverage (pull_request) Successful in 42s
CI / Dependency-Track (BOM) (pull_request) Successful in 22s
CI / Clippy (SARIF) (pull_request) Successful in 1m21s
CI / SonarQube (pull_request) Failing after 31s
CI / Electron Release Build (pull_request) Successful in 3m20s
CI / E2E Tests (Playwright + Electron) (pull_request) Successful in 6m43s
CI / Rust Format (pull_request) Successful in 23s
CI / TypeScript Lint + Typecheck (pull_request) Successful in 26s
CI / TypeScript Tests + Coverage (pull_request) Successful in 38s
CI / Rust Tests + Coverage (pull_request) Successful in 42s
CI / Dependency-Track (BOM) (pull_request) Successful in 22s
CI / Clippy (SARIF) (pull_request) Successful in 1m21s
CI / SonarQube (pull_request) Failing after 31s
CI / Electron Release Build (pull_request) Successful in 3m20s
CI / E2E Tests (Playwright + Electron) (pull_request) Successful in 6m43s
Gitea Actions reaches SonarQube fine; the scanner failed parsing our converted reports because many testCase elements had duration="0". Clamp to ≥1 ms and emit a standard XML declaration. Restore Rust + Vitest paths in sonar.testExecutionReportPaths. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -143,6 +143,11 @@ def collect_vitest(junit_path: Path, repo: Path) -> ByFile:
|
||||
return by_file
|
||||
|
||||
|
||||
def _sonar_duration_ms(ms: int) -> int:
|
||||
"""SonarQube 26.x generic test execution rejects duration=0 (expects positive ms)."""
|
||||
return max(ms, 1)
|
||||
|
||||
|
||||
def by_file_to_element(by_file: ByFile) -> ET.Element:
|
||||
out = ET.Element("testExecutions")
|
||||
out.set("version", "1")
|
||||
@@ -153,7 +158,7 @@ def by_file_to_element(by_file: ByFile) -> ET.Element:
|
||||
for display_name, ms, status in sorted(by_file[path], key=lambda x: x[0]):
|
||||
te = ET.SubElement(fe, "testCase")
|
||||
te.set("name", display_name)
|
||||
te.set("duration", str(ms))
|
||||
te.set("duration", str(_sonar_duration_ms(ms)))
|
||||
if status == "skipped":
|
||||
ET.SubElement(te, "skipped")
|
||||
elif status == "failure":
|
||||
@@ -190,12 +195,17 @@ def _write_xml(elem: ET.Element, out_path: Path) -> None:
|
||||
out_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
tree = ET.ElementTree(elem)
|
||||
ET.indent(tree, space=" ")
|
||||
# Avoid Python's single-quoted XML declaration; keep UTF-8 header aligned with JUnit producers.
|
||||
tree.write(
|
||||
out_path,
|
||||
encoding="utf-8",
|
||||
xml_declaration=True,
|
||||
xml_declaration=False,
|
||||
default_namespace=None,
|
||||
)
|
||||
raw = out_path.read_bytes()
|
||||
out_path.write_bytes(
|
||||
b'<?xml version="1.0" encoding="UTF-8"?>\n' + raw.lstrip()
|
||||
)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
|
||||
@@ -14,10 +14,9 @@ sonar.sarifReportPaths=target/clippy-report.sarif
|
||||
# Rust: CI converts target/lcov.info → target/sonar-rust-coverage.xml (Generic Coverage).
|
||||
# TypeScript still uses sonar.javascript.lcov.reportPaths below.
|
||||
sonar.coverageReportPaths=target/sonar-rust-coverage.xml
|
||||
# Generic Test Execution: Vitest JUnit converted in CI (see scripts/junit_to_sonar_test_execution.py).
|
||||
# SonarQube 26.4+ rejects our Rust report: paths map to library sources (inline #[cfg(test)]), not dedicated test files.
|
||||
# Rust coverage still comes from sonar.coverageReportPaths; nextest conversion remains in CI for debugging/ future use.
|
||||
sonar.testExecutionReportPaths=ui-reports/test-results/sonar-test-execution.xml
|
||||
# Generic Test Execution: nextest + Vitest JUnit → Sonar XML in CI (scripts/junit_to_sonar_test_execution.py).
|
||||
# SonarQube 26.x rejects duration="0"; the script clamps to ≥1 ms. Paths match artifact layout in the sonarqube job.
|
||||
sonar.testExecutionReportPaths=target/nextest/ci/sonar-test-execution.xml,ui-reports/test-results/sonar-test-execution.xml
|
||||
|
||||
sonar.scm.provider=git
|
||||
|
||||
|
||||
Reference in New Issue
Block a user