From e98f20da795d9e48701df8f7730263bb3b12b7d6 Mon Sep 17 00:00:00 2001 From: Jesse Turner Date: Tue, 14 Jul 2026 21:13:49 +0000 Subject: [PATCH 1/2] fix(deploy): pin vended aws-cdk-lib and enforce cloud-assembly schema compat The vended CDK template declared aws-cdk-lib with a caret range, so fresh projects resolve whatever npm serves. When upstream aws-cdk-lib bumps its cloud-assembly schema major, new projects write manifests the CLI's bundled readers (@aws-cdk/toolkit-lib, @aws-cdk/cdk-assets-lib) cannot parse, and agentcore deploy fails with AssemblyVersionMismatch. Pin the template's aws-cdk-lib to an exact version (2.261.0, schema v54) and keep it in lockstep with the CLI's readers: - src/assets/cdk/package.json: aws-cdk-lib ^2.248.0 -> 2.261.0 (exact) - package.json: exact-pin the aws-cdk-lib devDependency as the lockstep anchor; regenerate npm-shrinkwrap.json - New unit test (cdk-schema-compat.test.ts) asserts the template pin, root devDep, and installed copy match, and that each bundled reader supports a schema major >= what the pinned aws-cdk-lib writes - New scripts/sync-template-cdk.mjs re-syncs the pins and snapshots in one command; the test's failure messages point to it - dependabot.yml comment + docs/testing/unit-tests.md section describing the workflow for aws-cdk group bumps Verified: full unit suite green; fresh agentcore create vends the exact pin and resolves cloud-assembly-schema 54.x; negative tests (drifted pin, simulated schema-55 writer) fail with actionable messages. --- .github/dependabot.yml | 3 + docs/testing/unit-tests.md | 26 +++ npm-shrinkwrap.json | 198 +----------------- package.json | 2 +- scripts/sync-template-cdk.mjs | 91 ++++++++ .../assets.snapshot.test.ts.snap | 2 +- .../__tests__/cdk-schema-compat.test.ts | 103 +++++++++ src/assets/cdk/package.json | 2 +- 8 files changed, 232 insertions(+), 195 deletions(-) create mode 100644 scripts/sync-template-cdk.mjs create mode 100644 src/assets/__tests__/cdk-schema-compat.test.ts diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 09ed2343c..bb2abc41f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,6 +9,9 @@ updates: patterns: - '@aws-sdk/*' - '@smithy/*' + # aws-cdk-lib bumps must be synced into the vended template + # (src/assets/cdk/package.json): run `node scripts/sync-template-cdk.mjs` + # on the PR branch. Enforced by src/assets/__tests__/cdk-schema-compat.test.ts. aws-cdk: patterns: - '@aws-cdk/*' diff --git a/docs/testing/unit-tests.md b/docs/testing/unit-tests.md index 6c3a09fd7..ba6b8b6c7 100644 --- a/docs/testing/unit-tests.md +++ b/docs/testing/unit-tests.md @@ -105,3 +105,29 @@ Review the changes in `src/assets/__tests__/__snapshots__/` before committing. - File structure of `src/assets/` - Contents of all template files (CDK, Python frameworks, MCP, static assets) - Any file addition or removal + +## CDK Schema Compatibility Test + +The vended CDK template (`src/assets/cdk/package.json`) exact-pins `aws-cdk-lib`. This pin controls the cloud-assembly +schema version that user projects _write_ at synth time; the CLI's bundled readers (`@aws-cdk/toolkit-lib`, +`@aws-cdk/cdk-assets-lib`) can only _read_ schemas up to their own version. Readers accept older schemas but hard-fail +on newer ones, so an unpinned template broke every fresh project's deploy with `AssemblyVersionMismatch` when upstream +`aws-cdk-lib` bumped the schema (ticket V2240408418). + +`src/assets/__tests__/cdk-schema-compat.test.ts` enforces the coupling: + +- The template pin is exact and matches both the root `devDependencies['aws-cdk-lib']` (the lockstep anchor) and the + installed copy in `node_modules`. +- Each bundled reader's max supported schema version is >= the schema version the pinned `aws-cdk-lib` writes. + +When a Dependabot PR bumps the `aws-cdk` group (or you bump `aws-cdk-lib` manually), this test fails until you re-sync. +Fix it with one command on the PR branch: + +```bash +npm ci && node scripts/sync-template-cdk.mjs +``` + +The script copies the installed `aws-cdk-lib` version into the root devDependency and the template pin, then regenerates +asset snapshots. Commit the resulting changes (if the root `package.json` changed, run `npm install` first so +`npm-shrinkwrap.json` is regenerated too). Note that `@dependabot rebase` recreates the PR branch and drops the sync +commit — just re-run the script. diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 9d26c978c..226e0f6bc 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,12 +1,12 @@ { "name": "@aws/agentcore", - "version": "0.23.0", + "version": "0.24.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@aws/agentcore", - "version": "0.23.0", + "version": "0.24.1", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -68,7 +68,7 @@ "@typescript-eslint/parser": "^8.50.0", "@vitest/coverage-v8": "^4.0.18", "@xterm/headless": "^6.0.0", - "aws-cdk-lib": "^2.258.0", + "aws-cdk-lib": "2.261.0", "constructs": "^10.4.4", "esbuild": "^0.28.0", "eslint": "^9.39.4", @@ -7218,9 +7218,9 @@ } }, "node_modules/aws-cdk-lib": { - "version": "2.258.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.258.0.tgz", - "integrity": "sha512-OfFfg30ikBRJ3dimlzsWhPIrj6qug1p2XYsdB38CtMtcur7SufzoUczgI6kWjbQkOVcQgYzhzN29DErV0yZG7A==", + "version": "2.261.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.261.0.tgz", + "integrity": "sha512-e52e3Abjg0HkuRWlWwtSv5+ZiMW1rhCDdL9ff7lzWXInU8xdfLJpuoimfa0IJwjiNGyphppgg52Azx9M80OA0g==", "bundleDependencies": [ "@balena/dockerignore", "@aws-cdk/cloud-assembly-api", @@ -7231,7 +7231,6 @@ "minimatch", "punycode", "semver", - "table", "yaml", "mime-types" ], @@ -7251,7 +7250,6 @@ "minimatch": "^10.2.5", "punycode": "^2.3.1", "semver": "^7.8.1", - "table": "^6.9.0", "yaml": "1.10.3" }, "engines": { @@ -7283,55 +7281,6 @@ "inBundle": true, "license": "Apache-2.0" }, - "node_modules/aws-cdk-lib/node_modules/ajv": { - "version": "8.20.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/aws-cdk-lib/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/aws-cdk-lib/node_modules/astral-regex": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/aws-cdk-lib/node_modules/balanced-match": { "version": "4.0.4", "dev": true, @@ -7362,52 +7311,6 @@ "node": ">= 0.8.0" } }, - "node_modules/aws-cdk-lib/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/fast-deep-equal": { - "version": "3.1.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/fast-uri": { - "version": "3.1.2", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "inBundle": true, - "license": "BSD-3-Clause" - }, "node_modules/aws-cdk-lib/node_modules/fs-extra": { "version": "11.3.5", "dev": true, @@ -7437,21 +7340,6 @@ "node": ">= 4" } }, - "node_modules/aws-cdk-lib/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/aws-cdk-lib/node_modules/jsonfile": { "version": "6.2.1", "dev": true, @@ -7473,12 +7361,6 @@ "node": "*" } }, - "node_modules/aws-cdk-lib/node_modules/lodash.truncate": { - "version": "4.4.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/aws-cdk-lib/node_modules/mime-db": { "version": "1.52.0", "dev": true, @@ -7524,15 +7406,6 @@ "node": ">=6" } }, - "node_modules/aws-cdk-lib/node_modules/require-from-string": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/aws-cdk-lib/node_modules/semver": { "version": "7.8.1", "dev": true, @@ -7545,65 +7418,6 @@ "node": ">=10" } }, - "node_modules/aws-cdk-lib/node_modules/slice-ansi": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/aws-cdk-lib/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/table": { - "version": "6.9.0", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause", - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/aws-cdk-lib/node_modules/universalify": { "version": "2.0.1", "dev": true, diff --git a/package.json b/package.json index 7e6e23e97..1dfa2a5c3 100644 --- a/package.json +++ b/package.json @@ -136,7 +136,7 @@ "@typescript-eslint/parser": "^8.50.0", "@vitest/coverage-v8": "^4.0.18", "@xterm/headless": "^6.0.0", - "aws-cdk-lib": "^2.258.0", + "aws-cdk-lib": "2.261.0", "constructs": "^10.4.4", "esbuild": "^0.28.0", "eslint": "^9.39.4", diff --git a/scripts/sync-template-cdk.mjs b/scripts/sync-template-cdk.mjs new file mode 100644 index 000000000..506d01e18 --- /dev/null +++ b/scripts/sync-template-cdk.mjs @@ -0,0 +1,91 @@ +/** + * Syncs the aws-cdk-lib version across the three places that must stay in + * lockstep (enforced by src/assets/__tests__/cdk-schema-compat.test.ts): + * + * 1. node_modules/aws-cdk-lib — source of truth (whatever npm resolved) + * 2. package.json devDependencies — the lockstep anchor + * 3. src/assets/cdk/package.json — the template vended to user projects + * + * The template pin controls the cloud-assembly schema version fresh user + * projects write; the CLI's bundled toolkit-lib/cdk-assets-lib readers must + * be able to read it, or `agentcore deploy` fails with AssemblyVersionMismatch. + * + * Typical use on a Dependabot aws-cdk bump PR: + * + * npm ci && node scripts/sync-template-cdk.mjs + * + * Pass --no-snapshots to skip the asset-snapshot regeneration step. + */ +import { spawnSync } from 'child_process'; +import * as fs from 'fs'; +import * as path from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const repoRoot = path.join(__dirname, '..'); +const installedPkgPath = path.join(repoRoot, 'node_modules', 'aws-cdk-lib', 'package.json'); +const rootPkgPath = path.join(repoRoot, 'package.json'); +const templatePkgPath = path.join(repoRoot, 'src', 'assets', 'cdk', 'package.json'); + +/** + * Rewrite the aws-cdk-lib version specifier in a package.json section via + * targeted string replacement, preserving the file's existing formatting. + * @param {string} filePath - package.json to rewrite + * @param {'dependencies' | 'devDependencies'} section - section holding aws-cdk-lib + * @param {string} version - exact version to pin + * @returns {boolean} whether the file changed + */ +function pinAwsCdkLib(filePath, section, version) { + const content = fs.readFileSync(filePath, 'utf-8'); + const pkg = JSON.parse(content); + const current = pkg[section]?.['aws-cdk-lib']; + if (current === undefined) { + console.error(`Error: ${filePath} has no aws-cdk-lib in ${section}.`); + process.exit(1); + } + if (current === version) { + return false; + } + const updated = content.replace(`"aws-cdk-lib": "${current}"`, `"aws-cdk-lib": "${version}"`); + if (updated === content) { + console.error(`Error: could not rewrite aws-cdk-lib specifier "${current}" in ${filePath}.`); + process.exit(1); + } + fs.writeFileSync(filePath, updated); + return true; +} + +if (!fs.existsSync(installedPkgPath)) { + console.error('Error: aws-cdk-lib is not installed. Run "npm ci" first.'); + process.exit(1); +} + +const version = JSON.parse(fs.readFileSync(installedPkgPath, 'utf-8')).version; +console.log(`Installed aws-cdk-lib: ${version}`); + +const rootChanged = pinAwsCdkLib(rootPkgPath, 'devDependencies', version); +console.log(rootChanged ? `Updated package.json devDependency to ${version}` : 'package.json already in sync'); + +const templateChanged = pinAwsCdkLib(templatePkgPath, 'dependencies', version); +console.log(templateChanged ? `Updated src/assets/cdk/package.json pin to ${version}` : 'Template already in sync'); + +if (rootChanged) { + console.log('Note: package.json changed — run "npm install" to update npm-shrinkwrap.json, and commit both.'); +} + +if (templateChanged) { + if (process.argv.includes('--no-snapshots')) { + console.log('Skipping snapshot update (--no-snapshots). Run "npm run test:update-snapshots" before committing.'); + } else { + console.log('Regenerating asset snapshots...'); + const result = spawnSync('npm', ['run', 'test:update-snapshots'], { cwd: repoRoot, stdio: 'inherit' }); + if (result.status !== 0) { + console.error('Error: snapshot update failed.'); + process.exit(1); + } + } +} + +console.log(rootChanged || templateChanged ? 'Sync complete.' : 'Everything already in sync — nothing to do.'); diff --git a/src/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap b/src/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap index b935e4f72..3b3749adb 100644 --- a/src/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap +++ b/src/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap @@ -646,7 +646,7 @@ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/package.json should m }, "dependencies": { "@aws/agentcore-cdk": "^0.1.0-alpha.19", - "aws-cdk-lib": "^2.248.0", + "aws-cdk-lib": "2.261.0", "constructs": "^10.0.0" } } diff --git a/src/assets/__tests__/cdk-schema-compat.test.ts b/src/assets/__tests__/cdk-schema-compat.test.ts new file mode 100644 index 000000000..e8f0c7e19 --- /dev/null +++ b/src/assets/__tests__/cdk-schema-compat.test.ts @@ -0,0 +1,103 @@ +/** + * Guards against cloud-assembly schema drift between the vended CDK template + * and the CLI's bundled readers (@aws-cdk/toolkit-lib, @aws-cdk/cdk-assets-lib). + * + * The template's aws-cdk-lib determines the schema version a user project + * *writes*; the bundled readers determine the schema version the CLI can + * *read* during deploy. Readers accept older schemas but hard-fail on newer + * ones (AssemblyVersionMismatch), so the template pin must never emit a + * schema newer than the readers support. See ticket V2240408418 for the + * outage this prevents. + * + * If any test here fails after a dependency bump, run: + * + * node scripts/sync-template-cdk.mjs + */ +import * as fs from 'fs'; +import { createRequire } from 'module'; +import * as path from 'path'; +import { describe, expect, it } from 'vitest'; + +const REPO_ROOT = path.resolve(__dirname, '../../..'); +const HOW_TO_FIX = 'Run `node scripts/sync-template-cdk.mjs` to re-sync the template pin and snapshots.'; +const EXACT_VERSION = /^\d+\.\d+\.\d+$/; +const READERS = ['@aws-cdk/toolkit-lib', '@aws-cdk/cdk-assets-lib']; + +const requireFromRoot = createRequire(path.join(REPO_ROOT, 'package.json')); + +function readJson(filePath: string): Record { + return JSON.parse(fs.readFileSync(filePath, 'utf-8')); +} + +const templatePkg = readJson(path.join(REPO_ROOT, 'src/assets/cdk/package.json')); +const rootPkg = readJson(path.join(REPO_ROOT, 'package.json')); +const templatePin: string = templatePkg.dependencies['aws-cdk-lib']; + +/** + * Max cloud-assembly schema major a reader supports. Manifest.version() + * returns `${revision}.0.0` from schema/version.json in the schema copy the + * reader resolves, and validation rejects manifests with a greater major. + * Resolving per-reader handles nested/deduped schema copies in node_modules. + */ +function readerMaxSchemaMajor(readerName: string): number { + const readerPkgJsonPath = requireFromRoot.resolve(`${readerName}/package.json`); + const requireFromReader = createRequire(readerPkgJsonPath); + const schemaPkgJsonPath = requireFromReader.resolve('@aws-cdk/cloud-assembly-schema/package.json'); + const versionJson = readJson(path.join(path.dirname(schemaPkgJsonPath), 'schema', 'version.json')); + return versionJson.revision; +} + +/** + * Cloud-assembly schema major that the pinned aws-cdk-lib writes in a fresh + * user project. aws-cdk-lib declares @aws-cdk/cloud-assembly-schema with a + * caret range, which fixes the major — the only component that matters for + * reader compatibility. + */ +function emittedSchemaMajor(): number { + const cdkLibPkg = readJson(requireFromRoot.resolve('aws-cdk-lib/package.json')); + const range: string = cdkLibPkg.dependencies['@aws-cdk/cloud-assembly-schema']; + const match = /^\^(\d+)\./.exec(range); + if (!match) { + throw new Error( + `aws-cdk-lib's @aws-cdk/cloud-assembly-schema range "${range}" is not caret-style; ` + + `this test's major-version parsing is no longer sound and must be updated.` + ); + } + return Number(match[1]); +} + +describe('vended CDK template / bundled cloud-assembly reader compatibility', () => { + it('template exact-pins aws-cdk-lib', () => { + expect(templatePin, `Template must exact-pin aws-cdk-lib, got "${templatePin}". ${HOW_TO_FIX}`).toMatch( + EXACT_VERSION + ); + }); + + it('root devDependency is exact and in lockstep with the template pin', () => { + const rootDevDep = rootPkg.devDependencies['aws-cdk-lib']; + expect( + rootDevDep, + `Root devDependency aws-cdk-lib ("${rootDevDep}") must equal the template pin ("${templatePin}"). ${HOW_TO_FIX}` + ).toBe(templatePin); + }); + + it('installed aws-cdk-lib matches the template pin', () => { + const installed = readJson(requireFromRoot.resolve('aws-cdk-lib/package.json')).version; + expect( + installed, + `Installed aws-cdk-lib (${installed}) does not match the template pin (${templatePin}) — ` + + `node_modules may be stale; run \`npm ci\`. ${HOW_TO_FIX}` + ).toBe(templatePin); + }); + + it.each(READERS)('%s can read cloud assemblies written by the pinned aws-cdk-lib', reader => { + const readerMajor = readerMaxSchemaMajor(reader); + const emitted = emittedSchemaMajor(); + expect( + readerMajor, + `aws-cdk-lib@${templatePin} writes cloud-assembly schema v${emitted}, but ${reader} reads only up to ` + + `v${readerMajor}. Fresh projects would fail \`agentcore deploy\` with AssemblyVersionMismatch. ` + + `Bump ${reader} (npm install) or pin aws-cdk-lib to an older version, then run the sync script. ${HOW_TO_FIX}` + ).toBeGreaterThanOrEqual(emitted); + }); +}); diff --git a/src/assets/cdk/package.json b/src/assets/cdk/package.json index 4646bfb3e..299cbd874 100644 --- a/src/assets/cdk/package.json +++ b/src/assets/cdk/package.json @@ -24,7 +24,7 @@ }, "dependencies": { "@aws/agentcore-cdk": "^0.1.0-alpha.19", - "aws-cdk-lib": "^2.248.0", + "aws-cdk-lib": "2.261.0", "constructs": "^10.0.0" } } From 4b15e8ec90fd8573f4c39f9a5292d128b93c76ea Mon Sep 17 00:00:00 2001 From: Jesse Turner Date: Tue, 14 Jul 2026 21:23:55 +0000 Subject: [PATCH 2/2] docs: trim CDK schema compat test section --- docs/testing/unit-tests.md | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/docs/testing/unit-tests.md b/docs/testing/unit-tests.md index ba6b8b6c7..331ef915c 100644 --- a/docs/testing/unit-tests.md +++ b/docs/testing/unit-tests.md @@ -108,26 +108,15 @@ Review the changes in `src/assets/__tests__/__snapshots__/` before committing. ## CDK Schema Compatibility Test -The vended CDK template (`src/assets/cdk/package.json`) exact-pins `aws-cdk-lib`. This pin controls the cloud-assembly -schema version that user projects _write_ at synth time; the CLI's bundled readers (`@aws-cdk/toolkit-lib`, -`@aws-cdk/cdk-assets-lib`) can only _read_ schemas up to their own version. Readers accept older schemas but hard-fail -on newer ones, so an unpinned template broke every fresh project's deploy with `AssemblyVersionMismatch` when upstream -`aws-cdk-lib` bumped the schema (ticket V2240408418). +`src/assets/__tests__/cdk-schema-compat.test.ts` keeps the vended template's exact `aws-cdk-lib` pin in lockstep with +the CLI's bundled cloud-assembly readers (`@aws-cdk/toolkit-lib`, `@aws-cdk/cdk-assets-lib`) — an unpinned or drifted +template breaks fresh projects' deploys with `AssemblyVersionMismatch`. See the test file's header for details. -`src/assets/__tests__/cdk-schema-compat.test.ts` enforces the coupling: - -- The template pin is exact and matches both the root `devDependencies['aws-cdk-lib']` (the lockstep anchor) and the - installed copy in `node_modules`. -- Each bundled reader's max supported schema version is >= the schema version the pinned `aws-cdk-lib` writes. - -When a Dependabot PR bumps the `aws-cdk` group (or you bump `aws-cdk-lib` manually), this test fails until you re-sync. -Fix it with one command on the PR branch: +If it fails after an `aws-cdk-lib` bump (e.g. a Dependabot `aws-cdk` group PR), re-sync with: ```bash npm ci && node scripts/sync-template-cdk.mjs ``` -The script copies the installed `aws-cdk-lib` version into the root devDependency and the template pin, then regenerates -asset snapshots. Commit the resulting changes (if the root `package.json` changed, run `npm install` first so -`npm-shrinkwrap.json` is regenerated too). Note that `@dependabot rebase` recreates the PR branch and drops the sync -commit — just re-run the script. +then commit the changes (run `npm install` first if the root `package.json` changed, so `npm-shrinkwrap.json` is +regenerated). `@dependabot rebase` drops the sync commit — just re-run the script.