feat(sonar): Add SonarQube static analysis and code coverage setup
SonarQube Analysis / sonarqube (pull_request) Successful in 5m37s
SonarQube Analysis / sonarqube (pull_request) Successful in 5m37s
Establishes tooling to systematically analyze and address technical debt. This includes: - `scan-sonar.ps1`: An orchestration script for local SonarQube scans with coverage. - `Directory.Build.props`: Integrates SonarAnalyzer.CSharp for static analysis during build. - `coverlet.runsettings`: Configures code coverage collection using Coverlet. - `.claude/settings.local.json`: Adds permissions for AI to query SonarQube and local dev status.
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env pwsh
|
||||
# Runs a local SonarQube scan with coverage.
|
||||
# Requires: $env:SONAR_TOKEN (and optionally $env:SONAR_HOST_URL).
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
Set-Location $PSScriptRoot
|
||||
|
||||
if (-not $env:SONAR_TOKEN) {
|
||||
throw "Set `$env:SONAR_TOKEN before running (generate at <sonar>/account/security)."
|
||||
}
|
||||
|
||||
$sonarHost = if ($env:SONAR_HOST_URL) { $env:SONAR_HOST_URL } else { 'https://snrqbe.bermudalamb.synology.me' }
|
||||
$projectKey = 'sql-utilities'
|
||||
$solution = 'Strata.SqlTools.QueryBreakdown.sln'
|
||||
|
||||
if (-not (Get-Command dotnet-sonarscanner -ErrorAction SilentlyContinue)) {
|
||||
Write-Host "Installing dotnet-sonarscanner..." -ForegroundColor Cyan
|
||||
dotnet tool install --global dotnet-sonarscanner
|
||||
}
|
||||
|
||||
Write-Host "Cleaning previous coverage artifacts..." -ForegroundColor Cyan
|
||||
Get-ChildItem -Path tests -Directory -Filter TestResults -Recurse -ErrorAction SilentlyContinue |
|
||||
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
|
||||
|
||||
Write-Host "sonarscanner begin..." -ForegroundColor Cyan
|
||||
dotnet sonarscanner begin `
|
||||
/k:$projectKey `
|
||||
/d:sonar.host.url=$sonarHost `
|
||||
/d:sonar.token=$env:SONAR_TOKEN `
|
||||
/d:sonar.cs.opencover.reportsPaths="tests/**/TestResults/**/coverage.opencover.xml" `
|
||||
/d:sonar.exclusions="**/bin/**,**/obj/**" `
|
||||
/d:sonar.coverage.exclusions="tests/**,**/*.Tests/**" `
|
||||
/d:sonar.scanner.scanAll=false
|
||||
if ($LASTEXITCODE -ne 0) { throw "sonarscanner begin failed ($LASTEXITCODE)" }
|
||||
|
||||
Write-Host "dotnet build..." -ForegroundColor Cyan
|
||||
dotnet build $solution --configuration Release
|
||||
if ($LASTEXITCODE -ne 0) { throw "build failed ($LASTEXITCODE)" }
|
||||
|
||||
Write-Host "dotnet test (with coverage)..." -ForegroundColor Cyan
|
||||
dotnet test $solution `
|
||||
--configuration Release --no-build `
|
||||
--settings coverlet.runsettings `
|
||||
--collect "XPlat Code Coverage"
|
||||
# don't throw on test failures — we still want the analysis to upload
|
||||
if ($LASTEXITCODE -ne 0) { Write-Warning "some tests failed (exit $LASTEXITCODE); continuing so issues still upload" }
|
||||
|
||||
Write-Host "sonarscanner end..." -ForegroundColor Cyan
|
||||
dotnet sonarscanner end /d:sonar.token=$env:SONAR_TOKEN
|
||||
if ($LASTEXITCODE -ne 0) { throw "sonarscanner end failed ($LASTEXITCODE)" }
|
||||
|
||||
Write-Host "Done. Open $sonarHost/dashboard?id=$projectKey" -ForegroundColor Green
|
||||
Reference in New Issue
Block a user