chore(ci): scan this repo with SonarQube (phase 4, slice 0) #7
Reference in New Issue
Block a user
No description provided.
Delete Branch "chore/sonarqube"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
First slice of module-system Phase 4 (docs#141 settles the phase's shape). Independent of the rest of it — this touches nothing the other four slices touch, and
module-uois the only repo Phase 4 changes outsidewebsite.Until now this was the one part of the platform that had never been scanned. The 75 files here arrived in the Phase 3 extraction and left their Sonar history behind in core's project, so a whole module's worth of shipped code has no dashboard at all.
Adds
sonar-project.properties(project keyModule-uo) and asonarqube.ymlmirroringwebsite's: push tomain, never a PR gate, nothing waiting on the quality gate.Two things differ from core's config
Both because this repo is shaped differently, not by preference:
src/to pointsonar.sourcesat — the server half keepsboot.js/core.js/index.jsatserver/root beside its subdirectories. So the whole tree is included and the non-source parts are excluded instead. That direction is deliberate: a new top-level server directory is scanned by default rather than silently unscanned, which is the safer way for the list to be wrong.server/scriptsandclient/scriptsare in, not out.checkImports.jsandcheckExternals.jsare the enforcement of MODULE_API.md §5.1 and §3.6, they each carry their own test suite, and both have already shipped defects a reviewer missed. Build code that decides whether a release is allowed out is not throwaway code.The build ordering is load-bearing here too
The workflow builds the client chunk before running either suite, for the reason
pr-checks.ymlalready spells out:build.test.jsandregistration.test.jsreaddist/entry.jsand skip without it. Run the other way round, this job reports coverage for a suite that quietly asked less than it looks like it did.Both suites run from the repo root rather than with
--prefix, so the LCOVSF:paths come out repo-root-relative and resolve againstsonar.sources. That is why the server suite's--requireis spelled out in the workflow instead of reusingnpm test --prefix server, whose path is relative toserver/.scripts/sonar-test-reporter.mjsis a copy of core's — SonarQube's "Unit Tests" measure is fed by a separate report from coverage, and without it the dashboard shows a coverage % against an empty Unit Tests tile. A pure leaf build helper, which is the side of the vendoring line that may be copied.Verified locally
Ran both coverage commands exactly as the workflow does:
The client's covered-file count is low and honestly so: most of
client/srcis JSX the DOM-less runner cannot import, which is a known and documented limit of this test harness rather than something this PR should paper over.Setup
The
Module-uoproject already exists on the SonarQube instance (confirmed against/api/projects/search— it sits alongsiderunic-gateway-website,Runic-Gateway-linkandRunic-Gateway-Android-app), so the key insonar-project.propertiesmatches a real dashboard and nothing needs creating.Still needed once, in the Gitea UI (Repo → Settings → Actions), unless they resolve from org-level settings:
SONAR_TOKEN— a SonarQube Analysis tokenSONAR_HOST_URLUntil both resolve the job runs and fails at the scan step, harmlessly — it gates nothing.
AI disclosure
🤖 Generated with Claude Code
Until now this was the one part of the platform that had never been scanned. The 75 files here arrived in the Phase 3 extraction and left their Sonar history behind in core's project, so a whole module's worth of shipped code has no dashboard at all. Adds sonar-project.properties (project key Module-uo) and a sonarqube.yml mirroring website's: push to main, never a PR gate, nothing waiting on the quality gate. Two things differ from core's config, both because this repo is shaped differently: - There is no src/ to point sonar.sources at — the server half keeps boot.js/core.js/index.js at server/ root beside its subdirectories — so the whole tree is included and the non-source parts are excluded. That direction is deliberate: a new top-level server directory is scanned by default rather than silently unscanned. - server/scripts and client/scripts are IN. checkImports.js and checkExternals.js are the enforcement of MODULE_API.md 5.1 and 3.6, they carry their own test suites, and both have already shipped defects a reviewer missed. Build code that decides whether a release is allowed out is not throwaway code. The workflow builds the client chunk before running either suite, for the reason pr-checks.yml already calls load-bearing: build.test.js and registration.test.js read dist/entry.js and SKIP without it, so the other order reports coverage for a suite that quietly asked less than it looks like it did. Both suites run from the repo root rather than with --prefix, so the LCOV SF: paths come out repo-root-relative and resolve against sonar.sources. That is why the server suite's --require is spelled out here instead of reusing `npm test --prefix server`, whose path is relative to server/. Verified locally: 385 server test cases across 57 covered files and 40 client cases, both LCOV and Generic Test Execution XML well-formed with repo-root-relative paths. Needs one-time setup in the Gitea UI before it can run — secret SONAR_TOKEN and variable SONAR_HOST_URL, same as the other repos. Co-Authored-By: Claude <noreply@anthropic.com>