inspector/.github/workflows/main.yml
Cliff Hall 36b48e61a2
feat(web): build dist on demand for prod --web + end-to-end CI smoke (#1486) (#1497)
* feat(web): build dist on demand for prod --web + end-to-end CI smoke (#1486)

Prod `mcp-inspector --web` serves static assets from clients/web/dist,
which only exists after a build. In a fresh checkout it was absent and the
prod path served a broken page (ENOENT on index.html); the launcher smoke
test only covered --help, so this path was unverified in CI.

- ensure-web-build.ts: build dist on demand (vite build via build:client)
  when missing, or exit with an actionable error if the build can't run.
- run-web.ts: invoke ensureWebBuild before startHonoServer in the prod path
  (--dev runs Vite directly and skips it).
- scripts/smoke-web.mjs + smoke:web: start --web against built dist and
  assert GET / returns 200 with the injected __INSPECTOR_API_TOKEN__.
  Wired into validate:launcher and a new CI step.
- Docs: launcher README + AGENTS.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(web): surface spawn error in build-on-demand; clarify smoke comment

Address PR #1497 review:
- runViteBuild now logs result.error.message (e.g. ENOENT when npm isn't on
  PATH) before returning a null status, so the spawn-failure cause surfaces
  instead of only the generic actionable error. The build seam gains a `log`
  param; added a test covering the ENOENT path.
- Reword scripts/smoke-web.mjs header so it no longer implies the readiness
  wait covers a cold build-on-demand vite build (it's sized for a pre-built
  dist, which validate/CI guarantee).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 18:34:52 -04:00

77 lines
2.3 KiB
YAML

name: Run install, format, lint, build, and test on every push
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '20.x'
cache: 'npm'
- name: Install dependencies (root + all clients)
# The root postinstall (scripts/install-clients.mjs) cascades
# `npm install` into clients/web, clients/cli, clients/tui, and
# clients/launcher, so this single step sets up every client.
run: npm install
- name: Check formatting
working-directory: ./clients/web
run: npm run format:check
- name: Run linter
working-directory: ./clients/web
run: npm run lint
- name: Run Build
working-directory: ./clients/web
run: npm run build
- name: Run tests with coverage
working-directory: ./clients/web
run: npm run test:coverage
- name: Run CLI tests
working-directory: ./clients/cli
run: npm run test
- name: Run TUI tests
working-directory: ./clients/tui
run: npm run test
- name: Build CLI, TUI, and launcher
run: npm run build:cli && npm run build:tui && npm run build:launcher
- name: Smoke test launcher
run: |
node clients/launcher/build/index.js --help
node clients/launcher/build/index.js --cli --help
node clients/launcher/build/index.js --tui --help
- name: Smoke test prod web launcher (end-to-end)
# Starts `mcp-inspector --web` against the built clients/web/dist (from
# the "Run Build" step) and asserts GET / serves the SPA (HTTP 200) with
# the injected auth token — the prod web path the --help smoke can't
# reach (#1486).
run: npm run smoke:web
- name: Cache Playwright browsers
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ hashFiles('clients/web/package-lock.json') }}
- name: Install Playwright browsers
working-directory: ./clients/web
run: npx playwright install --with-deps chromium
- name: Run Storybook play-function tests
working-directory: ./clients/web
run: npm run test:storybook