Skip to content

Run the test suite against both deployment modes (full and lean) in CI#154

Merged
CarsonDavis merged 14 commits into
developmentfrom
tests-both-modes-ci
Jul 1, 2026
Merged

Run the test suite against both deployment modes (full and lean) in CI#154
CarsonDavis merged 14 commits into
developmentfrom
tests-both-modes-ci

Conversation

@CarsonDavis

@CarsonDavis CarsonDavis commented Jun 17, 2026

Copy link
Copy Markdown

What this does

MMGIS ships in two shapes from one codebase, selected by MMGIS_DEPLOYMENT_MODE: the full application, and a lean deployment that turns a set of server features off (geodata management, drawing, the bundled sidecar services, the on-disk mission filesystem, the link shortener, server-side raster utilities) and the dashboard publish flow on. Today CI exercises essentially one of those shapes — a change that breaks the other can pass CI and reach production.

This runs the e2e/boot suite once per shape and adds checks that verify the right features are present or absent in each mode, so a change that breaks either shape fails CI before merge. It's also the safety net for the planned (separate) gating-consolidation refactor, whose "no behavior change" claim is only trustworthy if the tests already run both modes.

Implements #151.

Changes

CI / test / docs only — no application or runtime source changed.

  • CI matrix. Split the workflow into a single unit job (Vitest, no DB/browser — it already covers both modes via require-cache busting, so it isn't matrixed) and a matrixed e2e job over mode: [full, lean]. The mode is written into .env and surfaced in the job name (e2e (full) / e2e (lean)) and per-mode artifact names.
  • Present/absent check (tests/e2e/deployment-mode.spec.js). A hand-written feature inventory (independent of any capability table — that independence is the point) asserting each full-only feature is reachable in full and gone in lean, and the lean-only dashboard publish flow the reverse. One loop covers both directions. Discriminator: a mounted route answers non-404; an unmounted one falls through to the catch-all 404. This step has no continue-on-error, so mis-gating a feature turns the leg red.
  • Mode reaches the test runner (playwright.config.js). The Playwright config loads .env (via dotenv, mirroring scripts/server.js) so the test process sees MMGIS_DEPLOYMENT_MODE. Without it the spec defaults to full and the lean leg silently tests the wrong mode.
  • Tables-exist check (tests/ci/assert-gated-tables.js). Features gated off in a mode still have their DB tables, because model registration + sync run unconditionally on boot and only route mounts are gated (the minimal-divergence gating from ADR D2 — models aren't per-mode-gated). This check pins that invariant — a change that accidentally gates model registration or drops a model fails CI. Asserted via the same getBackendSetups + sync path the server uses.
  • Honest lean leg. The lean leg disables the sidecar WITH_* flags so init-db and boot succeed without the services lean doesn't deploy (no sidecars, no spatial-catalog DB).
  • Short contributor note in README.md: two modes exist; author in full first, then confirm lean.

Verification

Booted both modes locally and ran the new checks:

Check full lean
present/absent spec (8 features) ✅ 8/8 ✅ 8/8
app boots ✅ (sidecar spawner + proxy disabled, no STAC DB)
gated tables exist ✅ (6 table groups, fresh DB)

Full-only routes return non-404 in full / 404 in lean; /api/deployments (publish flow) is the reverse. npx vitest run stays green (669/669).

Notes for reviewers

  • One focused CI/test-coverage PR; it carries no application-code change of its own. It is the prerequisite for the separate gating-consolidation refactor (not included here).
  • Rebased on current development (already includes the merged Run unit tests in a jsdom environment via Vitest #150); no stacked prerequisites remain.
  • The legacy smoke/eventbus e2e specs remain gating (no continue-on-error), matching their behavior on development; the split into their own step is organizational only. The new mode-shape and tables checks are also gating.

Closes #151

#151)

Add a [full, lean] deployment-mode matrix to the e2e/boot CI leg and the
checks that make a mode-specific break fail CI before merge:

- Split CI into a single hermetic unit job (vitest) and a matrixed e2e
  job; surface the mode in job and artifact names.
- New tests/e2e/deployment-mode.spec.js: a hand-written feature inventory
  asserting each full-only feature is reachable in full and gone in lean,
  and the lean-only dashboard publish flow the reverse. One loop covers
  both directions. The gating step has no continue-on-error, so a
  mis-gated feature turns the leg red (acceptance #5).
- New tests/ci/assert-gated-tables.js: gated-off features still have their
  DB tables in each mode (model sync is unconditional; only route mounts
  are gated), so a later mode flip needs no data migration (acceptance #4).
- Lean leg disables the sidecar WITH_* flags so init-db and boot succeed
  without the services lean doesn't deploy (acceptance #3).
- Short two-mode contributor note in README and AGENTS (author in full
  first, then confirm lean).

No application/runtime source changes. Verified locally: both legs' spec
passes 8/8, lean boots sidecar-free, and the gated tables exist in lean.
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we upgrade this version?

@CarsonDavis

Copy link
Copy Markdown
Author

Question: what are the ramifications of having the lean tests be the baseline tests and then the full tests import them? will that be cleaner than the current strategy?

Comment on lines +105 to +109
echo "WITH_STAC=false" >> .env
echo "WITH_TIPG=false" >> .env
echo "WITH_TITILER=false" >> .env
echo "WITH_TITILER_PGSTAC=false" >> .env
echo "WITH_VELOSERVER=false" >> .env

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a heads up to other reviewers, this is being simplified in #155, which depends on this PR for it's tests

The 'Acceptance #N' prefixes pointed at a numbered list that lives
nowhere in the repo and read like GitHub issue links. The comments
already explain their steps inline, so the prefixes only added
confusion. Also trim a redundant restated-step-name sentence.
Cut the 30-line header to ~14: drop the dangling 'Acceptance #4'
cross-ref, the both-legs/union paragraph (already explained inline at
the table list), and the obvious exit-code line. Keep only what a
reader can't infer from the code — why gated-off features still need
tables, and the postgis-before-sync ordering trap.
Cut the dangling 'acceptance #2' ref and the redundant full/lean
re-definition (that lives in AGENTS.md). Kept the two parts that earn
their space: the hand-written-inventory warning (independence from the
capability table is what makes the test trustworthy) and the
present-vs-absent 404 discriminator the assertions rely on.
…label

'Guards a both-modes invariant' announced a rule instead of stating it.
Open with the concrete requirement (gated-off features keep their DB
tables) so line 1 says the thing, no 'invariant' to decode first.
…invariant, not migration

The both-modes tables-exist check and the lean docs justified gated-off tables
as 'so a mode flip needs no migration.' That reason doesn't hold: deployments
never switch modes, and sequelize.sync() is additive and runs every boot. Reword
to the accurate framing — only route mounts are gated; models register and sync
unconditionally (ADR D2: keep, env-gated), so gated-off tables are created but
unused. assert-gated-tables.js pins exactly that invariant (catches a model
accidentally gated or dropped). Docs/comments only; no behavior change.
Base automatically changed from tests-stale-fixes to tests-jsdom June 30, 2026 15:41
Base automatically changed from tests-jsdom to development June 30, 2026 19:23
@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown

✅ Version Already Updated

This PR includes a manual version update to 4.2.13-20260701

No automatic version bump needed.

@CarsonDavis
CarsonDavis requested a review from sandesh-sp July 1, 2026 03:39
Trim verbose comments to terse notes; keep the non-obvious rationale (ADR-independent mapping, mounted-vs-404 discriminator, init-db ordering) and drop restated prose. Comments only; no behavior change.
deployment-mode.spec.js reads MMGIS_DEPLOYMENT_MODE from process.env, but the Playwright runner never loaded .env — so the spec defaulted to 'full' and the lean CI leg tested the wrong mode (all assertions failed). Mirror scripts/server.js by loading dotenv in the config. Verified via --list: the spec now resolves MODE=lean from .env.
They ran gated on development (no continue-on-error). The matrix split
accidentally added continue-on-error: true, silently downgrading their
coverage. Restore gating so a real regression fails the leg; they also
now confirm smoke + event bus pass under lean, not just full.
@CarsonDavis
CarsonDavis merged commit 0212493 into development Jul 1, 2026
7 checks passed
@CarsonDavis
CarsonDavis deleted the tests-both-modes-ci branch July 1, 2026 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Run the test suite against both deployment modes (full and lean) in CI

3 participants