test(integ): add docker-image-asset integ (deploy-time ECR build+push, ARM_64-pinned) - #834
Merged
Conversation
cdkd's Docker asset pipeline (src/assets/docker-asset-publisher.ts:
docker build of a local Dockerfile, ECR auth, docker push) was only
covered by the LOCAL-emulation container fixtures (local-invoke-container
etc.) which build images locally and never touch AWS. The actual
deploy-time ECR build+push was untested end-to-end.
New fixture tests/integration/docker-image-asset/:
- CdkdDockerImageAssetExample stack: a single lambda.DockerImageFunction
(DockerImageCode.fromImageAsset(docker/)), a trivial
public.ecr.aws/lambda/nodejs:20-based image with a one-line handler,
no VPC / NAT (cheapest reliable way to force the build+push).
- verify.sh (BSD/macOS-portable, real rc + explicit [verify] PASS):
- SKIPs gracefully (exit 0) when `docker info` fails, so it is robust
on a Docker-less box but runs in a Docker env.
- deploy -> asserts the Lambda has PackageType=Image with a
Code.ImageUri pointing at the CDK-managed container-assets ECR repo,
the repo exists + contains >=1 image, and the exact pushed image
(by digest, parsed from the ImageUri) is present.
- invokes the Lambda and asserts the expected payload (message,
deployedBy env var, echoed event) -> proves the pushed image runs.
- destroy -> asserts clean: Lambda gone, the pushed image gone from
ECR with 0 orphans, state file gone. The asset repo is the shared
bootstrap-managed cdk-hnb659fds-container-assets-* repo, so the
assertion is on OUR image's lifecycle by digest, not the shared
repo's removal.
- EXIT trap sweeps leftover state, the deployment-events sidecar, and
(by digest) the pushed image so the cost-bearing ECR image never
lingers.
New scenario tag docker-image-asset-ecr-publish (KNOWN_SCENARIOS in
scripts/build-scenario-coverage-matrix.ts); coverage matrices
regenerated (0 orphans); docs/testing.md + docs/changelog-cdkd.md notes
added.
…ge by tag The real-AWS run surfaced two issues: 1. Cross-arch InvalidEntrypoint. A default DockerImageFunction synthesizes no source.platform in the asset manifest and no Architectures on the template (defaulting to x86_64). cdkd correctly honors source.platform when present but builds for the HOST arch when it is absent, so on an arm64 (Apple Silicon) host it pushed an arm64 image to an x86_64 Lambda, which failed at invoke with Runtime.InvalidEntrypoint: ProcessSpawnFailed (the same trap CDK CLI users hit on Mac). Pin both the build platform (DockerImageCode.fromImageAsset platform: LINUX_ARM64) and the Lambda architecture (ARM_64) so they always match on any host. Confirmed synth now emits source.platform "linux/arm64" + Architectures ["arm64"]. 2. verify.sh image-count parse bug. The ">=1 image" check against the SHARED bootstrap repo (cdk-hnb659fds-container-assets-*) choked with "integer expected" because that repo already holds thousands of images; the count is not a meaningful signal anyway. Replace it with a by-TAG presence check: parse the content-addressed asset-hash tag from the Lambda Code.ImageUri (the tag form, not @sha256 digest) and assert describe-images --image-ids imageTag=<tag> finds our exact pushed image. Make the parse hard-fail if no tag is found, and use the tag for the post-destroy orphan sweep too. The shared bootstrap repo persisting is expected and is no longer treated as a failure. Updated the changelog entry to match the new arch-pinning + tag-based assertions. typecheck/lint/build/test/format all pass; fixture tsc clean; synth manifest + template confirmed.
go-to-k
force-pushed
the
test/docker-image-asset
branch
from
June 13, 2026 11:03
7e599be to
04a5f65
Compare
|
🎉 This PR is included in version 0.221.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the missing real-AWS integ for the deploy-time ECR Docker image build+push asset path (previously only LOCAL emulation fixtures like
local-invoke-containercovered Docker; the actualcdkd deploybuild+push was untested end-to-end). Fills the asset-layer ECR gap (.claude/rules/assets.md).Fixture (
CdkdDockerImageAssetExample, no VPC)A
lambda.DockerImageFunctionwhose image is built from a local Dockerfile (public.ecr.aws/lambda/nodejs:20+ a tiny handler) viaDockerImageCode.fromImageAsset. Architecture pinned to ARM_64 (bothDockerImageCodeplatformLINUX_ARM64and Lambdaarchitecture: ARM_64) — the first run surfaced a real cross-arch trap: a defaultDockerImageFunctionemits nosource.platform, so cdkd built the host arch (arm64) and pushed it to an x86_64 Lambda →Runtime.InvalidEntrypoint: ProcessSpawnFailed(same trap CDK CLI users hit on Mac). Pinning makes build-arch == Lambda-arch on any host.verify.sh asserts (Docker-availability guarded → SKIP if no daemon)
deploy → Lambda
PackageType=Image+Code.ImageUriparsed → asserts OUR pushed image is present in ECR by its content tag (describe-images --image-ids imageTag=<hash>) → invoke asserts the handler payload (the pushed image actually runs) → destroy → clean (the shared bootstrap repo persisting is not an orphan).Real-AWS result
PASS — 0 errors, 0 orphans (60s) after the arch fix. (First run FAILED on the arch mismatch — the integ did its job catching it.)
Coverage matrices regenerated (union with merged scenarios).