Adds SlpModularCms.Api.SlpSoftware and extracts shared CmsHost composition #9
@@ -128,12 +128,37 @@ jobs:
|
|||||||
needs: [changes, backend-build]
|
needs: [changes, backend-build]
|
||||||
if: needs.changes.outputs.backend == 'true'
|
if: needs.changes.outputs.backend == 'true'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
# Added for SlpModularCms.Api.Tests (slpsoftware-api feature, NFR-CS-01): its pipeline
|
||||||
|
# regression tests boot the real Api host via WebApplicationFactory, which unconditionally
|
||||||
|
# runs CmsHost.ConfigurePipeline's startup migration (MigrateCoreDatabase) -- unlike every
|
||||||
|
# other test project here, which mocks/uses EF Core InMemory and never touches a real
|
||||||
|
# database. Without a real, reachable MariaDB, those tests fail on the connection itself
|
||||||
|
# before any assertion runs.
|
||||||
|
services:
|
||||||
|
mariadb:
|
||||||
|
image: mariadb:11
|
||||||
|
env:
|
||||||
|
MARIADB_ROOT_PASSWORD: ci_test_password
|
||||||
|
MARIADB_DATABASE: SlpModularCms
|
||||||
|
ports:
|
||||||
|
- 3306:3306
|
||||||
|
options: >-
|
||||||
|
--health-cmd="mysqladmin ping --silent"
|
||||||
|
--health-interval=10s
|
||||||
|
--health-timeout=5s
|
||||||
|
--health-retries=5
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-dotnet@v4
|
- uses: actions/setup-dotnet@v4
|
||||||
with:
|
with:
|
||||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||||
- name: Test (Release)
|
- name: Test (Release)
|
||||||
|
env:
|
||||||
|
# Overrides the placeholder in SlpModularCms.Api/appsettings.Development.json for this
|
||||||
|
# CI run only -- ASP.NET Core's configuration layering applies environment variables
|
||||||
|
# after appsettings.*.json, so this reaches SlpModularCms.Api.Tests' WebApplicationFactory
|
||||||
|
# without touching any committed appsettings file.
|
||||||
|
ConnectionStrings__DefaultConnection: "Server=127.0.0.1;Port=3306;Database=SlpModularCms;Uid=root;Pwd=ci_test_password"
|
||||||
run: dotnet test SlpModularCms.sln -c Release
|
run: dotnet test SlpModularCms.sln -c Release
|
||||||
|
|
||||||
# --- Gate 3: vulnerability scan ---
|
# --- Gate 3: vulnerability scan ---
|
||||||
|
|||||||
@@ -563,3 +563,15 @@
|
|||||||
**Context**: Local dev/test database only, explicitly requested by the user, low-risk and reversible (test data). Returning to the Unit 1 Code Generation approval gate.
|
**Context**: Local dev/test database only, explicitly requested by the user, low-risk and reversible (test data). Returning to the Unit 1 Code Generation approval gate.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## CI Fix: backend-test Had No Database for the New Pipeline Tests
|
||||||
|
|
||||||
|
**Timestamp**: 2026-08-02T12:00:00Z
|
||||||
|
|
||||||
|
**User Input**: Pasted the Gitea Actions `backend-test` job log — all 4 `SlpModularCms.Api.Tests` failed with `MySqlException: Access denied for user 'root'@'localhost'`.
|
||||||
|
|
||||||
|
**AI Response**: "Read `.gitea/workflows/continuous_integration.yaml`'s `backend-test` job: it runs `dotnet test SlpModularCms.sln -c Release` with no MariaDB service container at all — every other test project (Core.Tests, Module.*.Tests) mocks or uses EF Core InMemory and never needed one. The new `SlpModularCms.Api.Tests` boots the real `Api` host via `WebApplicationFactory`, which unconditionally runs `CmsHost.ConfigurePipeline`'s startup migration -- there is no way to exercise the real pipeline (this unit's whole NFR-CS-01 point) without a real, reachable database, and CI never had one. This is a design gap in the original NFR Requirements/Design for this unit, not something introduced by a later change -- should have been anticipated when Q1=C committed to a real WebApplicationFactory test rather than a fully mocked one. Added a `mariadb` service container to the `backend-test` job plus a `ConnectionStrings__DefaultConnection` environment-variable override for the test step only, which overrides the placeholder in `Api/appsettings.Development.json` via ASP.NET Core's standard configuration layering (env vars win over appsettings.*.json) -- no committed appsettings file changes needed, and zero effect on local `dotnet test` runs (developers' own `appsettings.local.json` continues to apply there, unaffected by a CI-only env var). Verified the override mechanism works by reproducing it locally against the existing local MariaDB container before trusting it in CI."
|
||||||
|
|
||||||
|
**Context**: Real bug fix, and a boundary call: `.gitea/workflows/continuous_integration.yaml` is nominally owned by the `gitea-deployment-workflow` feature, but this specific change (making the `backend-test` gate pass for a test project this feature introduced) is Construction/Build-and-Test correctness for `slpsoftware-api`, not a deploy-target retarget (D-15, still deferred to Operations) -- judged in-scope to fix directly rather than blocking the PR on a separate feature's process.
|
||||||
|
|
||||||
|
---
|
||||||
|
|||||||
+6
@@ -43,6 +43,12 @@ Added (frontend, not part of the original per-unit plan, but a direct, symmetric
|
|||||||
|
|
||||||
Pre-existing bug, unrelated to this feature's own scope (not introduced by the `CmsHost` extraction) but surfaced by testing the new instance: `src/SlpModularCms.Core/Exceptions/GlobalExceptionHandler.cs` logged every exception at `LogError` before mapping it to a status code, so a routine `UnauthorizedException` (e.g. an invalid/missing refresh token — the normal state for a fresh, never-logged-in session) was indistinguishable from a genuine unhandled 500 in the console and in Sentry. Fixed: exceptions that map to a status below 500 now log at `LogWarning`; only genuinely unmapped exceptions (500) log at `LogError`. Affects every Client project equally (`Api`, `Api.Slave`, `Api.SlpSoftware`), not just this feature. No existing test asserted log level; full suite reran green (196 + 4).
|
Pre-existing bug, unrelated to this feature's own scope (not introduced by the `CmsHost` extraction) but surfaced by testing the new instance: `src/SlpModularCms.Core/Exceptions/GlobalExceptionHandler.cs` logged every exception at `LogError` before mapping it to a status code, so a routine `UnauthorizedException` (e.g. an invalid/missing refresh token — the normal state for a fresh, never-logged-in session) was indistinguishable from a genuine unhandled 500 in the console and in Sentry. Fixed: exceptions that map to a status below 500 now log at `LogWarning`; only genuinely unmapped exceptions (500) log at `LogError`. Affects every Client project equally (`Api`, `Api.Slave`, `Api.SlpSoftware`), not just this feature. No existing test asserted log level; full suite reran green (196 + 4).
|
||||||
|
|
||||||
|
## Post-Completion Fix: CI's backend-test Job Had No Database
|
||||||
|
|
||||||
|
The Gitea Actions `backend-test` job (`.gitea/workflows/continuous_integration.yaml`) just ran `dotnet test` with no MariaDB service — every pre-existing test project mocks or uses EF Core InMemory, so none of them ever needed one. `SlpModularCms.Api.Tests` boots the real `Api` host via `WebApplicationFactory`, which unconditionally runs the startup migration, so it genuinely needs a reachable database — a design gap in this unit's own NFR Requirements/Design that should have been anticipated when committing to a real pipeline test (Q1 = C) rather than a mocked one. Fixed by adding a `mariadb` service container to `backend-test` plus a `ConnectionStrings__DefaultConnection` environment-variable override for that step only (overrides the placeholder in `Api/appsettings.Development.json` via standard ASP.NET Core config layering — env vars win over `appsettings.*.json`). No committed appsettings changed; local `dotnet test` runs are unaffected (developers' own `appsettings.local.json` still applies there). Verified the override mechanism directly against the local MariaDB container before trusting it in CI.
|
||||||
|
|
||||||
|
**Scope note**: `continuous_integration.yaml` is nominally owned by the `gitea-deployment-workflow` feature. This specific change (making the test gate pass for a test project this feature introduced) was judged in-scope to fix directly as Build-and-Test correctness — distinct from the actual deploy-target retarget (D-15), which remains deferred to this feature's own Operations phase.
|
||||||
|
|
||||||
## Build and Test Verification (Step 13.5)
|
## Build and Test Verification (Step 13.5)
|
||||||
|
|
||||||
Two real build fixes were needed and applied during this step (not deviations from the plan — the plan didn't anticipate these, since they only surface once the code actually compiles):
|
Two real build fixes were needed and applied during this step (not deviations from the plan — the plan didn't anticipate these, since they only surface once the code actually compiles):
|
||||||
|
|||||||
Reference in New Issue
Block a user