name: Run install, format, lint, build, and test on every push on: push: # A published GitHub release triggers the `publish` job below. The release's # target commit determines which workflow runs — so this only publishes when a # release is cut from a commit that carries this (v2) workflow. release: types: [published] 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: '22.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: Validate (format, lint, build, fast tests) # Each client self-validates: format:check + lint + build + test (no # coverage instrumentation — fast). This also builds every client bundle # (web dist, cli/tui/launcher) that the smokes below need. The heavier # per-file coverage gate runs in its own step below. Unit tests run in # both steps (fast here, instrumented under coverage); the double unit # run is an accepted trade-off for keeping this fast build step intact. # A future optimization could split coverage into per-client parallel # jobs, but that's a larger restructure and deliberately out of scope. run: npm run validate - name: Enforce per-file coverage gate (≥90% on all four dimensions) # CI-ENFORCED coverage gate (#1550): runs `npm run coverage`, which # chains every client's `test:coverage` (v8-instrumented) and fails the # job if ANY file drops below 90% on lines, statements, functions, or # branches. This is the whole point of the step — a PR that regresses # coverage below the threshold now blocks merge instead of relying on a # contributor remembering to run the gate locally. # # This also covers the web integration project: web's `test:coverage` # runs `--project=unit --project=integration --coverage`, so the former # standalone `Run web integration tests` step was removed to avoid # running the integration suite twice. run: npm run coverage - name: Run cross-client smokes # End-to-end smokes through the built launcher (--help dispatch + prod # CLI/web). Not part of any client's `validate`: it needs the # cli/tui/launcher bundles, which `validate` above already built # (smoke:web builds clients/web/dist on demand — #1486). smoke:tui # self-skips here — the Ink TUI needs a real TTY (raw mode) that headless # CI lacks, so its boot/render check is local-only. run: npm run smoke - 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 # Publish the single `@modelcontextprotocol/inspector` package to npm on a # published GitHub release. v2 is not an npm workspace, so there is no # `publish-all` / `--workspaces` (v1) — just one `npm publish`, whose `prepack` # (`npm run build`) builds every client bundle into the `files` allowlist. # `pack:verify` runs first as the pre-publish gate: it builds, packs the real # tarball, installs it into a clean throwaway consumer, and drives the # installed `mcp-inspector` bin (web/cli/tui) end to end — so a broken package # is caught before it reaches npm rather than after. publish: runs-on: ubuntu-latest if: github.event_name == 'release' environment: release needs: build permissions: contents: read # Required for npm provenance (`--provenance` mints a signed attestation # via GitHub's OIDC token). The repo is public, so provenance is available. id-token: write steps: - name: Checkout code uses: actions/checkout@v6 - name: Setup Node.js uses: actions/setup-node@v6 with: node-version: '22.x' cache: 'npm' registry-url: 'https://registry.npmjs.org' - name: Install dependencies (root + all clients) run: npm install - name: Verify the publishable tarball end to end # Builds, `npm pack`s, installs the tarball into a clean consumer, and # drives the installed bin. Needs registry access to pull the tarball's # runtime deps — available here. `smoke:tui` inside it self-skips on CI. run: npm run pack:verify - name: Publish to npm (single package, with provenance) # `prepack` (`npm run build`) rebuilds the client bundles into the tarball. run: npm publish --access public --provenance env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}