Applications, documents (+ audit log) and the brief move off static in-memory Dictionaries onto a real SQLite file via EF Core, so demo data survives a process restart or `docker compose restart api` for the first time. The three stores (ApplicationStore/DocumentStore/BriefStore) keep their exact public signatures and static-class shape — no DI, no async ripple into Program.cs's minimal-API handlers — each method just opens a short-lived AppDbContext via Db.Create() under the same lock it already had. Opaque nested shapes (a wizard's draft snapshot, a brief's sections/placeholders/status) are stored as JSON text columns rather than redesigned into relational tables, matching the existing "don't interpret it" posture. Found two things the WP's own text got wrong, corrected in docs/backlog/WP-22-durable-persistence.md's Deviations section: SeedData never seeded these three stores (only the read-only BRP/DUO-mimicking GETs, which stay in-memory) so there's no seed step; and no new docker-compose volume is needed since the existing bind mount already covers the SQLite file — verified against this environment's real podman-backed compose stack, not just by reading the file. Also: pinned SQLitePCLRaw.bundle_e_sqlite3 to 3.0.3 (EF Core Sqlite's own transitive default bundles a pre-3.50.2 SQLite with a known high-severity memory-corruption advisory); found and fixed a real xUnit test race where concurrent test-class hosts stomped a shared static connection-string field, fixed by disabling cross-class test parallelization rather than adding DI the stores don't otherwise need. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
132 lines
4.0 KiB
YAML
132 lines
4.0 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
tags: ['v*']
|
|
pull_request:
|
|
|
|
# Least privilege by default; the CodeQL job widens its own scope locally.
|
|
permissions:
|
|
contents: read
|
|
|
|
# A newer push to the same ref cancels the in-flight run.
|
|
concurrency:
|
|
group: ci-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
frontend:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 24
|
|
cache: npm
|
|
- run: npm ci
|
|
- run: npm run lint
|
|
- run: npm run format:check
|
|
- run: npm run check:tokens
|
|
- run: npm test
|
|
# --localize builds every configured locale (nl + en, angular.json's i18n
|
|
# block) in one pass; i18nMissingTranslation:"error" (angular.json) fails
|
|
# this step if messages.en.xlf is missing a unit the source (WP-20) gains.
|
|
- run: npx ng build --localize
|
|
# The shipped bundle must stay clean; dev-only advisories are excluded.
|
|
- run: npm audit --omit=dev
|
|
|
|
storybook-a11y:
|
|
# Axe runs against every story in the static build; a violation fails the build.
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 24
|
|
cache: npm
|
|
- run: npm ci
|
|
- run: npx playwright install --with-deps chromium
|
|
- run: npm run build-storybook
|
|
- run: npm run test-storybook:ci
|
|
|
|
backend:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: 10.0.x
|
|
- run: dotnet format backend/BigRegister.slnx --verify-no-changes
|
|
- run: dotnet test backend/BigRegister.slnx
|
|
|
|
e2e:
|
|
# Smoke-level Playwright run against the REAL FE+backend (WP-19) — a fresh
|
|
# runner checkout per run, so there's no bigregister.db (WP-22, gitignored)
|
|
# left over from a prior run to leak state in; the backend creates + migrates
|
|
# an empty one on this boot, same as a fresh clone always has.
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 24
|
|
cache: npm
|
|
- uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: 10.0.x
|
|
- run: npm ci
|
|
- run: npx playwright install --with-deps chromium
|
|
- run: dotnet run --project backend/src/BigRegister.Api --urls http://localhost:5000 &
|
|
- run: npx ng serve --proxy-config proxy.conf.json &
|
|
- run: npx wait-on http://localhost:5000/swagger http://localhost:4200
|
|
- run: npm run e2e
|
|
|
|
codeql:
|
|
# Static analysis (SAST) for both sides; results appear under the Security tab.
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 20
|
|
permissions:
|
|
security-events: write
|
|
contents: read
|
|
actions: read
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
language: [javascript-typescript, csharp]
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- if: matrix.language == 'csharp'
|
|
uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: 10.0.x
|
|
- uses: github/codeql-action/init@v3
|
|
with:
|
|
languages: ${{ matrix.language }}
|
|
- uses: github/codeql-action/autobuild@v3
|
|
- uses: github/codeql-action/analyze@v3
|
|
|
|
api-client-drift:
|
|
# The committed typed client must match the backend OpenAPI doc.
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 24
|
|
cache: npm
|
|
- uses: actions/setup-dotnet@v4
|
|
with:
|
|
# 8.0 for the bundled NSwag runtime, 10.0 to build/emit the spec.
|
|
dotnet-version: |
|
|
8.0.x
|
|
10.0.x
|
|
- run: npm ci
|
|
- run: npm run gen:api
|
|
- run: git diff --exit-code src/app/shared/infrastructure/api-client.ts backend/swagger.json
|