Skip to content

Commit 4bb8f77

Browse files
committed
feat: add SonarQube server configuration script and update settings
1 parent 57eca80 commit 4bb8f77

5 files changed

Lines changed: 467 additions & 160 deletions

File tree

.vscode/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,9 @@
1111
"eslint.format.enable": false,
1212
"editor.codeActionsOnSave": {
1313
"source.fixAll.eslint": "never"
14+
},
15+
"sonarlint.connectedMode.project": {
16+
"connectionId": "http-192-168-2-50-9005",
17+
"projectKey": "xConfig"
1418
}
1519
}

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ direkt zu einer versionierten Release-Sektion.
2222
### Fixed
2323

2424
- Nutzerwirkung: Keine beabsichtigte sichtbare Verhaltensänderung; Theme-Mounting, Checkout-Board-Ziele sowie die Cricket-Wrapper für Highlighting und Grid-FX laufen auf denselben fachlichen Pfaden weiter, sind intern aber in dieser Sonar-Welle klarer in Status- und Aktivierungsblöcke getrennt.
25-
Technik: `mount-theme-feature`, `checkout-board-targets`, `cricket-highlighter` und `cricket-grid-fx` ziehen kleine Aktivierungs-, Renderstatus- und Nicht-Ready-Statuspfade jetzt in lokale Helper, ohne öffentliche Signaturen oder die beobachtbare Overlay-/Lifecycle-Semantik zu ändern; die bestehenden Theme-, Lifecycle-, Runtime-Performance- und Degraded-Host-Regressionen sichern diese Wrapper-Refactors gegen Drift ab.
25+
Technik: `mount-theme-feature`, `checkout-board-targets`, `cricket-highlighter` und `cricket-grid-fx` ziehen kleine Aktivierungs-, Renderstatus- und Nicht-Ready-Statuspfade jetzt in lokale Helper; `mount-theme-feature` kapselt zusätzlich Theme-Evaluator und Mutation-Callback in eigene lokale Fabriken, ohne öffentliche Signaturen oder die beobachtbare Overlay-/Lifecycle-Semantik zu ändern. Die bestehenden Theme-, Lifecycle-, Runtime-Performance- und Degraded-Host-Regressionen sichern diese Wrapper-Refactors gegen Drift ab.
2626

