fix(amplify-graphql-api-construct-tests): pin cdk init CLI and type e2e lambda scaffolds - #3519
Conversation
…2e lambda scaffolds
Fixes the deterministic custom_query_mutation_extension and admin_role e2e failures.
The e2e scratch-project scaffolder pinned aws-cdk-lib but ran `npx cdk init` with a
floating CLI. The upstream template has since changed the cdk.json synth command from
`npx ts-node --prefer-ts-exts bin/app.ts` to `npx tsc && npx tsx bin/app.ts` on
TypeScript ~7.0 with strict/noImplicitAny and no tsconfig include, so synth now begins
with a whole-project typecheck of every .ts in the scratch project.
Backend templates are copied wholesale into bin/, including lambda entry points that are
only ever referenced by esbuild as a path string and never imported by app.ts. Those files
are now typechecked from a directory they were never written to resolve from, failing
before synth:
- custom-query-mutation-extension/authorizer.ts:1:26 TS7006 (untyped event)
- admin-role/apiInvoker.ts:6:51 TS2307 ('../../../lambda-request' escapes the project)
- Pin the aws-cdk CLI so the template cannot drift again. The CLI and aws-cdk-lib have
used separate version lines since CLI v2.1000.0, so the CLI is pinned to its own
constant rather than to cdkVersion (no aws-cdk release matches aws-cdk-lib 2.260.0,
and cdkVersion may legitimately be 'latest').
- Drop the whole-project typecheck from the generated synth command, restoring the
historical behavior where synth only loads the app's import graph. The runtime
invocation is unchanged.
- Type the authorizer handler event, and inline the response type in apiInvoker.ts so the
bundled lambda entry is self-contained. All previously exported names remain exported.
CI StatusThe e2e runs for this PR are green except for the What this PR fixes (now passing ✅): the two toolchain-drift failures caused by the unpinned
Both now pass on the pinned CLI ( Remaining e2e failures — NOT caused by this PR: the Once #3518 merges, these groups will pass on this branch as well. This PR should not be blocked on them. ( |
| if (typeof cdkJson.app !== 'string') { | ||
| return; | ||
| } | ||
| const appWithoutTypecheck = cdkJson.app.replace(/^\s*npx\s+tsc\s*&&\s*/, ''); |
There was a problem hiding this comment.
minor: Since the regex and CDK_CLI_VERSION are coupled — if someone bumps the version and the new template's synth command is slightly different (e.g. tsc --build && or no npx prefix), this silently becomes a no-op and you'd get a confusing synth failure. Might be worth adding a warning when tsc is present but the regex didn't match:
if (appWithoutTypecheck === cdkJson.app && cdkJson.app.includes('tsc')) {
console.warn(`[initCDKProject] synth command contains 'tsc' but didn't match removal pattern: ${cdkJson.app}`);
}There was a problem hiding this comment.
Good idea. Will adjust in the next PR.
…s matching Addresses #3519 review feedback.
Problem
Two CDK e2e groups fail deterministically (6/6 locally reproduced), on
mainand on every open PR:custom_query_mutation_extensionbackends/custom-query-mutation-extension/authorizer.ts:1:26TS7006— Parametereventimplicitly has ananytypeadmin_rolebackends/admin-role/apiInvoker.ts:6:51TS2307— Cannot find module'../../../lambda-request'Both fail before
cdk synthruns, so no stack is ever deployed.Root cause: unpinned
cdk initCLI toolchain driftinitCDKProject()inpackages/amplify-graphql-api-construct-tests/src/commands.tspinsaws-cdk-lib(2.260.0) but rancdk initwith a floating CLI:The upstream TypeScript app template has since changed. Verified by running both CLIs into temp dirs:
2.179.0(old, working)2.1134.0(current)cdk.jsonappnpx ts-node --prefer-ts-exts bin/app.tsnpx tsc && npx tsx bin/app.tstypescript~5.6.3~7.0.2tsconfigincludestrict/noImplicitAnyThe critical change is the
npx tsc &&prefix.ts-nodeonly ever compiled the import graph reachable fromapp.ts.npx tscwith noincludeglob typechecks every.tsfile in the scratch project.That matters because
copyTemplateDirectory()copySyncs the whole backend directory flat intobin/. Several of those files are lambda entry points that are only ever referenced by esbuild as a path string — never imported:So they are now typechecked from
bin/, a directory they were never written to resolve from, and their relative import'../../../lambda-request'escapes the scratch project entirely.This is pre-existing on
mainand unrelated to any product code.Fix
aws-cdkCLI (durable — stops the template drifting again).Note the CLI could not be pinned to
cdkVersion:aws-cdkandaws-cdk-libhave used separate version lines since CLIv2.1000.0, so there is noaws-cdk@2.260.0(noraws-cdk@2.224.0) to install — andcdkVersionis legitimately'latest'in some tests. It therefore gets its ownCDK_CLI_VERSIONconstant.ts-nodesemantics where synth only loads the app's import graph. The runtime invocation (npx tsx bin/app.ts) is unchanged — only thenpx tsc &&gate is removed. This makes the scaffolder immune to any stray non-imported.tsin a backend, not just today's two.authorizer.ts— type the handlereventparam (behavior identical).apiInvoker.ts— inline the self-containedGraphqlProxiedLambdaResponsetype instead of importing it from outside the bundle. All previously exported names remain exported, soadmin-role.test.ts'simport type { CreateTodoHandlerEvent, CreateTodoResponseData }still compiles.Validation
Faithful local repro of
initCDKProject()(pinnedcdk init→ copy backend flat intobin/→ renameapp.ts→ installadditionalDependencies):tsc --build tsconfig.tests.json→ exit0prettier --checkon all 3 changed files → cleanPASS, construct-dependency validation, license extraction)Full e2e is CI's job — CodeBuild batches triggered on this branch.