feat(templates): support Container builds in the strands-http-python template - #2137
feat(templates): support Container builds in the strands-http-python template#2137Hweinstock wants to merge 3 commits into
Conversation
|
Claude Security Review: no high-confidence findings. (run) |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## refactor #2137 +/- ##
=========================================
Coverage 97.19% 97.20%
=========================================
Files 471 472 +1
Lines 28731 28790 +59
=========================================
+ Hits 27925 27984 +59
Misses 806 806 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Thanks for the report, @codecov-commenter — feedback like this is exactly Would you mind opening a new issue so we can track it properly? If this is a security issue, please report it privately via |
There was a problem hiding this comment.
AgentCore Harness Review
Verdict: Looks good
Nice refactor. The filter/transformContent split in FsTreeNode.fromAssetSource, the .template suffix convention (with clear rationale in the docstring for the extensionless-file bundling quirk), and the extraction of template shortcut resolution into resolveRuntimeTemplateShortcut all read well. Delegating validation to ScaffoldRuntimeInputSchema.superRefine/refine (e.g., API key + Bedrock, runtimeVersion + build) is the right move — errors like "API keys are not compatible with Bedrock model providers" fall out naturally instead of being open-coded in the handler.
The new e2e-ish tests in project.test.ts and add/runtime/index.test.ts exercise real project scaffolding against temp directories and assert file existence for Dockerfile/.dockerignore under the correct build modes, which is the right level of coverage for this feature.
A few small observations, non-blocking:
- In both
handlers/project/create/index.tsandhandlers/project/add/runtime/index.ts,presentScaffoldingFlags/isCustomare still computed even whenisTemplateis true. Since the ternary checksisTemplatefirst, theisCustombranch is unreachable in that case, so this is inert but slightly confusing. Optional cleanup. fsTree.tsfilter semantics: rejecting a name viacontinue assetPathscorrectly prevents new subtrees from being added, but if an earlier sibling path already created a directory node that the filter would now reject, the directory stays. In practice your filters are deterministic on names, so this doesn't bite — worth being aware of if filters ever become path-dependent.- No new telemetry for
--templateselection or overrides. There's no existing instrumentation in these handlers either, so this is consistent with the surrounding code; flagging only in case template-adoption metrics are wanted.
Problem
On the
refactorbranch, thestrands-http-pythontemplate does not support Container builds.agentcore project create --template strands-python --build Container --name perrored with "--templateand--buildare mutually exclusive", and even with that guard relaxed the template shipped noDockerfile.Solution
RUNTIME_TEMPLATE_SHORTCUTSinto a newsrc/handlers/project/shortcuts.tsand addedresolveRuntimeTemplateShortcut, which lets compatible flags (--build,--model-provider,--memory,--api-key,--runtime-name) override a--template. Only--language/--frameworkremain locked. Applied to bothproject createandproject add runtime. (I deliberately did not port fix(scaffold): allow certain template values to be overriden #2130's strands "CodeZip-only" guard, since the goal here is the opposite.)FsTreeNode.fromAssetSource(adapted from feat(templates): wire in memory to the runtime templates #2116): the resolver now accepts an object-shaped signature with afilter(name, isDir)option (andtransformContent). The filter receives the rendered name (post-renderName).filter: (name) => isContainer || (name !== "Dockerfile" && name !== ".dockerignore"), so the Dockerfile/.dockerignoreare scaffolded only for Container builds.buildRuntimeSpecalready stampsdockerfile: "Dockerfile"for Container builds.Dockerfile.template+dockerignore.templatetostrands-http-python(byte-identical to the workinghello-world-python-containerversions).Why
Dockerfile.templateand notDockerfilebun buildnames embedded assets[name].[ext], so an extensionlessDockerfileembeds into the compiled binary asDockerfile.(trailing dot). A project scaffolded from the binary would then get aDockerfile.thatproject deploy/project devcan't find. This is a pre-existing latent bug — the existinghello-world-python-container/Dockerfilehad the same problem in compiled binaries.Fix: reuse the existing dotfile-template convention (
gitignore.template→.gitignore).renderNamenow mapsDockerfile.template→Dockerfile. Both Dockerfiles (strands + hello-world) use the suffix, which also fixes the hello-world binary bug. Scaffold output is byte-identical, so no snapshot churn.The
renderNamechange is intentionally targeted rather than a generic.templatestrip: a generic strip would breakenv.local.template→.env.local(a dotfile mapping).Definition of Done — evidence
All commands below were run against a binary built with
bun run compile:linux-x64.1. Container agent from the strands template ✅
3. Default CodeZip still works, no Dockerfile ✅
2. Local dev / invoke returns real data ✅
agentcore project devis an interactive TUI (needs a live terminal), so I validated the runtime the same way its container path does under the hood — build + run the scaffolded image, then curlPOST /invocations(the AgentCore HTTP contract):4. Deployable + invokable ✅ (CodeZip) /⚠️ (Container — account infra blocker)
CodeZip — deployed and invoked end-to-end:
Container — the image builds and runs (see #2 above), but
project deployfails at the CloudFormation stage with:This is a template-independent account/bootstrap issue: the AgentCore CDK construct creates a customer-managed KMS key for the ECR repo, but the scoped CDK exec role (
AgentCoreCdkBootstrapExecution) lackskms:CreateGrant. It would block any container deploy in this account (includinghello-world-python-container) and is unrelated to this change. Resolving it needs an account-level IAM/bootstrap fix (grantkms:CreateGrantto the exec role, or bootstrap with a broader exec policy) — out of scope here. Filing/looping in for a follow-up on the bootstrap policy is recommended.Reproduce
Notes for reviewers
fromAssetSource's object-shaped signature mirrors feat(templates): wire in memory to the runtime templates #2116 verbatim to minimize merge conflicts with that PR; the inlineassetPaths:label comment is also carried over from feat(templates): wire in memory to the runtime templates #2116.--buildoverrides on templates, Container-vs-CodeZip Dockerfile presence,Dockerfile.template→Dockerfilerenaming, filter-on-rendered-name, and the--language/--framework/API-key rejection paths.