2727
- Nutzerwirkung: Keine beabsichtigte sichtbare Verhaltensänderung; ausgewählte Board-, Sweep- und Trend-Animationen sowie der interne Changelog-Check laufen auf denselben fachlichen Pfaden weiter, sind aber in dieser Sonar-Welle klarer und direkter ausgedrückt.
2828
Technik: Die vier `void`-basierten Reflow-Trigger in `average-trend-arrow`, `turn-start-sweep` und `cricket-grid-fx` verwenden jetzt explizite lokale Reflow-Helfer statt des `void`-Operators, das kleine `S3776` in `scripts/check-changelog-consistency.mjs` wurde nur durch lokale Helper-Aufteilung reduziert, und neue direkte Runtime-Tests sichern die Re-Trigger-/Cleanup-Verträge der Sweep- und Trend-Animationen auf dem Fake-DOM gegen Drift ab.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# SonarQube Server Config For autodarts-xconfig
2+
3+
Date: `2026-04-19`
4+
Project key: `xConfig`
5+
Project name: `autodarts-xconfig`
6+
JS profile: `autodarts-xconfig JS`
7+
8+
## Applied Live On Server
9+
10+
The following changes were applied directly on the SonarQube server:
11+
12+
- Deactivated `javascript:S2486`
13+
- Deactivated `javascript:S7764`
14+
- Deactivated `javascript:S7785`
15+
- Deactivated `javascript:S7761`
16+
- Deactivated `javascript:S1940`
17+
- Updated `javascript:S3776` to severity `MAJOR` with threshold `25`
18+
- Updated `javascript:S2004` to severity `MAJOR` with max nesting `4`
19+
- Updated `javascript:S6582` to severity `MINOR`
20+
- Set `sonar.exclusions` to:
21+
`dist/**`, `src/legacy-backups/**`, `src/vendors/anime.min.cjs`, `src/vendors/canvas-confetti.browser.js`
22+
- Set `sonar.cpd.exclusions` to:
23+
`src/vendors/**`, `src/legacy-backups/**`
24+
- Set `sonar.coverage.exclusions` to:
25+
`loader/**`, `scripts/**`, `src/vendors/**`, `src/legacy-backups/**`
26+
27+
## Verified Outcome
28+
29+
After a fresh Sonar analysis:
30+
31+
- Open issues dropped from `259` to `117`
32+
- Open `CRITICAL` issues dropped from `10` to `0`
33+
- JS profile active rule count is now `375`
34+
- Quality gate remains `OK`
35+
36+
## Intentional Non-Changes
37+
38+
The following were intentionally left unchanged:
39+
40+
- Quality gate conditions
41+
- New code definition
42+
- CSS profile
43+
- HTML profile
44+
45+
Reason:
46+
47+
- The current gate already focuses on new code and remains stable after the rule cleanup.
48+
- Coverage import is still `0.0`, so adding a coverage gate now would create noise rather than value.
49+
- The repository is overwhelmingly JS/MJS. Standalone CSS/HTML analysis is currently marginal for this project.
50+
51+
## Reapply Script
52+
53+
Use [apply-xconfig-server-config.ps1](/c:/Users/thoma/Documents/Development/autodarts-xconfig/ops/sonarqube/apply-xconfig-server-config.ps1) to reapply the same server changes.
54+
55+
Example:
56+
57+
```powershell
58+
$env:SONARQUBE_URL = "http://your-sonarqube-server:9000"
59+
$env:SONARQUBE_TOKEN = "your-token"
60+
61+
pwsh ./ops/sonarqube/apply-xconfig-server-config.ps1 `
62+
-SonarQubeUrl $env:SONARQUBE_URL `
63+
-SonarQubeToken $env:SONARQUBE_TOKEN `
64+
-RunAnalysis
65+
```
66+
67+
## Next Sensible Step
68+
69+
Do not add a coverage threshold in SonarQube until coverage reports are actually imported.
70+
71+
When coverage import is ready, the next server-side change should be:
72+
73+
- add `sonar.javascript.lcov.reportPaths`
74+
- then add a new-code coverage condition to the quality gate
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
param(
2+
[Parameter(Mandatory = $true)]
3+
[string]$SonarQubeUrl,
4+
5+
[Parameter(Mandatory = $true)]
6+
[string]$SonarQubeToken,
7+
8+
[string]$ProjectKey = "xConfig",
9+
[string]$JsProfileName = "autodarts-xconfig JS",
10+
[switch]$RunAnalysis
11+
)
12+
13+
$ErrorActionPreference = "Stop"
14+
15+
function New-AuthHeader {
16+
param([string]$Token)
17+
18+
$pair = "${Token}:"
19+
$base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($pair))
20+
return @{ Authorization = "Basic $base64" }
21+
}
22+
23+
function Invoke-SonarPost {
24+
param(
25+
[hashtable]$Headers,
26+
[string]$BaseUrl,
27+
[string]$Path,
28+
[hashtable]$Body
29+
)
30+
31+
Invoke-RestMethod -Headers $Headers -Method Post -Uri "$BaseUrl$Path" -Body $Body | Out-Null
32+
}
33+
34+
function Set-SonarMultiValue {
35+
param(
36+
[hashtable]$Headers,
37+
[string]$BaseUrl,
38+
[string]$Project,
39+
[string]$SettingKey,
40+
[string[]]$Values
41+
)
42+
43+
$parts = @(
44+
"component=$([uri]::EscapeDataString($Project))",
45+
"key=$([uri]::EscapeDataString($SettingKey))"
46+
)
47+
48+
foreach ($value in $Values) {
49+
$parts += "values=$([uri]::EscapeDataString($value))"
50+
}
51+
52+
$body = [string]::Join("&", $parts)
53+
54+
Invoke-RestMethod `
55+
-Headers $Headers `
56+
-Method Post `
57+
-ContentType "application/x-www-form-urlencoded" `
58+
-Uri "$BaseUrl/api/settings/set" `
59+
-Body $body | Out-Null
60+
}
61+
62+
$baseUrl = $SonarQubeUrl.TrimEnd("/")
63+
$headers = New-AuthHeader -Token $SonarQubeToken
64+
65+
$profiles = Invoke-RestMethod -Headers $headers -Uri "$baseUrl/api/qualityprofiles/search?project=$ProjectKey"
66+
$jsProfile = $profiles.profiles | Where-Object { $_.language -eq "js" -and $_.name -eq $JsProfileName } | Select-Object -First 1
67+
68+
if (-not $jsProfile) {
69+
throw "JS quality profile '$JsProfileName' for project '$ProjectKey' was not found."
70+
}
71+
72+
$profileKey = $jsProfile.key
73+
74+
Set-SonarMultiValue -Headers $headers -BaseUrl $baseUrl -Project $ProjectKey -SettingKey "sonar.exclusions" -Values @(
75+
"dist/**",
76+
"src/legacy-backups/**",
77+
"src/vendors/anime.min.cjs",
78+
"src/vendors/canvas-confetti.browser.js"
79+
)
80+
81+
Set-SonarMultiValue -Headers $headers -BaseUrl $baseUrl -Project $ProjectKey -SettingKey "sonar.cpd.exclusions" -Values @(
82+
"src/vendors/**",
83+
"src/legacy-backups/**"
84+
)
85+
86+
Set-SonarMultiValue -Headers $headers -BaseUrl $baseUrl -Project $ProjectKey -SettingKey "sonar.coverage.exclusions" -Values @(
87+
"loader/**",
88+
"scripts/**",
89+
"src/vendors/**",
90+
"src/legacy-backups/**"
91+
)
92+
93+
$deactivateRules = @(
94+
"javascript:S2486",
95+
"javascript:S7764",
96+
"javascript:S7785",
97+
"javascript:S7761",
98+
"javascript:S1940"
99+
)
100+
101+
foreach ($rule in $deactivateRules) {
102+
Invoke-SonarPost -Headers $headers -BaseUrl $baseUrl -Path "/api/qualityprofiles/deactivate_rule" -Body @{
103+
key = $profileKey
104+
rule = $rule
105+
}
106+
}
107+
108+
Invoke-SonarPost -Headers $headers -BaseUrl $baseUrl -Path "/api/qualityprofiles/activate_rule" -Body @{
109+
key = $profileKey
110+
rule = "javascript:S3776"
111+
severity = "MAJOR"
112+
params = "threshold=25"
113+
}
114+
115+
Invoke-SonarPost -Headers $headers -BaseUrl $baseUrl -Path "/api/qualityprofiles/activate_rule" -Body @{
116+
key = $profileKey
117+
rule = "javascript:S2004"
118+
severity = "MAJOR"
119+
params = "max=4"
120+
}
121+
122+
Invoke-SonarPost -Headers $headers -BaseUrl $baseUrl -Path "/api/qualityprofiles/activate_rule" -Body @{
123+
key = $profileKey
124+
rule = "javascript:S6582"
125+
severity = "MINOR"
126+
}
127+
128+
if ($RunAnalysis) {
129+
$env:SONAR_HOST_URL = $baseUrl
130+
$env:SONAR_TOKEN = $SonarQubeToken
131+
sonar-scanner
132+
}
133+
134+
$summary = [ordered]@{
135+
project = $ProjectKey
136+
jsProfile = $JsProfileName
137+
activeRuleCount = (Invoke-RestMethod -Headers $headers -Uri "$baseUrl/api/qualityprofiles/search?project=$ProjectKey").profiles |
138+
Where-Object { $_.language -eq "js" -and $_.name -eq $JsProfileName } |
139+
Select-Object -ExpandProperty activeRuleCount
140+
settings = Invoke-RestMethod -Headers $headers -Uri "$baseUrl/api/settings/values?component=$ProjectKey&keys=sonar.exclusions,sonar.cpd.exclusions,sonar.coverage.exclusions"
141+
}
142+
143+
$summary | ConvertTo-Json -Depth 8

0 commit comments

Comments
 (0)