Pin ida-pro-mcp e2e image by digest - #6159
Conversation
Dockyard rebuilds the mutable 1.4.0 tag periodically and resolves Python dependencies fresh on each build. ida-pro-mcp 1.4.0 declares an unbounded "mcp>=1.16.0" and imports mcp.server.fastmcp, which the mcp Python SDK removed in 2.0.0. The 2026-07-31 rebuild resolved mcp 2.0.0, so the backend container now crashloops with ModuleNotFoundError. The vMCP reports Ready: False and the optimizer multi-backend spec times out in BeforeAll, failing E2E Test Lifecycle on every kind version regardless of the PR diff. 1.4.0 is the newest ida-pro-mcp release on PyPI, so there is no version to bump to. Pin the last build that resolved a 1.x mcp instead, which makes the reference immutable and the spec independent of upstream rebuilds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6159 +/- ##
==========================================
- Coverage 72.63% 72.62% -0.02%
==========================================
Files 736 736
Lines 76331 76331
==========================================
- Hits 55444 55436 -8
- Misses 16949 16960 +11
+ Partials 3938 3935 -3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
The E2E Tests Lifecycle workflow is the only job that runs the Ginkgo suite under test/e2e/thv-operator, and that suite sources every backend container image from test/e2e/images. That path was missing from the trigger filter, so the ida-pro-mcp digest pin in the previous commit did not run the tests it fixes, and no future change to a test image would either. Add test/e2e/images to the filter. Because the workflow file is itself in the filter, this commit triggers the suite and verifies the pin. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Heads up to @JAORMX and @amirejaz: I pushed a second commit after your approvals, so the diff grew by one file. While verifying the pin I noticed the first push went green on all 45 checks without ever running the test it fixes. So a change to a test backend image couldn't trigger the tests that consume it. That's also part of why the original breakage looked like it came from unrelated PRs. 07936e0 adds the path. Because the workflow file is itself in the filter, that commit triggers the suite here, which is what actually verifies the pin. Updated the description with the details. |
The red
|
|
The red CI is independent of this fix. Will handle on a separate PR, merging this one as is |
The proxy e2e suites fail on every PR with "timeout waiting for MCP server to be ready". Same root cause as #6159, a different image: tag 2026.7.10 of mcp-server-time is mutable, dockyard rebuilds it and resolves Python dependencies fresh, and the 2026-07-31 rebuild picked up the mcp Python SDK 2.0.0 released 2026-07-28. mcp-server-time imports McpError from mcp.shared.exceptions, which 2.x moved, so the container now exits on startup with "ImportError: cannot import name 'McpError'". Pin the last build that resolved a 1.x mcp. Verified by driving both builds over stdio: the pinned digest answers initialize, tag 2026.7.10 does not. Point the two affected suites at the pinned constant instead of the "time" registry entry, since the registry resolves to the moving tag and is not fixable from this repo. Registry-name resolution stays covered by the sibling cases that run "osv". stdio_proxy_over_streamable_http gains an explicit --transport stdio, which the registry entry previously supplied. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary
E2E Test Lifecycleis currently failing on every PR, on all three kind versions, regardless of the diff. Theida-pro-mcpbackend in the optimizer multi-backend spec crashloops on startup:One unhealthy backend out of eleven makes the vMCP report
Ready: False(Some backends are unhealthy), so the spec times out after 300s inBeforeAll. The optimizer path itself is fine:EmbeddingServerReadyisTrueand the other ten backends reachReady.The cause is upstream drift in a mutable tag:
ida-pro-mcp1.4.0 declares an unboundedmcp>=1.16.0and importsmcp.server.fastmcp.mcpPython SDK removed that module in 2.0.0, uploaded to PyPI on 2026-07-28.ghcr.io/stacklok/dockyard/uvx/ida-pro-mcp:1.4.0on 2026-07-31 and resolvedmcp2.0.0. The previous build, 2026-07-27, hasmcp1.28.1 and works.1.4.0 is the newest
ida-pro-mcprelease on PyPI, so there is no version to bump to. This pins the last build that resolved a 1.xmcp, which makes the reference immutable and the spec independent of future rebuilds.IDAProMCPServerImageto1.4.0@sha256:5a596d96...intest/e2e/images/images.go, with a comment recording why.test/e2e/images/**to theE2E Tests Lifecycletrigger filter. See below.The trigger gap, found while verifying this PR
The first push here went green on all 45 checks without ever running the test it fixes.
E2E Tests Lifecycleis the only job that runs the Ginkgo suite undertest/e2e/thv-operator, which is where the optimizer multi-backend spec lives. (Operator CI / E2E Tests Operatorlooks like it would cover it, but it only runs the chainsaw suites undertest/e2e/chainsaw/operator.) Itspathsfilter listedtest/e2e/thv-operator/**but nottest/e2e/images/**, even though that package supplies every backend image the suite deploys.So a change to a test backend image could not trigger the tests that consume it. That is also why the original breakage looked like it came from unrelated PRs: the drift landed in an image, and nothing tied that to the suite.
Adding the path fixes it. Since the workflow file is itself in the filter, the second commit triggers the suite and verifies the pin on this PR.
Type of change
Test plan
task test-e2e)E2E:
E2E Test Lifecyclenow runs on this PR across all three kind versions, which is the suite that was failing. This is the actual verification of the fix, and it was only possible after the trigger-filter commit.Manual: verified against
linux/amd64, the arch CI runs, by pulling the per-arch manifest inside each index:1.4.0(sha256:05691124, built 2026-07-31):mcp2.0.0 installed,ida-pro-mcpexits with theModuleNotFoundErrorabove. Failure reproduced.sha256:5a596d96, built 2026-07-27):mcp1.28.1 installed. Full stdio MCP handshake succeeds,initializereturnsserverInfoida-pro-mcp, andtools/listreturns 48 tools.Also confirmed the reference form is supported:
MCPServerSpec.Imagecarries no pattern validation,pkg/runner/retrieveralready branches onnameref.Digest, andrepo:tag@digestresolves through the registry.Changes
test/e2e/images/images.goIDAProMCPServerImageto the 2026-07-27 digest of tag 1.4.0examples/operator/virtual-mcps/vmcp_optimizer_quickstart.yamlida-pro-mcpbackend.github/workflows/test-e2e-lifecycle.ymltest/e2e/images/**changesDoes this introduce a user-facing change?
No. Test fixtures, a CI trigger filter, and an example manifest.
Special notes for reviewers
The two approvals landed on the first commit, before the trigger-filter change. Worth a second look at
.github/workflows/test-e2e-lifecycle.ymlspecifically.This is distinct from #6026. That issue is the nondeterministic search-quality ranking assertion in the same spec file; this is a deterministic
BeforeAlltimeout from an unhealthy backend. Fixing this does not close that one.Two follow-ups I did not fold in, to keep the scope contained:
test/e2e/images/images.gois not covered by any Renovate manager, despite the package doc saying it enables automated updates. That is why the tag drifted unnoticed in the first place.mcp/puppeteer:latest,mcp/memory:latest,mcp/everything:latest,text-embeddings-inference:cpu-latest.The pin should be revisited once upstream
ida-pro-mcpeither caps itsmcpconstraint or adopts the 2.x API.pagerduty-mcp, the only other dockyard uvx image in the spec, capsmcp[cli]~=1.8and is not exposed.Generated with Claude Code