perf(test): disable Lambda bundling in CDK unit-test synths (~15x per synth) (#366)#371
perf(test): disable Lambda bundling in CDK unit-test synths (~15x per synth) (#366)#371scottschreckengaust wants to merge 4 commits into
Conversation
Template.fromStack() triggers a full CDK synth that bundles every NodejsFunction via esbuild — ~28s for the 413-resource AgentStack. Unit tests assert on CloudFormation structure, not bundled Lambda code, so the bundling is pure overhead. A jest setupFiles hook sets aws:cdk:bundling-stacks: [] via CDK_CONTEXT_JSON, which a bare new App() picks up with no call-site changes. Measured: single AgentStack synth 28.7s -> 1.9s (~15x); github-tags.test.ts ~135s -> 9s; full //cdk:test 155s -> 25s (8-core local). All 2177 tests pass; coverage thresholds unchanged (lines 92.36 >= 91). Durable regression guards added: AGENTS.md "Common mistakes" entry and a .abca/commands/review_pr.md checklist item — do not re-enable bundling in tests unless asserting on a bundled asset, and minimize full-stack synths (synth once in beforeAll). Both link docs/design/CI_BUILD_PERFORMANCE.md (PR #364). Refs #366. Part of #363. Likely supersedes the sharding approach (#365) — to be re-evaluated once this lands. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
isadeks
left a comment
There was a problem hiding this comment.
Genuinely good, well-scoped optimization. I verified the core mechanism empirically against aws-cdk-lib@2.257.0: bundlingRequired reads context key aws:cdk:bundling-stacks defaulting to ["**"], so setting it to [] makes [].some(...) return false and a bare new App() (the dominant test pattern) picks it up via CDK_CONTEXT_JSON with zero call-site changes. The ~15× synth speedup is real and the safety audit checks out.
✅ What I verified
- Mechanism is correct —
new App()readsCDK_CONTEXT_JSON;aws:cdk:bundling-stacks: []disables bundling (bundlingRequired === false). Confirmed empirically. - Safety claim holds —
version.test.tscomputes a bootstrap-policy hash and synthesizes no stack, so it's unaffected by disabling bundling. - No collateral — no existing CDK test asserts on bundled asset hashes / S3 keys, and none relies on a constructor-context bundling toggle, so the "all 2177 tests pass" claim is consistent.
- Setup-file internal merge is self-consistent — when
CDK_CONTEXT_JSONis pre-set, the existing value wins, matching the file's comment.
🚫 Blockers
None.
🔧 Should fix before merge
1. The documented per-test opt-out does not work (latent bug).
The escape hatch documented in all three places (disable-bundling.ts comment, AGENTS.md, review_pr.md) —
new App({ context: { 'aws:cdk:bundling-stacks': ['**'] } })— does not re-enable bundling. Verified empirically against aws-cdk-lib@2.257.0:
| App construction | stack.bundlingRequired |
|---|---|
bare new App() |
false (disabled ✅ — intended) |
new App({ context: { 'aws:cdk:bundling-stacks': ['**'] } }) |
false ❌ (PR claims true) |
new App({ postCliContext: { 'aws:cdk:bundling-stacks': ['**'] } }) |
true ✅ |
Root cause: CDK's App.loadContext(props.context, props.postCliContext) sets props.context first, then overwrites it with CDK_CONTEXT_JSON, then applies postCliContext last. So the env var beats constructor context.
Impact: a future author who needs a real bundled asset (asset-hash / S3-key assertion) follows the docs, gets a silently-unbundled synth, and a wrong/empty asset hash with no error. Not a current-test failure — no test uses this path today — so it's latent.
Fix: document postCliContext as the opt-out (it actually overrides), and correct the "Tests that pass their own { context } still merge on top" comment, which is wrong for this key.
💬 Other (self-disclosed)
2. Dangling doc link. AGENTS.md → ./docs/design/CI_BUILD_PERFORMANCE.md doesn't exist on this branch or main (added by draft PR #364). The PR body already flags the merge-order dependency. Note it intersects with the link-checker PR #300: AGENTS.md is a root .md within that checker's scope, so landing #371 + #300 without #364 would turn the dead link into a red CI check. (review_pr.md has the same link but .abca/ is outside the checker's scope, so only AGENTS.md would trip CI.)
Reviewed at xhigh effort. Mechanism and precedence claims verified empirically against aws-cdk-lib@2.257.0, not just read from source.
The documented per-test opt-out used constructor `context`, which CDK
silently overwrites with CDK_CONTEXT_JSON in App.loadContext — so
`new App({ context: { 'aws:cdk:bundling-stacks': ['**'] } })` does NOT
re-enable bundling. Only `postCliContext` (applied last) overrides the
global disable.
Corrects the opt-out instruction and precedence comment in all three
documented locations (disable-bundling.ts, AGENTS.md, review_pr.md).
Verified empirically against aws-cdk-lib@2.257.0. Comment/doc-only;
runtime logic unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…366) Disabling bundling does not stop tests from synthesizing — `Template.fromStack()` still runs a full synth; it only skips the esbuild asset-bundling step. The `postCliContext` opt-out exists solely for the rare test that needs real bundled-asset output (asset hash / S3 key), where an unbundled synth would silently yield a placeholder. Makes this explicit in disable-bundling.ts and AGENTS.md. Doc-only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The doc lives in draft PR #364 and exists on neither this branch nor main, so the three links (disable-bundling.ts, AGENTS.md, review_pr.md) are dead. Drop them and keep the stable #366 reference, removing the merge-order dependency on #364 and the link-checker (#300) risk. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@isadeks Thanks for the empirical verification — you're exactly right, and I confirmed it. I've corrected the opt-out to |
Re-review: ✅ Both findings resolved — recommend approveRe-reviewed at head
Finding 1 — verified against
The corrected AGENTS.md / Finding 2 — zero Core mechanism, the Nothing left blocking. One cosmetic residual: the PR description's dependency note still mentions the #364 merge ordering, which is now stale since the links are gone — worth trimming the description, but it's not a code issue. Good to mark ready once the 4-core CI build posts green. |
What
Disables Lambda asset bundling during CDK unit-test synthesis.
Template.fromStack()does a full CDK synth, which bundles everyNodejsFunctionvia esbuild — ~28s for the 413-resourceAgentStack. Unit tests assert on CloudFormation structure/properties, not bundled Lambda code, so the bundling is pure overhead.A jest
setupFileshook (cdk/test/setup/disable-bundling.ts) setsaws:cdk:bundling-stacks: []viaCDK_CONTEXT_JSON. A barenew App()— the dominant pattern across our tests (87 call sites) — picks this up with zero call-site changes.Closes #366. Part of #363.
Results (8-core local)
AgentStacksynthgithub-tags.test.ts//cdk:testWhy this over sharding (#365)
Profiling under #366 showed the CDK suite's cost is per-synth esbuild bundling, not test count or redundant synths. This single change beats 4-way sharding (~14%) and synth-dedup (~0%) by a wide margin, with no CI complexity. #365 (sharding) is likely now moot — to be re-evaluated once this lands and we see the new CI baseline.
Durable regression guards
beforeAll)..abca/commands/review_pr.md: a Stage-3 checklist item so PR review catches regressions.Safety / blast radius
test/bootstrap/version.test.ts) is a bootstrap policy hash, not a CDK asset hash, and synthesizes no stack — unaffected.aws:cdk:bundling-stacks: ['**']in its ownAppcontext (documented in the setup file).Dependency note
The AGENTS.md / review_pr.md links point to
docs/design/CI_BUILD_PERFORMANCE.md, which is added by PR #364 (the design doc, currently draft). Merge #364 first (or together) so the links resolve.Draft
Opened as draft while under review per WIP discipline. Will mark ready once the 4-core CI build posts green and #364 ordering is settled.
🤖 Generated with Claude Code