diff --git a/.github/workflows/publish-mcp.yml b/.github/workflows/publish-mcp.yml index f3e226ca..09a65628 100644 --- a/.github/workflows/publish-mcp.yml +++ b/.github/workflows/publish-mcp.yml @@ -1,7 +1,8 @@ name: Publish MCP Server # Publishes @next-ai-drawio/mcp-server to npm via OIDC trusted publishing -# (no token, no OTP). Triggers when packages/mcp-server changes on main; +# (no token, no OTP). Triggers when packages/mcp-server or the web app code +# bundled into the canvas shell (scripts/build-shell.mjs) changes on main; # skips silently if the package.json version is already on npm — so a # release is just "bump the version in a PR and merge". on: @@ -10,6 +11,14 @@ on: - main paths: - "packages/mcp-server/**" + # The canvas shell is bundled from these with the root's lockfile + - "components/**" + - "contexts/**" + - "hooks/**" + - "lib/**" + - "stores/**" + - "app/globals.css" + - "package-lock.json" workflow_dispatch: permissions: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f36935a4..52079d7e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -93,10 +93,30 @@ jobs: env: CI: true + # The canvas shell in a browser, from the package as npm installs it: + # the packed tarball goes into an empty directory, its dist/index.js is + # started over stdio and headless Chromium opens the URL start_session + # returns (packages/mcp-server/tests/e2e). Chromium is installed above; + # the build shares the root build's draw.war download. + - name: Run the MCP shell E2E tests on the packed tarball + if: matrix.shard == 1 + run: | + npm --prefix packages/mcp-server ci + npm --prefix packages/mcp-server run build + npm pack ./packages/mcp-server --pack-destination "$RUNNER_TEMP/mcp-pack" + mkdir -p "$RUNNER_TEMP/mcp-install" + npm --prefix "$RUNNER_TEMP/mcp-install" install "$RUNNER_TEMP"/mcp-pack/*.tgz + MCP_SERVER_ENTRY="$RUNNER_TEMP/mcp-install/node_modules/@next-ai-drawio/mcp-server/dist/index.js" \ + npm --prefix packages/mcp-server run test:e2e + env: + CI: true + - name: Upload test results uses: actions/upload-artifact@v6 if: always() with: name: playwright-report-${{ matrix.shard }} - path: playwright-report/ + path: | + playwright-report/ + packages/mcp-server/test-results/ retention-days: 7 diff --git a/packages/mcp-server/tests/e2e/shell.spec.ts b/packages/mcp-server/tests/e2e/shell.spec.ts index ad4e70b9..b07b703d 100644 --- a/packages/mcp-server/tests/e2e/shell.spec.ts +++ b/packages/mcp-server/tests/e2e/shell.spec.ts @@ -1,7 +1,8 @@ /** * The canvas shell as start_session opens it with DRAWIO_PREVIEW_UI=shell: - * the built server (dist/index.js) runs over stdio as an MCP client would - * start it, and headless Chromium opens the URL it returns. + * the built server (dist/index.js, or the copy MCP_SERVER_ENTRY names: CI + * installs the packed tarball in an empty directory) runs over stdio as an + * MCP client would start it, and headless Chromium opens the URL it returns. */ import { mkdtempSync, readFileSync, rmSync } from "node:fs" import { tmpdir } from "node:os" @@ -21,7 +22,7 @@ test.beforeAll(async () => { dataDir = mkdtempSync(join(tmpdir(), "mcp-shell-e2e-")) const transport = new StdioClientTransport({ command: process.execPath, - args: [join(pkg, "dist/index.js")], + args: [process.env.MCP_SERVER_ENTRY ?? join(pkg, "dist/index.js")], env: { ...process.env, DRAWIO_DATA_DIR: dataDir,