The Windows WSL job is the critical path of every CI run (589 to 752 s). Its checkout sits on the Windows drive, which WSL reaches over 9P, and writing node_modules there is what makes npm ci take about three minutes where the Linux job takes 23 s. The step now copies the tree onto the distro's ext4 filesystem before installing and building, as Microsoft's WSL guidance recommends for I/O-heavy work. The e2e job downloaded the full Chromium build (about 165 MB) on every run, but a headless run with no channel launches chromium-headless-shell and never opens it. `--only-shell` skips that download. Every tsconfig now lists the @types packages it uses (node, bun, vite/client, dom-speech-recognition) instead of relying on TypeScript auto-including everything under node_modules/@types. On TypeScript 5.9 this is a no-op: identical diagnostics across all 48 projects and byte-identical emitted .d.ts files. It is a prerequisite for TypeScript 7, which drops the auto-inclusion; with these lists the Go compiler passes all 48 projects, so that upgrade becomes a version bump once TypeDoc supports it. Two cache-based approaches were evaluated and rejected: an npm cache for the WSL job (npm ci is slow there because of 9P, not downloads, and a prefix-restored cache grows without bound) and a Playwright browser cache (Playwright's docs advise against it; the download is under 10 s).
236 lines
6.6 KiB
YAML
236 lines
6.6 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
prettier-fix:
|
|
name: Auto-fix formatting
|
|
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
with:
|
|
ref: ${{ github.head_ref }}
|
|
token: ${{ github.token }}
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: "22"
|
|
cache: npm
|
|
|
|
- run: npm ci
|
|
|
|
- run: npm run prettier:fix
|
|
|
|
- name: Commit formatting changes
|
|
run: |
|
|
git diff --quiet && exit 0
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
git add -A
|
|
git commit -m "style: auto-fix prettier formatting"
|
|
git push
|
|
|
|
build:
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- os: ubuntu-latest
|
|
name: Linux x64
|
|
- os: ubuntu-24.04-arm
|
|
name: Linux ARM64
|
|
- os: windows-latest
|
|
name: Windows x64
|
|
- os: windows-11-arm
|
|
name: Windows ARM64
|
|
- os: macos-latest
|
|
name: macOS ARM64
|
|
|
|
name: Build (${{ matrix.name }})
|
|
runs-on: ${{ matrix.os }}
|
|
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- name: Verify no private URLs in package-lock.json
|
|
shell: bash
|
|
run: '! grep -E "\"resolved\": \"https?://" package-lock.json | grep -v registry.npmjs.org'
|
|
|
|
- name: Verify example dependency versions
|
|
shell: bash
|
|
run: node scripts/check-versions.mjs
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: "22"
|
|
cache: npm
|
|
|
|
- run: npm ci
|
|
|
|
- run: npm run build
|
|
|
|
- name: Validate TypeDoc links
|
|
if: runner.os == 'Linux' && matrix.name == 'Linux x64'
|
|
run: npm exec typedoc -- --treatValidationWarningsAsErrors --emit none
|
|
|
|
- run: npm run examples:build
|
|
|
|
- name: Verify generated schemas are up-to-date
|
|
shell: bash
|
|
run: |
|
|
npm run generate:schemas
|
|
git diff --exit-code src/generated/ || (echo "Generated schemas are out of date. Run 'npm run generate:schemas' and commit." && exit 1)
|
|
|
|
- name: Verify synced snippets are up-to-date
|
|
shell: bash
|
|
run: |
|
|
npm run sync:snippets
|
|
git diff --exit-code src/ docs/ || (echo "Synced snippets are out of date. Run 'npm run sync:snippets' and commit." && exit 1)
|
|
|
|
- run: npm test
|
|
|
|
- run: npm run prettier
|
|
|
|
- name: Build MCPB bundle (pdf-server)
|
|
if: runner.os == 'Linux' && matrix.name == 'Linux x64'
|
|
run: node build-mcpb.mjs
|
|
working-directory: examples/pdf-server
|
|
|
|
- name: Smoke-test MCPB bundle starts
|
|
if: runner.os == 'Linux' && matrix.name == 'Linux x64'
|
|
run: |
|
|
unzip -q pdf-server.mcpb -d .mcpb-smoke
|
|
node .mcpb-smoke/dist/index.js --stdio < /dev/null 2>&1 | tee /tmp/mcpb-smoke.log
|
|
grep -q "Ready" /tmp/mcpb-smoke.log
|
|
working-directory: examples/pdf-server
|
|
|
|
dependency-isolation:
|
|
name: Dependency isolation
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: "22"
|
|
cache: npm
|
|
|
|
- run: npm ci
|
|
|
|
- run: npm run test:dependency-isolation
|
|
|
|
e2e:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: latest
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: "22"
|
|
cache: npm
|
|
|
|
- uses: astral-sh/setup-uv@v7
|
|
|
|
- run: npm ci
|
|
|
|
# Headless runs without a channel use chromium-headless-shell, so the
|
|
# full Chromium build (about 165 MB) would only be downloaded, never run.
|
|
- name: Install Playwright browsers
|
|
run: npx playwright install --with-deps --only-shell chromium
|
|
|
|
- name: Run E2E tests
|
|
run: npx playwright test --reporter=list
|
|
|
|
- name: Upload test results
|
|
uses: actions/upload-artifact@v6
|
|
if: failure()
|
|
with:
|
|
name: test-results
|
|
path: test-results/
|
|
retention-days: 7
|
|
|
|
# Test build in Windows WSL (Ubuntu)
|
|
build-wsl:
|
|
name: Build (Windows WSL)
|
|
runs-on: windows-latest
|
|
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: Vampire/setup-wsl@v6
|
|
with:
|
|
distribution: Ubuntu-24.04
|
|
|
|
- name: Install Node.js in WSL
|
|
shell: wsl-bash {0}
|
|
run: |
|
|
sudo apt-get update
|
|
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
|
|
sudo apt-get install -y nodejs
|
|
|
|
# The checkout lives on the Windows drive, which WSL reaches over 9P;
|
|
# writing node_modules there is what makes this job slow (npm ci alone
|
|
# took about 3 minutes). Copy the tree onto the distro's ext4 filesystem
|
|
# first, as Microsoft's WSL guidance recommends for anything I/O heavy.
|
|
- name: Build and test in WSL
|
|
shell: wsl-bash {0}
|
|
run: |
|
|
cp -r "$(pwd)" ~/ext-apps && cd ~/ext-apps
|
|
npm ci
|
|
npm run build
|
|
npm run examples:build
|
|
npm test
|
|
npm run prettier
|
|
|
|
# Test that the package can be installed from git (triggers prepare script)
|
|
test-git-install:
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- os: ubuntu-latest
|
|
name: Linux x64
|
|
- os: ubuntu-24.04-arm
|
|
name: Linux ARM64
|
|
- os: windows-latest
|
|
name: Windows x64
|
|
- os: windows-11-arm
|
|
name: Windows ARM64
|
|
- os: macos-latest
|
|
name: macOS ARM64
|
|
|
|
name: Test git install (${{ matrix.name }})
|
|
runs-on: ${{ matrix.os }}
|
|
|
|
steps:
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: "22"
|
|
|
|
- name: Create test project and install from git
|
|
shell: bash
|
|
env:
|
|
HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
|
|
HEAD_REF: ${{ github.head_ref || github.ref_name }}
|
|
run: |
|
|
mkdir test-project
|
|
cd test-project
|
|
npm init -y
|
|
# Install from the PR branch (use head repo for fork PRs)
|
|
npm install "git+https://github.com/${HEAD_REPO}#${HEAD_REF}"
|
|
# Verify the package is usable (ESM import)
|
|
node --input-type=module -e "import { App } from '@modelcontextprotocol/ext-apps'; console.log('Import successful:', typeof App)"
|