Files
TREK/.github/workflows/sonarqube.yml
T
Maurice fe5c6f182e fix(ci): restore the peer dep the swc install drops, and close a test race (#2040)
Two separate reasons v4.0.0 (#1719) is red.

The SonarQube workflow killed all 616 client test files with "Cannot find module
'@testing-library/dom'". That package is a peer dependency of
@testing-library/react and not a direct dependency of the client, and the step
that installs @swc/core's Linux binary passes --legacy-peer-deps, which tells npm
not to put peer dependencies back when it re-resolves the tree. In test.yml that
step lives in the server job, which never runs client tests, so folding the jobs
into one (#2039) is what brought the two together. It now installs alongside the
swc binary, with its version read from the peer range rather than pinned, and a
one-line resolve check right after fails fast with the module name instead of six
hundred identical failures twenty minutes later.

MAdminStoragePanel's FE-MOB-MSTOR-015 was a genuine race in the test, not in the
panel. Its POST handler incremented postCount, then awaited request.json(), and
only then pushed to migrationPosts — so between the two there was a window where
one POST had been counted but migrationPosts was still empty. The GET handler
reports `migrations: []` for an empty migrationPosts, i.e. "nothing running", so
a poll landing in that window told the queue it was free to start the second
migration, and the waitFor(postCount === 1) above could resolve inside it too.
Parsing before counting closes it. Verified by running the whole mobile suite at
--maxWorkers=8, where it used to surface.
2026-08-25 17:09:29 +02:00

103 lines
4.7 KiB
YAML

name: SonarQube
permissions:
contents: read
# Push to dev only, deliberately.
#
# The SonarQube instance is Community Edition, which has no branch or
# pull-request analysis: the project holds exactly one view. Analysing a feature
# branch would overwrite that view with the branch's numbers until somebody
# scanned dev again, so the one branch that may publish is the one everybody
# reads. workflow_dispatch stays available for a manual re-run.
on:
push:
branches: [dev]
workflow_dispatch:
jobs:
scan:
name: Coverage & Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
# Sonar reads git blame to date each issue and to decide what counts as
# new code. A shallow clone leaves it blind to both.
fetch-depth: 0
- uses: actions/setup-node@v6
with:
node-version: 24
cache: npm
cache-dependency-path: package-lock.json
- name: Install dependencies
run: npm ci
- name: Install plugin-sdk dependencies
# plugin-sdk is not a root workspace (workspaces = client, server, shared)
# — it ships as its own npm package with its own lockfile, so the root
# npm ci does not reach it. Its coverage is part of test:cov all the same.
run: cd plugin-sdk && npm ci
- name: Ensure @swc/core's Linux binary for unplugin-swc
# Same reason as test.yml: the lockfile was generated on Windows and omits
# @swc/core's Linux optional native binary, so npm ci skips it on the
# runner and the server's SWC transform cannot load.
#
# @testing-library/dom rides along, and has to. This install re-resolves
# the tree, and --legacy-peer-deps means npm does not put peer
# dependencies back — @testing-library/dom is a peer of
# @testing-library/react and not a direct dependency of the client, so it
# was silently dropped and all 616 client test files died on
# "Cannot find module". In test.yml this step lives in the server job,
# which never runs client tests, so the collision only appears once the
# jobs are folded into one. The version is read from the peer range rather
# than pinned here, so a bump to @testing-library/react carries over.
run: |
SWC_VERSION=$(node -p "require('@swc/core/package.json').version")
DOM_RANGE=$(node -p "require('@testing-library/react/package.json').peerDependencies['@testing-library/dom']")
npm install --no-save --legacy-peer-deps \
"@swc/core-linux-x64-gnu@$SWC_VERSION" \
"@testing-library/dom@$DOM_RANGE"
- name: Verify the test toolchain survived that install
# Cheap tripwire: if a future dependency bump loses another peer the same
# way, this fails here with the name of the module instead of 600
# identical test failures twenty minutes later.
run: node -e "require.resolve('@testing-library/dom'); require.resolve('@swc/core')"
- name: Build shared
# Only shared, not the root `build`. server and client run their suites
# from source through vitest, so building them would add a tsc pass and a
# full vite bundle that nothing here reads.
run: npm run build --workspace=shared
- name: Run tests with coverage
# One script for all four packages — it already ends with
# `--prefix plugin-sdk`. Each writes lcov to <pkg>/coverage/, which is
# where sonar.javascript.lcov.reportPaths looks. Without those files every
# line reports as uncovered and the dashboard shows a collapse that did
# not happen, so this step failing has to stop the scan rather than let it
# publish a false number.
run: npm run test:cov
- name: Scan
uses: SonarSource/sonarqube-scan-action@v8
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
with:
# New Code is configured as "previous version", so this string is what
# draws that line — changing it re-bases every "new code" metric.
# Pinned rather than read from package.json on purpose: package.json is
# still on 3.4.1 while the project has been analysed as 4.0.0 all along,
# and taking the lower number would silently move the baseline. Bump it
# here as part of the release, together with the version bump.
#
# Everything else — sources, tests, exclusions, the documented
# false-positive list — lives in sonar-project.properties so it stays
# reviewable in a PR rather than buried in workflow YAML.
args: -Dsonar.projectVersion=4.0.0