diff --git a/.github/workflows/test-e2e-lifecycle.yml b/.github/workflows/test-e2e-lifecycle.yml index 3c6b55d168..eba490de30 100644 --- a/.github/workflows/test-e2e-lifecycle.yml +++ b/.github/workflows/test-e2e-lifecycle.yml @@ -8,6 +8,11 @@ on: - 'cmd/thv-operator/**' - 'pkg/**' - 'test/e2e/thv-operator/**' + # This job is the only one that runs the Ginkgo suite under + # test/e2e/thv-operator, and that suite sources every backend container + # image from test/e2e/images. A change there alters what these tests + # actually deploy, so it has to trigger them. + - 'test/e2e/images/**' - '.github/workflows/test-e2e-lifecycle.yml' permissions: diff --git a/examples/operator/virtual-mcps/vmcp_optimizer_quickstart.yaml b/examples/operator/virtual-mcps/vmcp_optimizer_quickstart.yaml index 35694a384c..fd3d6bfd3c 100644 --- a/examples/operator/virtual-mcps/vmcp_optimizer_quickstart.yaml +++ b/examples/operator/virtual-mcps/vmcp_optimizer_quickstart.yaml @@ -288,6 +288,9 @@ spec: --- # Step 2j: MCPServer backend - ida-pro-mcp (IDA Pro reverse engineering) +# The 1.4.0 tag is mutable and its latest rebuild resolves mcp Python SDK 2.0.0, +# which dropped mcp.server.fastmcp and makes the container crashloop. Pinned to +# the last build that resolved mcp 1.x. See test/e2e/images/images.go. apiVersion: toolhive.stacklok.dev/v1beta1 kind: MCPServer metadata: @@ -296,7 +299,7 @@ metadata: spec: groupRef: name: optimizer-services - image: ghcr.io/stacklok/dockyard/uvx/ida-pro-mcp:1.4.0 + image: ghcr.io/stacklok/dockyard/uvx/ida-pro-mcp:1.4.0@sha256:5a596d965fe05052d615a41152213f93ebc72bf46b07304718de948833d73c70 transport: stdio proxyPort: 8080 resources: diff --git a/test/e2e/images/images.go b/test/e2e/images/images.go index 0dd341ccb9..d1dd46e2ec 100644 --- a/test/e2e/images/images.go +++ b/test/e2e/images/images.go @@ -92,9 +92,24 @@ const ( idaProMCPServerImageURL = "ghcr.io/stacklok/dockyard/uvx/ida-pro-mcp" idaProMCPServerImageTag = "1.4.0" + // idaProMCPServerImageDigest pins the 2026-07-27 build of tag 1.4.0. + // + // The tag is mutable: dockyard periodically rebuilds it and resolves Python + // dependencies fresh each time. ida-pro-mcp 1.4.0 declares an unbounded + // "mcp>=1.16.0" and imports mcp.server.fastmcp, which was removed in the + // mcp Python SDK 2.0.0 (released 2026-07-28). The 2026-07-31 rebuild picked + // up mcp 2.0.0, so the container now crashloops on startup with + // "ModuleNotFoundError: No module named 'mcp.server.fastmcp'". + // + // 1.4.0 is the newest ida-pro-mcp release on PyPI, so there is nothing to + // bump to. Pin the last build that resolved a 1.x mcp (1.28.1) until + // upstream caps the constraint or adopts the 2.x API. Every other backend + // in the optimizer test is unaffected -- pagerduty-mcp, the only other + // dockyard uvx image, caps "mcp[cli]~=1.8". + idaProMCPServerImageDigest = "sha256:5a596d965fe05052d615a41152213f93ebc72bf46b07304718de948833d73c70" // IDAProMCPServerImage is used for testing multi-backend optimizer scenarios. // Provides ~47 IDA Pro reverse engineering tools (decompile, disassemble, rename, etc.). - IDAProMCPServerImage = idaProMCPServerImageURL + ":" + idaProMCPServerImageTag + IDAProMCPServerImage = idaProMCPServerImageURL + ":" + idaProMCPServerImageTag + "@" + idaProMCPServerImageDigest pagerdutyMCPServerImageURL = "ghcr.io/stacklok/dockyard/uvx/pagerduty-mcp" pagerdutyMCPServerImageTag = "0.12.0"