mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
8dca372c47
Both only ran on a developer's machine, and both had stopped telling the truth. The end-to-end flows now run in CI in Chromium and in WebKit (the iPad and iPhone cases need the engine every iOS browser uses), with the browsers cached on the lockfile and the traces uploaded when a flow fails. A second job builds the client and fails when one chunk carries both map engines. Making them pass meant fixing what had rotted. The setup closed every first-run notice but the release notes, whose X is called Close, so the notes covered the dashboard and every flow after login timed out on a click. The iPad case still expected undraggable place rows; tablets drag on purpose since #1616, behind the long-press bridge, so it now checks what #1432 is about, a swipe that scrolls and raises no drop overlay, with locators for the scroller and the Plan tab that match today's markup. The iPhone case read the body scroll lock through window.scrollBy, which moves an overflow: hidden viewport in every engine; it now reads the lock where it takes effect and checks the page keeps its place.
622 lines
23 KiB
YAML
622 lines
23 KiB
YAML
name: Tests & SonarQube
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
# The repo's test/quality CI and SonarQube Cloud analysis in one workflow, so
|
|
# each test suite runs once per event instead of once for the old test.yml and
|
|
# once more for Sonar's coverage. Pushes to dev and main produce branch
|
|
# analysis; pull requests get PR analysis with decoration on the PR itself
|
|
# (the scanner picks the context up from the Actions environment).
|
|
#
|
|
# Job layout — three tiers:
|
|
# - Preflight: plugin-facts, i18n-parity and the quality jobs
|
|
# (server-quality, client-quality, plugin-sdk-quality) hold the cheap
|
|
# generated-code/typecheck/lint/smoke gates. Every test job `needs:` all
|
|
# of them, so a gate failure stops the run before the expensive coverage
|
|
# fan-out spends ~15 runner-minutes on a result the gates already sank.
|
|
# - Tests: the *-coverage jobs run the suites and upload lcov; s3-contract
|
|
# runs the MinIO contract suite. Coverage jobs run tests only — with the
|
|
# gates cleared in preflight, they can only fail because tests failed.
|
|
# client-e2e drives the real app in Chromium and WebKit, and client-bundle
|
|
# builds the client and checks each map engine keeps a chunk of its own.
|
|
# Neither feeds the scan.
|
|
# - Scan `needs:` exactly the four coverage jobs. A coverage job failing
|
|
# must stop the scan — a missing lcov file would make every line of that
|
|
# package report as uncovered, and the dashboard would show a collapse
|
|
# that did not happen. (The preflight gates stop it transitively.)
|
|
# - Fork PRs don't receive secrets, so the two jobs that need them skip
|
|
# themselves: s3-contract (MINIO_LICENSE_KEY) and scan (SONAR_TOKEN).
|
|
# Everything else runs on fork PRs so outside contributors still get the
|
|
# full test signal.
|
|
#
|
|
# Automatic Analysis must stay disabled on sonarcloud.io — it is mutually
|
|
# exclusive with CI-based analysis, and it cannot import the lcov coverage
|
|
# this workflow produces.
|
|
# A push or PR that touches none of these paths can't change the tests or the
|
|
# analysis, so don't spend the coverage fan-out on it. For a docs-only push
|
|
# that means no run and no fresh branch analysis — harmless, since the last
|
|
# analysis is still accurate for unchanged code. GitHub Actions doesn't
|
|
# support YAML anchors, so the two lists are literal copies: keep them
|
|
# identical when editing either one.
|
|
on:
|
|
push:
|
|
branches: [main, dev]
|
|
paths:
|
|
- 'server/**'
|
|
- 'client/**'
|
|
- 'shared/**'
|
|
- 'plugin-sdk/**'
|
|
# npm workspaces hoist every dependency into the single root lockfile,
|
|
# so a dependency bump touches none of the four directories above — and
|
|
# a native binding like better-sqlite3 is exactly what needs the suite.
|
|
- 'package.json'
|
|
- 'package-lock.json'
|
|
- 'sonar-project.properties'
|
|
- '.github/workflows/test.yml'
|
|
# The image's start-up shape is pinned by a unit test
|
|
# (server/tests/unit/docker-entrypoint.test.ts), so a change to the
|
|
# Dockerfile or to the entrypoint script has to run the suite — that is
|
|
# exactly the change the test exists to catch.
|
|
- 'Dockerfile'
|
|
- 'server/scripts/**'
|
|
# Docs inside the workspaces (CLAUDE.md, READMEs, PATTERN.md) affect
|
|
# neither the tests nor the scan — no test reads checked-in markdown
|
|
# and SonarCloud has no markdown analyzer. Negations must stay last.
|
|
- '!**/*.md'
|
|
pull_request:
|
|
branches: [main, dev]
|
|
paths:
|
|
- 'server/**'
|
|
- 'client/**'
|
|
- 'shared/**'
|
|
- 'plugin-sdk/**'
|
|
# npm workspaces hoist every dependency into the single root lockfile,
|
|
# so a dependency bump touches none of the four directories above — and
|
|
# a native binding like better-sqlite3 is exactly what needs the suite.
|
|
- 'package.json'
|
|
- 'package-lock.json'
|
|
- 'sonar-project.properties'
|
|
- '.github/workflows/test.yml'
|
|
# The image's start-up shape is pinned by a unit test
|
|
# (server/tests/unit/docker-entrypoint.test.ts), so a change to the
|
|
# Dockerfile or to the entrypoint script has to run the suite — that is
|
|
# exactly the change the test exists to catch.
|
|
- 'Dockerfile'
|
|
- 'server/scripts/**'
|
|
# Docs inside the workspaces (CLAUDE.md, READMEs, PATTERN.md) affect
|
|
# neither the tests nor the scan — no test reads checked-in markdown
|
|
# and SonarCloud has no markdown analyzer. Negations must stay last.
|
|
- '!**/*.md'
|
|
workflow_dispatch:
|
|
|
|
# A newer push to the same branch/PR supersedes the running one — cancel it
|
|
# rather than spending the coverage fan-out on a stale commit. Safe here
|
|
# because the Sonar scan job runs last and only the latest commit matters.
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
plugin-facts:
|
|
name: Plugin Permission Facts
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
# 22 matches the TREK server runtime (same choice as the plugin-sdk
|
|
# jobs and publish-plugin-sdk.yml).
|
|
node-version: 22
|
|
cache: npm
|
|
cache-dependency-path: package-lock.json
|
|
|
|
- name: Install dependencies
|
|
run: npm ci --workspace server
|
|
|
|
# The plugin permission facts live once, in
|
|
# server/src/nest/plugins/protocol/envelope.ts. Every other copy — the
|
|
# SDK's generated/host-facts.ts and shared's plugin-permissions.ts — is
|
|
# generated from it and checked in, because publish-plugin-sdk builds
|
|
# from a standalone checkout with no server present. This fails the run
|
|
# if a copy drifts, if a new permission has no admin.plugins.perm.*
|
|
# translation, or if the CLI has no hint for it.
|
|
- name: Check the generated plugin facts are in sync
|
|
run: cd server && npm run check:plugin-facts
|
|
|
|
i18n-parity:
|
|
name: i18n Key Parity
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Check i18n key parity
|
|
run: node shared/scripts/i18n-parity.mjs --strict
|
|
|
|
server-quality:
|
|
name: Server Types & Lint
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
cache: npm
|
|
cache-dependency-path: package-lock.json
|
|
|
|
- name: Install dependencies
|
|
run: npm ci
|
|
|
|
- name: Build shared
|
|
run: npm run build --workspace=shared
|
|
|
|
- name: Typecheck shared
|
|
# Rides along here rather than in shared-coverage: this job already
|
|
# pays the root install and shared build, and a coverage job may only
|
|
# fail because tests failed (it gates the scan).
|
|
run: cd shared && npm run typecheck
|
|
|
|
- name: Build server (tsc -> dist)
|
|
run: cd server && npm run build
|
|
|
|
- name: Smoke production require chain
|
|
# Vitest aliases the MCP SDK deep imports, so only this exercises what
|
|
# production runs: the built dist resolving the MCP SDK's subpath
|
|
# exports through the tsconfig-paths/register runtime hook.
|
|
run: cd server && node --require tsconfig-paths/register -e "require('./dist/nest-mcp')"
|
|
|
|
- name: Typecheck
|
|
run: cd server && npm run typecheck
|
|
|
|
- name: Typecheck tests
|
|
# tests/ is outside the build tsconfig, so a service that grows a
|
|
# constructor parameter does not break its hand-wired call sites at
|
|
# compile time: the argument arrives as undefined and throws at
|
|
# runtime, if anything reads it at all. This is the step that
|
|
# catches it.
|
|
run: cd server && npm run typecheck:tests
|
|
|
|
- name: Typecheck entity generator
|
|
# tsconfig.scripts.json covers generate-entities.ts and migrate-encryption.ts;
|
|
# gen-plugin-facts.ts uses import.meta and does not compile under this
|
|
# config (needs a newer --module target), so the gate is named for what
|
|
# it actually covers rather than the whole directory.
|
|
run: cd server && npm run typecheck:scripts
|
|
|
|
- name: Entity files match the generator
|
|
run: cd server && npm run check:entities
|
|
|
|
- name: Lint
|
|
# Type-aware rules build the src + tests program, which outgrows
|
|
# Node's default ~4 GB heap on the runner.
|
|
env:
|
|
NODE_OPTIONS: --max-old-space-size=8192
|
|
run: cd server && npm run lint:check
|
|
|
|
- name: DB call-graph gate (no sync DB-touching methods, no raw transactions)
|
|
run: cd server && npm run db:call-graph -- --sync --tx
|
|
|
|
client-quality:
|
|
name: Client Types & Lint
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
cache: npm
|
|
cache-dependency-path: package-lock.json
|
|
|
|
- name: Install dependencies
|
|
run: npm ci --workspace shared && npm ci --workspace client
|
|
|
|
- name: Build shared
|
|
run: npm run build --workspace=shared
|
|
|
|
- name: Typecheck
|
|
run: cd client && npm run typecheck
|
|
|
|
- name: Lint
|
|
run: cd client && npm run lint:check
|
|
|
|
- name: Page pattern check
|
|
run: cd client && npm run lint:pages
|
|
|
|
- name: Reading direction check
|
|
# Arabic runs right to left. A file may hold no more physical
|
|
# left/right classes and styles than scripts/rtl-baseline.json allows,
|
|
# so new code uses the logical start/end forms (scripts/rtl-lint.mjs).
|
|
run: cd client && npm run lint:rtl
|
|
|
|
plugin-sdk-quality:
|
|
name: Plugin SDK Types
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
defaults:
|
|
run:
|
|
working-directory: plugin-sdk
|
|
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 22
|
|
|
|
# plugin-sdk is standalone (own lockfile, not a root workspace), so it
|
|
# installs from its own directory.
|
|
- name: Install dependencies
|
|
run: npm ci
|
|
|
|
- name: Typecheck
|
|
run: npm run typecheck
|
|
|
|
client-bundle:
|
|
name: Client Bundle
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
needs: [plugin-facts, i18n-parity, server-quality, client-quality, plugin-sdk-quality]
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
cache: npm
|
|
cache-dependency-path: package-lock.json
|
|
|
|
- name: Install dependencies
|
|
run: npm ci --workspace shared && npm ci --workspace client
|
|
|
|
- name: Build shared
|
|
run: npm run build --workspace=shared
|
|
|
|
- name: Build client
|
|
run: cd client && npm run build
|
|
|
|
- name: Each map engine in a chunk of its own
|
|
# One static import of mapbox-gl or maplibre-gl in the map tree folds
|
|
# both engines into one chunk again, and nothing else notices: the build
|
|
# stays green and the app still works, only every map user downloads
|
|
# both. scripts/check-gl-split.mjs explains the markers it looks for.
|
|
run: cd client && npm run check:gl-split
|
|
|
|
client-e2e:
|
|
name: Client End-to-End
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
needs: [plugin-facts, i18n-parity, server-quality, client-quality, plugin-sdk-quality]
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
cache: npm
|
|
cache-dependency-path: package-lock.json
|
|
|
|
# The run boots the real server (e2e/server-launch.mjs builds it and
|
|
# starts it against a throwaway SQLite file) and the Vite dev server in
|
|
# front of it, so it needs every workspace.
|
|
- name: Install dependencies
|
|
run: npm ci
|
|
|
|
- name: Build shared
|
|
run: npm run build --workspace=shared
|
|
|
|
# Keyed on the lockfile, which pins @playwright/test and with it the
|
|
# browser builds. The system libraries the browsers need are not cached
|
|
# and are installed on every run.
|
|
- name: Cache browsers
|
|
id: browsers
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: ~/.cache/ms-playwright
|
|
key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
|
|
|
|
# Chromium for the desktop and phone flows, WebKit for the iPad and
|
|
# iPhone ones (every browser on iOS and iPadOS is WebKit underneath).
|
|
- name: Install browsers
|
|
if: steps.browsers.outputs.cache-hit != 'true'
|
|
run: cd client && npx playwright install --with-deps chromium webkit
|
|
|
|
- name: Install browser dependencies
|
|
if: steps.browsers.outputs.cache-hit == 'true'
|
|
run: cd client && npx playwright install-deps chromium webkit
|
|
|
|
# The public and app projects are the regression flows. The screenshot
|
|
# and help-media projects make pictures for the wiki and the help center
|
|
# and assert nothing, so they stay out of CI.
|
|
- name: Run the end-to-end flows
|
|
run: cd client && npx playwright test --project=public --project=app
|
|
|
|
- name: Upload traces
|
|
if: failure()
|
|
uses: actions/upload-artifact@v6
|
|
with:
|
|
name: e2e-results
|
|
path: client/test-results/
|
|
retention-days: 7
|
|
|
|
s3-contract:
|
|
name: S3 Driver Contract (MinIO)
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
needs: [plugin-facts, i18n-parity, server-quality, client-quality, plugin-sdk-quality]
|
|
# Fork PRs don't get repo secrets, so MINIO_LICENSE_KEY would be empty and
|
|
# the AIStor container would fail to boot. Pushes and manual dispatches do
|
|
# have secrets, so only fork PRs are filtered out. (The implicit success()
|
|
# on this expression also keeps the job skipped when a preflight fails.)
|
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
|
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
cache: npm
|
|
cache-dependency-path: package-lock.json
|
|
|
|
- name: Install dependencies
|
|
run: npm ci
|
|
|
|
- name: Ensure @swc/core's Linux binary for unplugin-swc
|
|
# The lockfile was generated on Windows and omits @swc/core's Linux
|
|
# optional native binary, so npm ci/install skips it on the runner.
|
|
# Install the matching version explicitly so the server's SWC transform
|
|
# (server/vitest.config.ts) can load.
|
|
run: |
|
|
SWC_VERSION=$(node -p "require('@swc/core/package.json').version")
|
|
npm install --no-save --legacy-peer-deps "@swc/core-linux-x64-gnu@$SWC_VERSION"
|
|
|
|
- name: Build shared
|
|
run: npm run build --workspace=shared
|
|
|
|
- name: Write MinIO license
|
|
run: printf '%s' "${{ secrets.MINIO_LICENSE_KEY }}" > minio-licence.key
|
|
|
|
- name: Start MinIO
|
|
# `services:` can't pass the `server /data --license ...` command to
|
|
# the AIStor image, so it starts via docker run. 127.0.0.1 endpoint is
|
|
# load-bearing: aws-lite picks path-style only for IP/localhost hosts,
|
|
# which is all stock MinIO/AIStor speaks.
|
|
run: |
|
|
docker run -d --name minio -p 127.0.0.1:9000:9000 \
|
|
-v "$PWD/minio-licence.key:/minio.license:ro" \
|
|
-e MINIO_ROOT_USER=trekci -e MINIO_ROOT_PASSWORD=trekci-secret \
|
|
quay.io/minio/aistor/minio:RELEASE.2026-08-07T18-34-35Z server /data --license /minio.license
|
|
|
|
- name: Wait for MinIO
|
|
# curl was removed from the AIStor image — poll from the runner instead.
|
|
# 60 x 2s gives a wider margin on cold runners than the 30 x 1s the
|
|
# pre-6fbff835 job used.
|
|
run: |
|
|
for i in $(seq 1 60); do
|
|
curl -sf http://127.0.0.1:9000/minio/health/live && exit 0
|
|
sleep 2
|
|
done
|
|
echo "MinIO never became healthy" >&2
|
|
docker logs minio >&2
|
|
exit 1
|
|
|
|
- name: Run the S3 driver contract suite
|
|
# No --coverage: the src/nest/storage/** 94/84/97/94 pin must keep
|
|
# holding from hermetic tests alone. The suite's beforeAll creates
|
|
# the trek-test bucket idempotently — no separate bucket-init step.
|
|
env:
|
|
TREK_TEST_S3_ENDPOINT: http://127.0.0.1:9000
|
|
TREK_TEST_S3_BUCKET: trek-test
|
|
TREK_TEST_S3_ACCESS_KEY_ID: trekci
|
|
TREK_TEST_S3_SECRET_ACCESS_KEY: trekci-secret
|
|
run: cd server && npx vitest run tests/unit/nest/storage/s3.driver.contract.test.ts
|
|
|
|
server-coverage:
|
|
name: Server Coverage
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
needs: [plugin-facts, i18n-parity, server-quality, client-quality, plugin-sdk-quality]
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
cache: npm
|
|
cache-dependency-path: package-lock.json
|
|
|
|
- name: Install dependencies
|
|
run: npm ci
|
|
|
|
- name: Ensure @swc/core's Linux binary for unplugin-swc
|
|
# The lockfile was generated on Windows and omits @swc/core's Linux
|
|
# optional native binary, so npm ci/install skips it on the runner.
|
|
# Install the matching version explicitly so the server's SWC transform
|
|
# (server/vitest.config.ts) can load.
|
|
run: |
|
|
SWC_VERSION=$(node -p "require('@swc/core/package.json').version")
|
|
npm install --no-save --legacy-peer-deps "@swc/core-linux-x64-gnu@$SWC_VERSION"
|
|
|
|
- name: Build shared
|
|
run: npm run build --workspace=shared
|
|
|
|
- name: Run tests with coverage
|
|
run: cd server && npm run test:coverage
|
|
|
|
- name: Upload coverage
|
|
uses: actions/upload-artifact@v6
|
|
with:
|
|
name: sonar-server-coverage
|
|
path: server/coverage/
|
|
retention-days: 1
|
|
|
|
client-coverage:
|
|
name: Client Coverage
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
needs: [plugin-facts, i18n-parity, server-quality, client-quality, plugin-sdk-quality]
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
cache: npm
|
|
cache-dependency-path: package-lock.json
|
|
|
|
# Only the shared and client workspaces — a full root npm ci is not
|
|
# needed, and the scoped install keeps @testing-library/dom (a peer of
|
|
# @testing-library/react) in the tree without the re-resolution dance
|
|
# the folded coverage job used to need.
|
|
- name: Install dependencies
|
|
run: npm ci --workspace shared && npm ci --workspace client
|
|
|
|
- name: Build shared
|
|
run: npm run build --workspace=shared
|
|
|
|
- name: Run tests with coverage
|
|
run: cd client && npm run test:coverage
|
|
|
|
- name: Upload coverage
|
|
uses: actions/upload-artifact@v6
|
|
with:
|
|
name: sonar-client-coverage
|
|
path: client/coverage/
|
|
retention-days: 1
|
|
|
|
shared-coverage:
|
|
name: Shared Coverage
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
needs: [plugin-facts, i18n-parity, server-quality, client-quality, plugin-sdk-quality]
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
cache: npm
|
|
cache-dependency-path: package-lock.json
|
|
|
|
- name: Install dependencies
|
|
run: npm ci --workspace shared
|
|
|
|
- name: Run tests with coverage
|
|
run: cd shared && npm run test:coverage
|
|
|
|
- name: Upload coverage
|
|
uses: actions/upload-artifact@v6
|
|
with:
|
|
name: sonar-shared-coverage
|
|
path: shared/coverage/
|
|
retention-days: 1
|
|
|
|
plugin-sdk-coverage:
|
|
name: Plugin SDK Coverage
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
needs: [plugin-facts, i18n-parity, server-quality, client-quality, plugin-sdk-quality]
|
|
defaults:
|
|
run:
|
|
working-directory: plugin-sdk
|
|
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
# 22 matches the TREK server runtime and has node:sqlite, which the
|
|
# dev-server tests exercise (same choice as publish-plugin-sdk.yml).
|
|
node-version: 22
|
|
|
|
# plugin-sdk is standalone (own lockfile, not a root workspace), so it
|
|
# installs from its own directory.
|
|
- name: Install dependencies
|
|
run: npm ci
|
|
|
|
- name: Run tests with coverage
|
|
run: npm run test:coverage
|
|
|
|
- name: Upload coverage
|
|
uses: actions/upload-artifact@v6
|
|
with:
|
|
name: sonar-plugin-sdk-coverage
|
|
path: plugin-sdk/coverage/
|
|
retention-days: 1
|
|
|
|
scan:
|
|
name: Scan
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
# Fork PRs don't receive SONAR_TOKEN — skip the scan rather than fail it.
|
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
|
# Coverage jobs failing must stop the scan: a missing lcov file would make
|
|
# every line of that package report as uncovered, and the dashboard would
|
|
# show a collapse that did not happen. The preflight gates already stop it
|
|
# transitively through these four, so they aren't repeated here.
|
|
needs: [server-coverage, client-coverage, shared-coverage, plugin-sdk-coverage]
|
|
|
|
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
|
|
|
|
- name: Download server coverage
|
|
uses: actions/download-artifact@v6
|
|
with:
|
|
name: sonar-server-coverage
|
|
path: server/coverage/
|
|
|
|
- name: Download client coverage
|
|
uses: actions/download-artifact@v6
|
|
with:
|
|
name: sonar-client-coverage
|
|
path: client/coverage/
|
|
|
|
- name: Download shared coverage
|
|
uses: actions/download-artifact@v6
|
|
with:
|
|
name: sonar-shared-coverage
|
|
path: shared/coverage/
|
|
|
|
- name: Download plugin-sdk coverage
|
|
uses: actions/download-artifact@v6
|
|
with:
|
|
name: sonar-plugin-sdk-coverage
|
|
path: plugin-sdk/coverage/
|
|
|
|
- name: Scan
|
|
uses: SonarSource/sonarqube-scan-action@v8
|
|
env:
|
|
# SonarQube Cloud is the scan action's default host, so no
|
|
# SONAR_HOST_URL — the token is a sonarcloud.io token for the
|
|
# liketrek org.
|
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
|
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
|