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)"