Skip to content

CI: smoke tests for scanner + dashboard render paths#29

Merged
jeftekhari merged 1 commit into
mainfrom
feat/ci-smoke-tests
Apr 18, 2026
Merged

CI: smoke tests for scanner + dashboard render paths#29
jeftekhari merged 1 commit into
mainfrom
feat/ci-smoke-tests

Conversation

@jeftekhari

Copy link
Copy Markdown
Contributor

Second open-source-readiness blocker: no CI beyond deploy. Closes that gap with a pair of smoke tests that run on every push and PR.

Why smoke tests, not tsc --noEmit

tsc --noEmit against the current tsconfig produces hundreds of pre-existing errors unrelated to real defects — the project uses tsx at runtime, which tolerates the verbatimModuleSyntax + no-@types/node combination that tsc rejects. Fixing that cleanly is a separate effort. More importantly, a type-check would not have caught the 2026-04-18 outage (the offending field was optional and legally undefined). Runtime smoke tests with fixture manifests would have.

What's in the workflow

.github/workflows/ci.yml — runs on push to main and every PR. Own concurrency group with cancel-in-progress: true so force-pushes don't waste minutes. Two steps after npm ci:

  1. Scanner smokenpm run scan -- . against this repo. Exercises every scan rule, policy render, framework evaluation, and report generator on a real tree. Catches any regression that breaks the scanner pipeline end-to-end.

  2. Dashboard render smokenpx tsx scripts/smoke-dashboard.ts. Exercises every exported render function with two fixtures: current-shape and pre-Phase-8-shape (no aiSystems field). The second fixture is a regression guard for the 2026-04-18 outage.

scripts/smoke-dashboard.ts — constructs both fixtures, summarises each, feeds through renderDashboard, renderRepoDetail, renderNistView, renderBranchComparison, renderTrendChart, renderAIComplianceView, and renderInventoryView (empty + populated). Also independently exercises evaluateEUAIAct / calcAIComplianceScore / getAIPhaseScores. Assertions per render: returns a string, at least 100 bytes, no bare >undefined< or ="undefined" in output. Inline JS that references undefined as an identifier is allowed.

Test plan

  • npx tsx scripts/smoke-dashboard.ts passes locally.
  • npm run scan -- . exits 0 locally.
  • Merge this PR — confirm the CI job turns green on main.
  • Follow-up regression test: ship a deliberately-broken commit on a throwaway branch, confirm CI fails on it.

Known gaps (tracked in checklist)

  • No proper unit test framework yet — these smoke tests are a down payment.
  • No lint / type-check step — adding one requires tsconfig cleanup or swapping to Biome. Separate PR.

Closes the second open-source-readiness blocker — no CI beyond
deploy. Up until now a broken import or a runtime throw in a
render function could sail onto main and break production, as
happened on 2026-04-18 with older manifests missing aiSystems.

## What's here

- `.github/workflows/ci.yml` — runs on every push and PR, in
  its own concurrency group so superseded runs get cancelled.
  Two steps:
    - Scanner smoke: runs `npm run scan -- .` against this repo.
      Exercises every scan rule, policy render, framework
      evaluation, and report generator end-to-end on a real
      tree. Non-zero exit fails the job.
    - Dashboard render smoke: runs scripts/smoke-dashboard.ts
      via tsx. Exercises every exported render function with
      both a current-shape and a pre-Phase-8-shape manifest.

- `scripts/smoke-dashboard.ts` — builds two fixtures (new-shape
  and old-shape), summarises each, and feeds them through
  renderDashboard, renderRepoDetail, renderNistView,
  renderBranchComparison, renderTrendChart,
  renderAIComplianceView, and renderInventoryView. Also
  independently exercises evaluateEUAIAct /
  calcAIComplianceScore / getAIPhaseScores.

  Assertions per render: returns a string, at least 100 bytes,
  no bare `>undefined<` or `="undefined"` anywhere. Inline JS
  references to `undefined` as an identifier are allowed.

  The old-shape fixture specifically lacks aiSystems — mirrors
  what pre-Phase-8 scanner versions stored in KV and guards
  against the 2026-04-18 regression.

## Not here

tsc --noEmit is intentionally skipped: this project uses tsx
at runtime, which tolerates the `verbatimModuleSyntax` +
no-@types/node combination that `tsc` does not. Running `tsc
--noEmit` against the current tsconfig produces hundreds of
pre-existing errors unrelated to real defects. A proper lint
pass (Biome, or tsconfig cleanup + ESLint) is tracked as a
separate open-source-readiness item.

## Checklist

- Closed: "No CI beyond deploy"
- Still open: "No unit tests" (smoke tests are a down payment,
  not a replacement) and "No lint / type-check"
@jeftekhari jeftekhari merged commit 0205cc7 into main Apr 18, 2026
1 check passed
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.

1 participant