@aws/nx-plugin 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-THIRD-PARTY +3 -3
- package/migrations.json +26 -1
- package/package.json +1 -1
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +10 -0
- package/src/infra/app/files/app/README.md.template +12 -0
- package/src/infra/app/generator.js +8 -0
- package/src/infra/app/generator.js.map +1 -1
- package/src/migrations/latest/cache-inputs-outputs/metadata.json +3 -0
- package/src/migrations/latest/cache-inputs-outputs/migration.d.ts +6 -0
- package/src/migrations/latest/cache-inputs-outputs/migration.js +176 -0
- package/src/migrations/latest/cache-inputs-outputs/migration.js.map +1 -0
- package/src/migrations/latest/infra-test-loop/metadata.json +3 -0
- package/src/migrations/latest/infra-test-loop/migration.d.ts +6 -0
- package/src/migrations/latest/infra-test-loop/migration.js +110 -0
- package/src/migrations/latest/infra-test-loop/migration.js.map +1 -0
- package/src/migrations/latest/pin-strands-express-peer/metadata.json +3 -0
- package/src/migrations/latest/pin-strands-express-peer/migration.d.ts +29 -0
- package/src/migrations/latest/pin-strands-express-peer/migration.js +58 -0
- package/src/migrations/latest/pin-strands-express-peer/migration.js.map +1 -0
- package/src/migrations/latest/py-dynamodb-type-base-model-meta/metadata.json +3 -0
- package/src/migrations/latest/py-dynamodb-type-base-model-meta/migration.d.ts +6 -0
- package/src/migrations/latest/py-dynamodb-type-base-model-meta/migration.js +87 -0
- package/src/migrations/latest/py-dynamodb-type-base-model-meta/migration.js.map +1 -0
- package/src/migrations/latest/rdb-drop-lambda-rie/metadata.json +3 -0
- package/src/migrations/latest/rdb-drop-lambda-rie/migration.d.ts +6 -0
- package/src/migrations/latest/rdb-drop-lambda-rie/migration.js +105 -0
- package/src/migrations/latest/rdb-drop-lambda-rie/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.90/0004-python-test-input-scoping/migration.js +8 -2
- package/src/migrations/v1.0.0-rc.90/0004-python-test-input-scoping/migration.js.map +1 -1
- package/src/open-api/py-client/files/client/__clientModuleName__.py.template +17 -6
- package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +4 -4
- package/src/py/dynamodb/files/__name__/entities/base.py.template +2 -2
- package/src/py/rdb/__snapshots__/generator.spec.ts.snap +20 -8
- package/src/py/rdb/files/Dockerfile.create-db-user.template +5 -2
- package/src/py/rdb/files/Dockerfile.migration.template +5 -2
- package/src/smithy/project/__snapshots__/generator.spec.ts.snap +9 -0
- package/src/smithy/project/generator.d.ts +9 -0
- package/src/smithy/project/generator.js +15 -0
- package/src/smithy/project/generator.js.map +1 -1
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +2 -0
- package/src/terraform/project/generator.js +2 -4
- package/src/terraform/project/generator.js.map +1 -1
- package/src/ts/agent/a2a-connection/generator.d.ts +26 -30
- package/src/ts/agent/a2a-connection/generator.js +9 -5
- package/src/ts/agent/a2a-connection/generator.js.map +1 -1
- package/src/ts/agent/gateway-connection/generator.d.ts +5 -7
- package/src/ts/agent/gateway-connection/generator.js +12 -0
- package/src/ts/agent/gateway-connection/generator.js.map +1 -1
- package/src/ts/agent/generator.d.ts +3 -8
- package/src/ts/agent/generator.js +16 -2
- package/src/ts/agent/generator.js.map +1 -1
- package/src/ts/agent/mcp-connection/generator.d.ts +5 -7
- package/src/ts/agent/mcp-connection/generator.js +12 -0
- package/src/ts/agent/mcp-connection/generator.js.map +1 -1
- package/src/ts/astro-docs/generator.d.ts +4 -4
- package/src/ts/astro-docs/generator.js +10 -4
- package/src/ts/astro-docs/generator.js.map +1 -1
- package/src/ts/lib/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/ts/lib/generator.d.ts +14 -3
- package/src/ts/lib/generator.js +18 -7
- package/src/ts/lib/generator.js.map +1 -1
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +4 -2
- package/src/ts/rdb/files/Dockerfile.template +4 -2
- package/src/ts/rdb/generator.js +4 -0
- package/src/ts/rdb/generator.js.map +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +102 -2
- package/src/utils/__snapshots__/cdk-test-setup.spec.ts.snap +25 -0
- package/src/utils/agent-connection/agent-connection.d.ts +28 -5
- package/src/utils/agent-connection/agent-connection.js +39 -14
- package/src/utils/agent-connection/agent-connection.js.map +1 -1
- package/src/utils/cdk-test-setup.d.ts +22 -0
- package/src/utils/cdk-test-setup.js +38 -0
- package/src/utils/cdk-test-setup.js.map +1 -0
- package/src/utils/files/cdk-test-setup/tests/global-setup.ts.template +45 -0
- package/src/utils/shared-constructs.js +2 -0
- package/src/utils/shared-constructs.js.map +1 -1
- package/src/utils/test/python-dependencies.d.ts +6 -0
- package/src/utils/test/python-dependencies.js +9 -0
- package/src/utils/test/python-dependencies.js.map +1 -1
- package/src/utils/test/warm-python-cache.js +40 -21
- package/src/utils/test/warm-python-cache.js.map +1 -1
- package/src/utils/versions.d.ts +2 -2
- package/src/utils/versions.js +2 -2
- package/src/utils/versions.js.map +1 -1
package/LICENSE-THIRD-PARTY
CHANGED
|
@@ -4274,7 +4274,7 @@ SOFTWARE.
|
|
|
4274
4274
|
|
|
4275
4275
|
---
|
|
4276
4276
|
|
|
4277
|
-
The following software may be included in this product: @oxc-project/types (0.
|
|
4277
|
+
The following software may be included in this product: @oxc-project/types (0.152.0)
|
|
4278
4278
|
This software contains the following license and notice below:
|
|
4279
4279
|
|
|
4280
4280
|
MIT License
|
|
@@ -13381,7 +13381,7 @@ SOFTWARE.**
|
|
|
13381
13381
|
|
|
13382
13382
|
---
|
|
13383
13383
|
|
|
13384
|
-
The following software may be included in this product: proxy-addr (2.0.
|
|
13384
|
+
The following software may be included in this product: proxy-addr (2.0.8)
|
|
13385
13385
|
This software contains the following license and notice below:
|
|
13386
13386
|
|
|
13387
13387
|
(The MIT License)
|
|
@@ -14165,7 +14165,7 @@ SOFTWARE.
|
|
|
14165
14165
|
|
|
14166
14166
|
---
|
|
14167
14167
|
|
|
14168
|
-
The following software may be included in this product: rolldown (1.2.
|
|
14168
|
+
The following software may be included in this product: rolldown (1.2.12)
|
|
14169
14169
|
This software contains the following license and notice below:
|
|
14170
14170
|
|
|
14171
14171
|
MIT License
|
package/migrations.json
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
"$schema": "http://json-schema.org/schema",
|
|
3
3
|
"name": "@aws/nx-plugin",
|
|
4
4
|
"generators": {
|
|
5
|
+
"latest-pin-strands-express-peer": {
|
|
6
|
+
"version": "1.0.7",
|
|
7
|
+
"description": "Declare express in every project that declares @strands-agents/sdk without it so @strands-agents/sdk resolves to a single peer-suffixed instance",
|
|
8
|
+
"implementation": "./src/migrations/latest/pin-strands-express-peer/migration"
|
|
9
|
+
},
|
|
10
|
+
"latest-rdb-drop-lambda-rie": {
|
|
11
|
+
"version": "1.0.7",
|
|
12
|
+
"description": "Remove the Lambda Runtime Interface Emulator from vended ts#rdb and py#rdb Dockerfiles so its known HIGH vulnerabilities are not present in the image",
|
|
13
|
+
"implementation": "./src/migrations/latest/rdb-drop-lambda-rie/migration"
|
|
14
|
+
},
|
|
15
|
+
"latest-infra-test-loop": {
|
|
16
|
+
"version": "1.0.8",
|
|
17
|
+
"description": "Run CDK infrastructure tests against the artifacts their stacks deploy rather than every upstream build, in a per-run temp directory with CDK asset bundling skipped",
|
|
18
|
+
"implementation": "./src/migrations/latest/infra-test-loop/migration"
|
|
19
|
+
},
|
|
20
|
+
"latest-py-dynamodb-type-base-model-meta": {
|
|
21
|
+
"version": "1.0.8",
|
|
22
|
+
"description": "Declare the py#dynamodb BaseModel Meta class as a subclass of pynamodb's MetaProtocol so the generated project type checks with ty 0.0.86",
|
|
23
|
+
"implementation": "./src/migrations/latest/py-dynamodb-type-base-model-meta/migration"
|
|
24
|
+
},
|
|
25
|
+
"latest-cache-inputs-outputs": {
|
|
26
|
+
"version": "1.0.8",
|
|
27
|
+
"description": "Keep checkov reports and vitest coverage out of downstream task hashes, declare Smithy build inputs, cache ts#rdb Prisma client generation and stop caching Terraform output",
|
|
28
|
+
"implementation": "./src/migrations/latest/cache-inputs-outputs/migration"
|
|
29
|
+
},
|
|
5
30
|
"v1.0.0-rc.50-0001-modernize-function-props-cast": {
|
|
6
31
|
"version": "1.0.0-rc.50",
|
|
7
32
|
"description": "Replace the legacy angle-bracket FunctionProps type assertion with the modern as syntax in generated API constructs",
|
|
@@ -383,7 +408,7 @@
|
|
|
383
408
|
"implementation": "./src/migrations/v1.0.5/0001-api-custom-domain-runtime-config/migration"
|
|
384
409
|
},
|
|
385
410
|
"sync-vended-versions": {
|
|
386
|
-
"version": "1.0.
|
|
411
|
+
"version": "1.0.8",
|
|
387
412
|
"description": "Sync vended dependency versions and the tracked plugin version to those vended by this release",
|
|
388
413
|
"implementation": "./src/utils/version-upgrade-migration/migration"
|
|
389
414
|
}
|
package/package.json
CHANGED
|
@@ -281,6 +281,11 @@ exports[`infra generator > should configure project.json with correct targets >
|
|
|
281
281
|
"{workspaceRoot}/dist/{projectRoot}/cdk.out",
|
|
282
282
|
],
|
|
283
283
|
},
|
|
284
|
+
"test": {
|
|
285
|
+
"dependsOn": [
|
|
286
|
+
"^assemble",
|
|
287
|
+
],
|
|
288
|
+
},
|
|
284
289
|
},
|
|
285
290
|
}
|
|
286
291
|
`;
|
|
@@ -893,6 +898,11 @@ exports[`infra generator > should handle custom project names correctly > custom
|
|
|
893
898
|
"{workspaceRoot}/dist/{projectRoot}/cdk.out",
|
|
894
899
|
],
|
|
895
900
|
},
|
|
901
|
+
"test": {
|
|
902
|
+
"dependsOn": [
|
|
903
|
+
"^assemble",
|
|
904
|
+
],
|
|
905
|
+
},
|
|
896
906
|
},
|
|
897
907
|
}
|
|
898
908
|
`;
|
|
@@ -9,6 +9,18 @@ Run `<%= pkgMgrCmd %> nx build <%= fullyQualifiedName %> [--skip-nx-cache]` to b
|
|
|
9
9
|
|
|
10
10
|
Run `<%= pkgMgrCmd %> nx test <%= fullyQualifiedName %>` to execute the unit tests via Vitest.
|
|
11
11
|
|
|
12
|
+
Tests run against the artifacts each deployed project's `assemble` target produces (bundles, packages and, where a project builds a container image, the image build), rather than every upstream project's lint, test and type-check gates. Projects that build a container image (container agents and MCP servers, RDB) still run their image build under `test`, because that build also stages the asset the construct reads.
|
|
13
|
+
|
|
14
|
+
`tests/global-setup.ts` gives each test run its own temporary directory, removed afterwards, and skips CDK asset bundling (`aws:cdk:bundling-stacks: []`). To bundle assets in a single test, opt back in:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
const app = new App({
|
|
18
|
+
postCliContext: { 'aws:cdk:bundling-stacks': ['**'] },
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`synth` is the check that every vended asset exists, because it stages the real assets. Run `<%= pkgMgrCmd %> nx synth <%= fullyQualifiedName %>`.
|
|
23
|
+
|
|
12
24
|
### Updating snapshots
|
|
13
25
|
|
|
14
26
|
To update snapshots, run the following command:
|
|
@@ -6,6 +6,7 @@ import path from "path";
|
|
|
6
6
|
import tsProjectGenerator, { getTsLibDetails } from "../../ts/lib/generator.js";
|
|
7
7
|
import { mergeTsReferences } from "../../ts/lib/ts-project-utils.js";
|
|
8
8
|
import { addTsDependencies } from "../../utils/add-dependencies.js";
|
|
9
|
+
import { addCdkTestGlobalSetup } from "../../utils/cdk-test-setup.js";
|
|
9
10
|
import { resolveContainers } from "../../utils/containers.js";
|
|
10
11
|
import { declareDependencies, ownedElsewhere } from "../../utils/declared-dependencies.js";
|
|
11
12
|
import { formatFilesInSubtree } from "../../utils/format.js";
|
|
@@ -115,8 +116,11 @@ export async function tsInfraGenerator(tree, schema) {
|
|
|
115
116
|
const sandboxStagePattern = `"${namespace}-sandbox/**"`;
|
|
116
117
|
// `tsProjectGenerator` scaffolds a library `src`, which the CDK app layout
|
|
117
118
|
// replaces. Only on creation — on a re-run this is the user's infrastructure.
|
|
119
|
+
// Likewise its generic README, which would otherwise keep the infra README
|
|
120
|
+
// below from being written (it is generated `KeepExisting`).
|
|
118
121
|
if (isNewProject) {
|
|
119
122
|
tree.delete(joinPathFragments(libraryRoot, 'src'));
|
|
123
|
+
tree.delete(joinPathFragments(libraryRoot, 'README.md'));
|
|
120
124
|
}
|
|
121
125
|
// The guide walks through declaring resources in
|
|
122
126
|
// `src/stacks/application-stack.ts` and adding stages to `src/main.ts`, so
|
|
@@ -134,12 +138,16 @@ export async function tsInfraGenerator(tree, schema) {
|
|
|
134
138
|
}, {
|
|
135
139
|
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
136
140
|
});
|
|
141
|
+
await addCdkTestGlobalSetup(tree, libraryRoot);
|
|
137
142
|
updateJson(tree, `${libraryRoot}/project.json`, (config)=>{
|
|
138
143
|
config.projectType = 'application';
|
|
139
144
|
// `synth` is the CDK artifact, so it belongs on `assemble` too; `checkov`
|
|
140
145
|
// is a quality gate, so it stays on `build` alone.
|
|
141
146
|
addArtifactDependencyToTargets(config, 'synth');
|
|
142
147
|
addDependencyToTargetIfNotPresent(config, 'build', 'checkov');
|
|
148
|
+
// Infra tests read the deployed projects' artifacts, not their quality
|
|
149
|
+
// gates, so they replace the `^build` target default with `^assemble`.
|
|
150
|
+
addDependencyToTargetIfNotPresent(config, 'test', '^assemble');
|
|
143
151
|
config.targets.compile.outputs = [
|
|
144
152
|
'{workspaceRoot}/dist/{projectRoot}/tsc'
|
|
145
153
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/infra/app/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n readProjectConfiguration,\n type Tree,\n updateJson,\n} from '@nx/devkit';\nimport path from 'path';\nimport tsProjectGenerator, { getTsLibDetails } from '../../ts/lib/generator.js';\nimport { mergeTsReferences } from '../../ts/lib/ts-project-utils.js';\nimport { addTsDependencies } from '../../utils/add-dependencies.js';\nimport { resolveContainers } from '../../utils/containers.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../utils/declared-dependencies.js';\nimport { formatFilesInSubtree } from '../../utils/format.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { addLocalProjectDependency } from '../../utils/local-project-dependency.js';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics.js';\nimport { esmVars } from '../../utils/module-format.js';\nimport { kebabCase } from '../../utils/names.js';\nimport { getNpmScopePrefix } from '../../utils/npm-scope.js';\nimport {\n addArtifactDependencyToTargets,\n addDependencyToTargetIfNotPresent,\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n} from '../../utils/nx.js';\nimport { sortObjectKeys } from '../../utils/object.js';\nimport { getPackageManagerDisplayCommands } from '../../utils/pkg-manager.js';\nimport { uvxCommand } from '../../utils/py.js';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../../utils/shared-constructs.js';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_INFRA_CONFIG_DIR,\n} from '../../utils/shared-constructs-constants.js';\nimport { sharedInfraConfigGenerator } from '../../utils/shared-infra-config.js';\nimport {\n SHARED_INFRA_SCRIPTS_DEPENDENCIES,\n sharedInfraScriptsGenerator,\n} from '../../utils/shared-infra-scripts.js';\nimport type { TsInfraGeneratorSchema } from './schema';\n\n// This generator records no metadata, so nothing a predicate could read: the\n// CDK app always needs the app libraries, and the CLI, bundler and tsx are\n// shared tooling.\nexport const DEPENDENCIES = declareDependencies()({\n ts: [\n { name: 'aws-cdk-lib' },\n { name: 'constructs' },\n { name: 'source-map-support' },\n // The `aws-cdk` CLI, esbuild (CDK bundling) and tsx are shared tooling.\n { name: 'aws-cdk', dev: true, root: true },\n { name: 'esbuild', dev: true, root: true },\n { name: 'tsx', dev: true, root: true },\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ...ownedElsewhere(SHARED_INFRA_SCRIPTS_DEPENDENCIES),\n ],\n});\n\nexport const INFRA_APP_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport async function tsInfraGenerator(\n tree: Tree,\n schema: TsInfraGeneratorSchema,\n): Promise<GeneratorCallback> {\n const lib = getTsLibDetails(tree, schema);\n\n const isNewProject = !projectExists(tree, lib.fullyQualifiedName);\n if (isNewProject) {\n await tsProjectGenerator(tree, {\n ...schema,\n preferInstallDependencies: false,\n });\n }\n\n // CDK shells out to a container engine to build image assets. Default\n // (docker) needs no env override; finch is set via CDK_DOCKER per\n // https://docs.aws.amazon.com/cdk/v2/guide/build-containers.html#build-container-replace.\n const containers = await resolveContainers(tree, 'inherit');\n const cdkEnv: Record<string, string> | undefined =\n containers === 'docker' ? undefined : { CDK_DOCKER: containers };\n const withCdkEnv = <T extends Record<string, unknown>>(opts: T): T => {\n if (!cdkEnv) return opts;\n const existingEnv = (opts.env as Record<string, string> | undefined) ?? {};\n return { ...opts, env: { ...existingEnv, ...cdkEnv } } as T;\n };\n\n // This generator IS the CDK infrastructure project, so the provider is fixed.\n addGeneratorMetadata(tree, lib.fullyQualifiedName, INFRA_APP_GENERATOR_INFO, {\n iac: 'cdk',\n });\n\n // Shared constructs always in CDK for typescript infra generator\n await sharedConstructsGenerator(\n tree,\n {\n iac: 'cdk',\n },\n DEPENDENCIES,\n );\n\n // Shared infra-config and infra-scripts packages (lazy creation, only when enabled)\n const stageConfig = schema.stageConfig ?? false;\n if (stageConfig) {\n await sharedInfraConfigGenerator(tree);\n await sharedInfraScriptsGenerator(tree, DEPENDENCIES);\n }\n\n const synthDirFromRoot = `/dist/${lib.dir}/cdk.out`;\n const synthDirFromProject =\n lib.dir\n .split('/')\n .map(() => '..')\n .join('/') + `/dist/${lib.dir}/cdk.out`;\n const distDirFromProjectRoot =\n lib.dir\n .split('/')\n .map(() => '..')\n .join('/') + '/dist/{projectRoot}/cdk.out';\n const projectConfig = readProjectConfiguration(tree, lib.fullyQualifiedName);\n const libraryRoot = projectConfig.root;\n const npmScopePrefix = getNpmScopePrefix(tree);\n const scopeAlias = npmScopePrefix;\n const fullyQualifiedName = `${npmScopePrefix}${schema.name}`;\n const namespace = kebabCase(fullyQualifiedName);\n // The stage instantiated in main.ts. `**` so the pattern also selects stacks\n // nested below the stage's own stacks, such as the `us-east-1` WebACL stack a\n // website creates - `cdk destroy` only deletes the stacks its pattern selects,\n // so a single `*` leaves those behind. Quoted so the shell does not glob.\n const sandboxStagePattern = `\"${namespace}-sandbox/**\"`;\n\n // `tsProjectGenerator` scaffolds a library `src`, which the CDK app layout\n // replaces. Only on creation — on a re-run this is the user's infrastructure.\n if (isNewProject) {\n tree.delete(joinPathFragments(libraryRoot, 'src'));\n }\n\n // The guide walks through declaring resources in\n // `src/stacks/application-stack.ts` and adding stages to `src/main.ts`, so\n // everything here is scaffolded once and then left alone.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, './files/app'),\n libraryRoot,\n {\n synthDir: synthDirFromProject,\n scopeAlias: scopeAlias,\n namespace,\n fullyQualifiedName,\n pkgMgrCmd: getPackageManagerDisplayCommands().exec,\n dir: lib.dir,\n stageConfig,\n ...schema,\n ...esmVars(tree),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n updateJson(\n tree,\n `${libraryRoot}/project.json`,\n (config: ProjectConfiguration) => {\n config.projectType = 'application';\n // `synth` is the CDK artifact, so it belongs on `assemble` too; `checkov`\n // is a quality gate, so it stays on `build` alone.\n addArtifactDependencyToTargets(config, 'synth');\n addDependencyToTargetIfNotPresent(config, 'build', 'checkov');\n config.targets.compile.outputs = [\n '{workspaceRoot}/dist/{projectRoot}/tsc',\n ];\n config.targets.synth = {\n cache: true,\n executor: 'nx:run-commands',\n inputs: ['default'],\n outputs: ['{workspaceRoot}/dist/{projectRoot}/cdk.out'],\n dependsOn: ['^assemble', 'compile'], // compile clobbers dist directory, so ensure synth runs afterwards\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk synth',\n }),\n };\n // `default` rather than the synth directory: `dist` is gitignored, so a\n // fileset input pointed at it matches no tracked file and hashes to a\n // constant — the scan would cache-hit forever and pass on infrastructure\n // it never read. `default` carries the project's own sources plus the\n // transitive `dependentTasksOutputFiles` entry, which resolves against\n // the upstream `synth` task and so hashes the template actually scanned.\n config.targets.checkov = {\n cache: true,\n executor: 'nx:run-commands',\n inputs: ['default'],\n outputs: ['{workspaceRoot}/dist/{projectRoot}/checkov'],\n dependsOn: ['synth'],\n options: {\n command: uvxCommand(\n 'checkov',\n '--config-file {projectRoot}/checkov.yml --directory dist/{projectRoot}/cdk.out --framework cloudformation',\n ),\n },\n };\n config.targets.deploy = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n // No --express: this target deploys whichever stage is named, including\n // beta and prod, so it waits for full resource stabilization. Express\n // mode belongs to `deploy-sandbox`, which only ever deploys a sandbox.\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-deploy.ts ${libraryRoot}`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk deploy --require-approval=never',\n }),\n };\n config.targets['deploy-sandbox'] = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-deploy.ts ${libraryRoot} ${sandboxStagePattern} --express`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk deploy --require-approval=never ${sandboxStagePattern} --express`,\n }),\n };\n config.targets['deploy-ci'] = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk deploy --require-approval=never --app ${distDirFromProjectRoot}`,\n }),\n };\n config.targets.destroy = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-destroy.ts ${libraryRoot}`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk destroy',\n }),\n };\n config.targets['destroy-sandbox'] = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-destroy.ts ${libraryRoot} ${sandboxStagePattern}`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk destroy ${sandboxStagePattern}`,\n }),\n };\n config.targets['destroy-ci'] = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk destroy --app ${distDirFromProjectRoot}`,\n }),\n };\n config.targets.cdk = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk',\n }),\n };\n config.targets.bootstrap = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk bootstrap',\n }),\n };\n config.targets = sortObjectKeys(config.targets);\n return config;\n },\n );\n\n addTsDependencies(tree, DEPENDENCIES, { projectRoot: libraryRoot });\n\n updateJson(tree, `${libraryRoot}/tsconfig.lib.json`, (tsConfig) => ({\n ...tsConfig,\n references: mergeTsReferences(tsConfig.references, [\n {\n path: `${path.relative(\n libraryRoot,\n `${tree.root}/${PACKAGES_DIR}`,\n )}/${SHARED_CONSTRUCTS_DIR}/tsconfig.lib.json`,\n },\n ...(stageConfig\n ? [\n {\n path: `${path.relative(\n libraryRoot,\n `${tree.root}/${PACKAGES_DIR}`,\n )}/${SHARED_INFRA_CONFIG_DIR}/tsconfig.json`,\n },\n ]\n : []),\n ]),\n }));\n\n // `main.ts` and the application stack import the shared constructs.\n addLocalProjectDependency(tree, {\n consumerRoot: libraryRoot,\n dependencyRoot: joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR),\n });\n if (stageConfig) {\n addLocalProjectDependency(tree, {\n consumerRoot: libraryRoot,\n dependencyRoot: joinPathFragments(PACKAGES_DIR, SHARED_INFRA_CONFIG_DIR),\n });\n }\n\n await addGeneratorMetricsIfApplicable(tree, [INFRA_APP_GENERATOR_INFO]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, schema.preferInstallDependencies, {\n languages: ['typescript'],\n });\n}\nexport default tsInfraGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","readProjectConfiguration","updateJson","path","tsProjectGenerator","getTsLibDetails","mergeTsReferences","addTsDependencies","resolveContainers","declareDependencies","ownedElsewhere","formatFilesInSubtree","installDependencies","addLocalProjectDependency","addGeneratorMetricsIfApplicable","esmVars","kebabCase","getNpmScopePrefix","addArtifactDependencyToTargets","addDependencyToTargetIfNotPresent","addGeneratorMetadata","getGeneratorInfo","projectExists","sortObjectKeys","getPackageManagerDisplayCommands","uvxCommand","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_INFRA_CONFIG_DIR","sharedInfraConfigGenerator","SHARED_INFRA_SCRIPTS_DEPENDENCIES","sharedInfraScriptsGenerator","DEPENDENCIES","ts","name","dev","root","INFRA_APP_GENERATOR_INFO","filename","tsInfraGenerator","tree","schema","lib","isNewProject","fullyQualifiedName","preferInstallDependencies","containers","cdkEnv","undefined","CDK_DOCKER","withCdkEnv","opts","existingEnv","env","iac","stageConfig","synthDirFromRoot","dir","synthDirFromProject","split","map","join","distDirFromProjectRoot","projectConfig","libraryRoot","npmScopePrefix","scopeAlias","namespace","sandboxStagePattern","delete","dirname","synthDir","pkgMgrCmd","exec","overwriteStrategy","KeepExisting","config","projectType","targets","compile","outputs","synth","cache","executor","inputs","dependsOn","options","cwd","command","checkov","deploy","destroy","cdk","bootstrap","projectRoot","tsConfig","references","relative","consumerRoot","dependencyRoot","languages"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/infra/app/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n readProjectConfiguration,\n type Tree,\n updateJson,\n} from '@nx/devkit';\nimport path from 'path';\nimport tsProjectGenerator, { getTsLibDetails } from '../../ts/lib/generator.js';\nimport { mergeTsReferences } from '../../ts/lib/ts-project-utils.js';\nimport { addTsDependencies } from '../../utils/add-dependencies.js';\nimport { addCdkTestGlobalSetup } from '../../utils/cdk-test-setup.js';\nimport { resolveContainers } from '../../utils/containers.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../utils/declared-dependencies.js';\nimport { formatFilesInSubtree } from '../../utils/format.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { addLocalProjectDependency } from '../../utils/local-project-dependency.js';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics.js';\nimport { esmVars } from '../../utils/module-format.js';\nimport { kebabCase } from '../../utils/names.js';\nimport { getNpmScopePrefix } from '../../utils/npm-scope.js';\nimport {\n addArtifactDependencyToTargets,\n addDependencyToTargetIfNotPresent,\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n} from '../../utils/nx.js';\nimport { sortObjectKeys } from '../../utils/object.js';\nimport { getPackageManagerDisplayCommands } from '../../utils/pkg-manager.js';\nimport { uvxCommand } from '../../utils/py.js';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../../utils/shared-constructs.js';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_INFRA_CONFIG_DIR,\n} from '../../utils/shared-constructs-constants.js';\nimport { sharedInfraConfigGenerator } from '../../utils/shared-infra-config.js';\nimport {\n SHARED_INFRA_SCRIPTS_DEPENDENCIES,\n sharedInfraScriptsGenerator,\n} from '../../utils/shared-infra-scripts.js';\nimport type { TsInfraGeneratorSchema } from './schema';\n\n// This generator records no metadata, so nothing a predicate could read: the\n// CDK app always needs the app libraries, and the CLI, bundler and tsx are\n// shared tooling.\nexport const DEPENDENCIES = declareDependencies()({\n ts: [\n { name: 'aws-cdk-lib' },\n { name: 'constructs' },\n { name: 'source-map-support' },\n // The `aws-cdk` CLI, esbuild (CDK bundling) and tsx are shared tooling.\n { name: 'aws-cdk', dev: true, root: true },\n { name: 'esbuild', dev: true, root: true },\n { name: 'tsx', dev: true, root: true },\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ...ownedElsewhere(SHARED_INFRA_SCRIPTS_DEPENDENCIES),\n ],\n});\n\nexport const INFRA_APP_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport async function tsInfraGenerator(\n tree: Tree,\n schema: TsInfraGeneratorSchema,\n): Promise<GeneratorCallback> {\n const lib = getTsLibDetails(tree, schema);\n\n const isNewProject = !projectExists(tree, lib.fullyQualifiedName);\n if (isNewProject) {\n await tsProjectGenerator(tree, {\n ...schema,\n preferInstallDependencies: false,\n });\n }\n\n // CDK shells out to a container engine to build image assets. Default\n // (docker) needs no env override; finch is set via CDK_DOCKER per\n // https://docs.aws.amazon.com/cdk/v2/guide/build-containers.html#build-container-replace.\n const containers = await resolveContainers(tree, 'inherit');\n const cdkEnv: Record<string, string> | undefined =\n containers === 'docker' ? undefined : { CDK_DOCKER: containers };\n const withCdkEnv = <T extends Record<string, unknown>>(opts: T): T => {\n if (!cdkEnv) return opts;\n const existingEnv = (opts.env as Record<string, string> | undefined) ?? {};\n return { ...opts, env: { ...existingEnv, ...cdkEnv } } as T;\n };\n\n // This generator IS the CDK infrastructure project, so the provider is fixed.\n addGeneratorMetadata(tree, lib.fullyQualifiedName, INFRA_APP_GENERATOR_INFO, {\n iac: 'cdk',\n });\n\n // Shared constructs always in CDK for typescript infra generator\n await sharedConstructsGenerator(\n tree,\n {\n iac: 'cdk',\n },\n DEPENDENCIES,\n );\n\n // Shared infra-config and infra-scripts packages (lazy creation, only when enabled)\n const stageConfig = schema.stageConfig ?? false;\n if (stageConfig) {\n await sharedInfraConfigGenerator(tree);\n await sharedInfraScriptsGenerator(tree, DEPENDENCIES);\n }\n\n const synthDirFromRoot = `/dist/${lib.dir}/cdk.out`;\n const synthDirFromProject =\n lib.dir\n .split('/')\n .map(() => '..')\n .join('/') + `/dist/${lib.dir}/cdk.out`;\n const distDirFromProjectRoot =\n lib.dir\n .split('/')\n .map(() => '..')\n .join('/') + '/dist/{projectRoot}/cdk.out';\n const projectConfig = readProjectConfiguration(tree, lib.fullyQualifiedName);\n const libraryRoot = projectConfig.root;\n const npmScopePrefix = getNpmScopePrefix(tree);\n const scopeAlias = npmScopePrefix;\n const fullyQualifiedName = `${npmScopePrefix}${schema.name}`;\n const namespace = kebabCase(fullyQualifiedName);\n // The stage instantiated in main.ts. `**` so the pattern also selects stacks\n // nested below the stage's own stacks, such as the `us-east-1` WebACL stack a\n // website creates - `cdk destroy` only deletes the stacks its pattern selects,\n // so a single `*` leaves those behind. Quoted so the shell does not glob.\n const sandboxStagePattern = `\"${namespace}-sandbox/**\"`;\n\n // `tsProjectGenerator` scaffolds a library `src`, which the CDK app layout\n // replaces. Only on creation — on a re-run this is the user's infrastructure.\n // Likewise its generic README, which would otherwise keep the infra README\n // below from being written (it is generated `KeepExisting`).\n if (isNewProject) {\n tree.delete(joinPathFragments(libraryRoot, 'src'));\n tree.delete(joinPathFragments(libraryRoot, 'README.md'));\n }\n\n // The guide walks through declaring resources in\n // `src/stacks/application-stack.ts` and adding stages to `src/main.ts`, so\n // everything here is scaffolded once and then left alone.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, './files/app'),\n libraryRoot,\n {\n synthDir: synthDirFromProject,\n scopeAlias: scopeAlias,\n namespace,\n fullyQualifiedName,\n pkgMgrCmd: getPackageManagerDisplayCommands().exec,\n dir: lib.dir,\n stageConfig,\n ...schema,\n ...esmVars(tree),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n await addCdkTestGlobalSetup(tree, libraryRoot);\n\n updateJson(\n tree,\n `${libraryRoot}/project.json`,\n (config: ProjectConfiguration) => {\n config.projectType = 'application';\n // `synth` is the CDK artifact, so it belongs on `assemble` too; `checkov`\n // is a quality gate, so it stays on `build` alone.\n addArtifactDependencyToTargets(config, 'synth');\n addDependencyToTargetIfNotPresent(config, 'build', 'checkov');\n // Infra tests read the deployed projects' artifacts, not their quality\n // gates, so they replace the `^build` target default with `^assemble`.\n addDependencyToTargetIfNotPresent(config, 'test', '^assemble');\n config.targets.compile.outputs = [\n '{workspaceRoot}/dist/{projectRoot}/tsc',\n ];\n config.targets.synth = {\n cache: true,\n executor: 'nx:run-commands',\n inputs: ['default'],\n outputs: ['{workspaceRoot}/dist/{projectRoot}/cdk.out'],\n dependsOn: ['^assemble', 'compile'], // compile clobbers dist directory, so ensure synth runs afterwards\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk synth',\n }),\n };\n // `default` rather than the synth directory: `dist` is gitignored, so a\n // fileset input pointed at it matches no tracked file and hashes to a\n // constant — the scan would cache-hit forever and pass on infrastructure\n // it never read. `default` carries the project's own sources plus the\n // transitive `dependentTasksOutputFiles` entry, which resolves against\n // the upstream `synth` task and so hashes the template actually scanned.\n config.targets.checkov = {\n cache: true,\n executor: 'nx:run-commands',\n inputs: ['default'],\n outputs: ['{workspaceRoot}/dist/{projectRoot}/checkov'],\n dependsOn: ['synth'],\n options: {\n command: uvxCommand(\n 'checkov',\n '--config-file {projectRoot}/checkov.yml --directory dist/{projectRoot}/cdk.out --framework cloudformation',\n ),\n },\n };\n config.targets.deploy = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n // No --express: this target deploys whichever stage is named, including\n // beta and prod, so it waits for full resource stabilization. Express\n // mode belongs to `deploy-sandbox`, which only ever deploys a sandbox.\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-deploy.ts ${libraryRoot}`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk deploy --require-approval=never',\n }),\n };\n config.targets['deploy-sandbox'] = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-deploy.ts ${libraryRoot} ${sandboxStagePattern} --express`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk deploy --require-approval=never ${sandboxStagePattern} --express`,\n }),\n };\n config.targets['deploy-ci'] = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk deploy --require-approval=never --app ${distDirFromProjectRoot}`,\n }),\n };\n config.targets.destroy = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-destroy.ts ${libraryRoot}`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk destroy',\n }),\n };\n config.targets['destroy-sandbox'] = {\n executor: 'nx:run-commands',\n dependsOn: ['^assemble', 'compile'],\n options: stageConfig\n ? withCdkEnv({\n command: `tsx packages/common/scripts/src/infra/infra-destroy.ts ${libraryRoot} ${sandboxStagePattern}`,\n })\n : withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk destroy ${sandboxStagePattern}`,\n }),\n };\n config.targets['destroy-ci'] = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: `cdk destroy --app ${distDirFromProjectRoot}`,\n }),\n };\n config.targets.cdk = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk',\n }),\n };\n config.targets.bootstrap = {\n executor: 'nx:run-commands',\n options: withCdkEnv({\n cwd: '{projectRoot}',\n command: 'cdk bootstrap',\n }),\n };\n config.targets = sortObjectKeys(config.targets);\n return config;\n },\n );\n\n addTsDependencies(tree, DEPENDENCIES, { projectRoot: libraryRoot });\n\n updateJson(tree, `${libraryRoot}/tsconfig.lib.json`, (tsConfig) => ({\n ...tsConfig,\n references: mergeTsReferences(tsConfig.references, [\n {\n path: `${path.relative(\n libraryRoot,\n `${tree.root}/${PACKAGES_DIR}`,\n )}/${SHARED_CONSTRUCTS_DIR}/tsconfig.lib.json`,\n },\n ...(stageConfig\n ? [\n {\n path: `${path.relative(\n libraryRoot,\n `${tree.root}/${PACKAGES_DIR}`,\n )}/${SHARED_INFRA_CONFIG_DIR}/tsconfig.json`,\n },\n ]\n : []),\n ]),\n }));\n\n // `main.ts` and the application stack import the shared constructs.\n addLocalProjectDependency(tree, {\n consumerRoot: libraryRoot,\n dependencyRoot: joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR),\n });\n if (stageConfig) {\n addLocalProjectDependency(tree, {\n consumerRoot: libraryRoot,\n dependencyRoot: joinPathFragments(PACKAGES_DIR, SHARED_INFRA_CONFIG_DIR),\n });\n }\n\n await addGeneratorMetricsIfApplicable(tree, [INFRA_APP_GENERATOR_INFO]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, schema.preferInstallDependencies, {\n languages: ['typescript'],\n });\n}\nexport default tsInfraGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","readProjectConfiguration","updateJson","path","tsProjectGenerator","getTsLibDetails","mergeTsReferences","addTsDependencies","addCdkTestGlobalSetup","resolveContainers","declareDependencies","ownedElsewhere","formatFilesInSubtree","installDependencies","addLocalProjectDependency","addGeneratorMetricsIfApplicable","esmVars","kebabCase","getNpmScopePrefix","addArtifactDependencyToTargets","addDependencyToTargetIfNotPresent","addGeneratorMetadata","getGeneratorInfo","projectExists","sortObjectKeys","getPackageManagerDisplayCommands","uvxCommand","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_INFRA_CONFIG_DIR","sharedInfraConfigGenerator","SHARED_INFRA_SCRIPTS_DEPENDENCIES","sharedInfraScriptsGenerator","DEPENDENCIES","ts","name","dev","root","INFRA_APP_GENERATOR_INFO","filename","tsInfraGenerator","tree","schema","lib","isNewProject","fullyQualifiedName","preferInstallDependencies","containers","cdkEnv","undefined","CDK_DOCKER","withCdkEnv","opts","existingEnv","env","iac","stageConfig","synthDirFromRoot","dir","synthDirFromProject","split","map","join","distDirFromProjectRoot","projectConfig","libraryRoot","npmScopePrefix","scopeAlias","namespace","sandboxStagePattern","delete","dirname","synthDir","pkgMgrCmd","exec","overwriteStrategy","KeepExisting","config","projectType","targets","compile","outputs","synth","cache","executor","inputs","dependsOn","options","cwd","command","checkov","deploy","destroy","cdk","bootstrap","projectRoot","tsConfig","references","relative","consumerRoot","dependencyRoot","languages"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type MigrationReturnObject, type Tree } from '@nx/devkit';
|
|
6
|
+
export default function migration(tree: Tree): Promise<MigrationReturnObject>;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { getProjects, readNxJson, updateNxJson, updateProjectConfiguration } from "@nx/devkit";
|
|
5
|
+
import { SMITHY_PROJECT_GENERATOR_INFO, SMITHY_TARGET_INPUTS } from "../../../smithy/project/generator.js";
|
|
6
|
+
import { TERRAFORM_PROJECT_GENERATOR_INFO } from "../../../terraform/project/generator.js";
|
|
7
|
+
import { DEPENDENT_TASKS_OUTPUT_FILES_INPUT, VENDED_DEPENDENT_TASKS_OUTPUT_GLOBS } from "../../../ts/lib/generator.js";
|
|
8
|
+
import { TS_RDB_GENERATOR_INFO } from "../../../ts/rdb/generator.js";
|
|
9
|
+
import { formatFilesInSubtree } from "../../../utils/format.js";
|
|
10
|
+
/**
|
|
11
|
+
* Fix what four generated targets hash, so cached results follow what each
|
|
12
|
+
* task actually reads:
|
|
13
|
+
*
|
|
14
|
+
* - `nx.json`'s `default` input no longer hashes checkov reports
|
|
15
|
+
* (`dist/<project>/checkov/checkov_report.json`, CDK and Terraform) or vitest
|
|
16
|
+
* coverage (`dist/<project>/test-output/vitest/coverage/`) from upstream
|
|
17
|
+
* tasks. Nothing downstream reads them, and an uncached scan or coverage run
|
|
18
|
+
* rewrites them, which missed every dependent task.
|
|
19
|
+
* - A Smithy project's `compile` and `generate-ssdk` declare `["default"]`,
|
|
20
|
+
* their own sources plus the outputs of the tasks they depend on, rather
|
|
21
|
+
* than relying on whatever target default applies. That hashes a consumed
|
|
22
|
+
* shape library's output only in a workspace where nx.json's `default`
|
|
23
|
+
* carries the `dependentTasksOutputFiles` entry, which only
|
|
24
|
+
* ts/lib/generator.ts writes.
|
|
25
|
+
* - A ts#rdb project's `generate` (`prisma generate`) is cached on
|
|
26
|
+
* `["default"]`, which covers the Prisma schema and config. The Prisma
|
|
27
|
+
* version is hashed through the lockfile.
|
|
28
|
+
* - A Terraform project's `output` is no longer cached: it reads remote state,
|
|
29
|
+
* which no input can hash, so a hit could replay values from before an apply.
|
|
30
|
+
*
|
|
31
|
+
* Each edit uses the generator's own constants, so a migrated workspace is
|
|
32
|
+
* byte-identical to a freshly generated one, keys in the same order. A target
|
|
33
|
+
* or glob that has diverged from the generated shape is left untouched and
|
|
34
|
+
* reported.
|
|
35
|
+
*
|
|
36
|
+
* Changing `namedInputs.default` changes every task hash, so the first build
|
|
37
|
+
* after migrating misses the cache throughout. Removing a churning input can
|
|
38
|
+
* also let a target that reads a file it does not declare replay a stale
|
|
39
|
+
* result, so that risk is reported whenever the glob is rewritten.
|
|
40
|
+
*/ const CURRENT_GLOB = DEPENDENT_TASKS_OUTPUT_FILES_INPUT.dependentTasksOutputFiles;
|
|
41
|
+
const STALE_PASS_ADVISORY = "nx.json's 'default' input no longer hashes checkov reports or vitest coverage from upstream tasks. A target that reads a file it does not declare as an input (for example a test reading README.md) can now replay a cached result after that file changes; add such files to the target's inputs.";
|
|
42
|
+
const SMITHY_TARGETS = [
|
|
43
|
+
'compile',
|
|
44
|
+
'generate-ssdk'
|
|
45
|
+
];
|
|
46
|
+
const RDB_INPUTS = [
|
|
47
|
+
'default'
|
|
48
|
+
];
|
|
49
|
+
const PRE_FIX_TERRAFORM_OUTPUT_INPUTS = [
|
|
50
|
+
'default'
|
|
51
|
+
];
|
|
52
|
+
const sameInputs = (inputs, expected)=>Array.isArray(inputs) && inputs.length === expected.length && inputs.every((input, index)=>input === expected[index]);
|
|
53
|
+
const command = (target)=>target.options?.command;
|
|
54
|
+
/** Rewrites a previously vended glob; returns whether it did. */ const migrateGlob = (tree, nextSteps)=>{
|
|
55
|
+
const nxJson = readNxJson(tree);
|
|
56
|
+
const defaultInputs = nxJson?.namedInputs?.default;
|
|
57
|
+
if (!nxJson || !Array.isArray(defaultInputs)) return false;
|
|
58
|
+
// A dependentTasksOutputFiles entry is "vended" if it is already current or
|
|
59
|
+
// is one of the globs this plugin has shipped (and so would be rewritten to
|
|
60
|
+
// the current one below). An extra entry a user added beside it - neither
|
|
61
|
+
// current nor vended - is their own scoping decision and is reported only
|
|
62
|
+
// when no vended-or-current entry exists; otherwise it would be reported on
|
|
63
|
+
// every run with advice that could widen hashing.
|
|
64
|
+
const hasVendedOrCurrentEntry = defaultInputs.some((input)=>typeof input === 'object' && input !== null && 'dependentTasksOutputFiles' in input && (input.dependentTasksOutputFiles === CURRENT_GLOB || input.transitive && VENDED_DEPENDENT_TASKS_OUTPUT_GLOBS.includes(input.dependentTasksOutputFiles)));
|
|
65
|
+
let rewrote = false;
|
|
66
|
+
nxJson.namedInputs.default = defaultInputs.map((input)=>{
|
|
67
|
+
if (typeof input !== 'object' || !('dependentTasksOutputFiles' in input)) {
|
|
68
|
+
return input;
|
|
69
|
+
}
|
|
70
|
+
const glob = input.dependentTasksOutputFiles;
|
|
71
|
+
if (glob === CURRENT_GLOB) return input;
|
|
72
|
+
if (input.transitive && VENDED_DEPENDENT_TASKS_OUTPUT_GLOBS.includes(glob)) {
|
|
73
|
+
rewrote = true;
|
|
74
|
+
return {
|
|
75
|
+
...input,
|
|
76
|
+
dependentTasksOutputFiles: CURRENT_GLOB
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (!hasVendedOrCurrentEntry) {
|
|
80
|
+
nextSteps.push(`nx.json: the 'default' input's dependentTasksOutputFiles '${glob}' has diverged from the generated shape - left untouched. Consider excluding checkov reports and vitest coverage ('${CURRENT_GLOB}'), which otherwise miss every dependent task whenever a scan or coverage run rewrites them.`);
|
|
81
|
+
}
|
|
82
|
+
return input;
|
|
83
|
+
});
|
|
84
|
+
if (rewrote) updateNxJson(tree, nxJson);
|
|
85
|
+
return rewrote;
|
|
86
|
+
};
|
|
87
|
+
const diverged = (projectName, targetName, advice)=>`${projectName}:${targetName}: has diverged from the generated shape - left untouched. ${advice}`;
|
|
88
|
+
/** Inserts `inputs` after `cache`, where the generator writes it. */ const migrateSmithyTarget = (projectName, targetName, target, nextSteps)=>{
|
|
89
|
+
if (sameInputs(target.inputs, SMITHY_TARGET_INPUTS)) return undefined;
|
|
90
|
+
if (target.inputs !== undefined || target.executor !== 'nx:run-commands') {
|
|
91
|
+
nextSteps.push(diverged(projectName, targetName, "Confirm its inputs cover the Smithy sources and the outputs of the tasks it depends on, as ['default'] does."));
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
const { cache, ...rest } = target;
|
|
95
|
+
return {
|
|
96
|
+
cache,
|
|
97
|
+
inputs: [
|
|
98
|
+
...SMITHY_TARGET_INPUTS
|
|
99
|
+
],
|
|
100
|
+
...rest
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
/** Inserts `cache` and `inputs` after `executor`, where the generator writes them. */ const migrateRdbGenerate = (projectName, target, nextSteps)=>{
|
|
104
|
+
if (target.cache === true && sameInputs(target.inputs, RDB_INPUTS)) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
if (target.executor !== 'nx:run-commands' || command(target) !== 'prisma generate' || target.cache !== undefined || target.inputs !== undefined) {
|
|
108
|
+
nextSteps.push(diverged(projectName, 'generate', "To cache Prisma client generation, set cache: true and inputs: ['default'], which covers the Prisma schema and config."));
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
const { executor, ...rest } = target;
|
|
112
|
+
return {
|
|
113
|
+
executor,
|
|
114
|
+
cache: true,
|
|
115
|
+
inputs: [
|
|
116
|
+
...RDB_INPUTS
|
|
117
|
+
],
|
|
118
|
+
...rest
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
/** Stops caching `output` in place and drops its inputs. */ const migrateTerraformOutput = (projectName, target, nextSteps)=>{
|
|
122
|
+
if (target.cache !== true) return undefined;
|
|
123
|
+
if (!sameInputs(target.inputs, PRE_FIX_TERRAFORM_OUTPUT_INPUTS) || command(target) !== 'terraform output -json') {
|
|
124
|
+
nextSteps.push(diverged(projectName, 'output', 'A cached output can replay stale values after an apply; set cache: false.'));
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
const { inputs: _inputs, ...rest } = target;
|
|
128
|
+
return {
|
|
129
|
+
...rest,
|
|
130
|
+
cache: false
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
const migrateProject = (projectName, project, nextSteps)=>{
|
|
134
|
+
const generator = project.metadata?.generator;
|
|
135
|
+
const targets = project.targets ?? {};
|
|
136
|
+
const migrations = generator === SMITHY_PROJECT_GENERATOR_INFO.id ? SMITHY_TARGETS.map((name)=>[
|
|
137
|
+
name,
|
|
138
|
+
()=>migrateSmithyTarget(projectName, name, targets[name], nextSteps)
|
|
139
|
+
]) : generator === TS_RDB_GENERATOR_INFO.id ? [
|
|
140
|
+
[
|
|
141
|
+
'generate',
|
|
142
|
+
()=>migrateRdbGenerate(projectName, targets.generate, nextSteps)
|
|
143
|
+
]
|
|
144
|
+
] : generator === TERRAFORM_PROJECT_GENERATOR_INFO.id ? [
|
|
145
|
+
[
|
|
146
|
+
'output',
|
|
147
|
+
()=>migrateTerraformOutput(projectName, targets.output, nextSteps)
|
|
148
|
+
]
|
|
149
|
+
] : [];
|
|
150
|
+
let changed = false;
|
|
151
|
+
for (const [name, migrate] of migrations){
|
|
152
|
+
if (!targets[name]) continue;
|
|
153
|
+
const migrated = migrate();
|
|
154
|
+
if (migrated) {
|
|
155
|
+
targets[name] = migrated;
|
|
156
|
+
changed = true;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return changed;
|
|
160
|
+
};
|
|
161
|
+
export default async function migration(tree) {
|
|
162
|
+
const nextSteps = [];
|
|
163
|
+
const rewroteGlob = migrateGlob(tree, nextSteps);
|
|
164
|
+
for (const [projectName, project] of getProjects(tree)){
|
|
165
|
+
if (migrateProject(projectName, project, nextSteps)) {
|
|
166
|
+
updateProjectConfiguration(tree, projectName, project);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (rewroteGlob) nextSteps.push(STALE_PASS_ADVISORY);
|
|
170
|
+
await formatFilesInSubtree(tree);
|
|
171
|
+
return {
|
|
172
|
+
nextSteps
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
//# sourceMappingURL=migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/cache-inputs-outputs/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n type MigrationReturnObject,\n type ProjectConfiguration,\n readNxJson,\n type TargetConfiguration,\n type Tree,\n updateNxJson,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport {\n SMITHY_PROJECT_GENERATOR_INFO,\n SMITHY_TARGET_INPUTS,\n} from '../../../smithy/project/generator.js';\nimport { TERRAFORM_PROJECT_GENERATOR_INFO } from '../../../terraform/project/generator.js';\nimport {\n DEPENDENT_TASKS_OUTPUT_FILES_INPUT,\n VENDED_DEPENDENT_TASKS_OUTPUT_GLOBS,\n} from '../../../ts/lib/generator.js';\nimport { TS_RDB_GENERATOR_INFO } from '../../../ts/rdb/generator.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\n\n/**\n * Fix what four generated targets hash, so cached results follow what each\n * task actually reads:\n *\n * - `nx.json`'s `default` input no longer hashes checkov reports\n * (`dist/<project>/checkov/checkov_report.json`, CDK and Terraform) or vitest\n * coverage (`dist/<project>/test-output/vitest/coverage/`) from upstream\n * tasks. Nothing downstream reads them, and an uncached scan or coverage run\n * rewrites them, which missed every dependent task.\n * - A Smithy project's `compile` and `generate-ssdk` declare `[\"default\"]`,\n * their own sources plus the outputs of the tasks they depend on, rather\n * than relying on whatever target default applies. That hashes a consumed\n * shape library's output only in a workspace where nx.json's `default`\n * carries the `dependentTasksOutputFiles` entry, which only\n * ts/lib/generator.ts writes.\n * - A ts#rdb project's `generate` (`prisma generate`) is cached on\n * `[\"default\"]`, which covers the Prisma schema and config. The Prisma\n * version is hashed through the lockfile.\n * - A Terraform project's `output` is no longer cached: it reads remote state,\n * which no input can hash, so a hit could replay values from before an apply.\n *\n * Each edit uses the generator's own constants, so a migrated workspace is\n * byte-identical to a freshly generated one, keys in the same order. A target\n * or glob that has diverged from the generated shape is left untouched and\n * reported.\n *\n * Changing `namedInputs.default` changes every task hash, so the first build\n * after migrating misses the cache throughout. Removing a churning input can\n * also let a target that reads a file it does not declare replay a stale\n * result, so that risk is reported whenever the glob is rewritten.\n */\n\nconst CURRENT_GLOB =\n DEPENDENT_TASKS_OUTPUT_FILES_INPUT.dependentTasksOutputFiles;\n\nconst STALE_PASS_ADVISORY =\n \"nx.json's 'default' input no longer hashes checkov reports or vitest coverage from upstream tasks. A target that reads a file it does not declare as an input (for example a test reading README.md) can now replay a cached result after that file changes; add such files to the target's inputs.\";\n\nconst SMITHY_TARGETS = ['compile', 'generate-ssdk'];\nconst RDB_INPUTS = ['default'];\nconst PRE_FIX_TERRAFORM_OUTPUT_INPUTS = ['default'];\n\nconst sameInputs = (\n inputs: TargetConfiguration['inputs'],\n expected: string[],\n): boolean =>\n Array.isArray(inputs) &&\n inputs.length === expected.length &&\n inputs.every((input, index) => input === expected[index]);\n\nconst command = (target: TargetConfiguration): unknown =>\n target.options?.command;\n\n/** Rewrites a previously vended glob; returns whether it did. */\nconst migrateGlob = (tree: Tree, nextSteps: string[]): boolean => {\n const nxJson = readNxJson(tree);\n const defaultInputs = nxJson?.namedInputs?.default;\n if (!nxJson || !Array.isArray(defaultInputs)) return false;\n\n // A dependentTasksOutputFiles entry is \"vended\" if it is already current or\n // is one of the globs this plugin has shipped (and so would be rewritten to\n // the current one below). An extra entry a user added beside it - neither\n // current nor vended - is their own scoping decision and is reported only\n // when no vended-or-current entry exists; otherwise it would be reported on\n // every run with advice that could widen hashing.\n const hasVendedOrCurrentEntry = defaultInputs.some(\n (input) =>\n typeof input === 'object' &&\n input !== null &&\n 'dependentTasksOutputFiles' in input &&\n (input.dependentTasksOutputFiles === CURRENT_GLOB ||\n (input.transitive &&\n VENDED_DEPENDENT_TASKS_OUTPUT_GLOBS.includes(\n input.dependentTasksOutputFiles,\n ))),\n );\n\n let rewrote = false;\n nxJson.namedInputs.default = defaultInputs.map((input) => {\n if (typeof input !== 'object' || !('dependentTasksOutputFiles' in input)) {\n return input;\n }\n const glob = input.dependentTasksOutputFiles;\n if (glob === CURRENT_GLOB) return input;\n if (\n input.transitive &&\n VENDED_DEPENDENT_TASKS_OUTPUT_GLOBS.includes(glob)\n ) {\n rewrote = true;\n return { ...input, dependentTasksOutputFiles: CURRENT_GLOB };\n }\n if (!hasVendedOrCurrentEntry) {\n nextSteps.push(\n `nx.json: the 'default' input's dependentTasksOutputFiles '${glob}' has diverged from the generated shape - left untouched. Consider excluding checkov reports and vitest coverage ('${CURRENT_GLOB}'), which otherwise miss every dependent task whenever a scan or coverage run rewrites them.`,\n );\n }\n return input;\n });\n\n if (rewrote) updateNxJson(tree, nxJson);\n return rewrote;\n};\n\nconst diverged = (projectName: string, targetName: string, advice: string) =>\n `${projectName}:${targetName}: has diverged from the generated shape - left untouched. ${advice}`;\n\n/** Inserts `inputs` after `cache`, where the generator writes it. */\nconst migrateSmithyTarget = (\n projectName: string,\n targetName: string,\n target: TargetConfiguration,\n nextSteps: string[],\n): TargetConfiguration | undefined => {\n if (sameInputs(target.inputs, SMITHY_TARGET_INPUTS)) return undefined;\n if (target.inputs !== undefined || target.executor !== 'nx:run-commands') {\n nextSteps.push(\n diverged(\n projectName,\n targetName,\n \"Confirm its inputs cover the Smithy sources and the outputs of the tasks it depends on, as ['default'] does.\",\n ),\n );\n return undefined;\n }\n const { cache, ...rest } = target;\n return { cache, inputs: [...SMITHY_TARGET_INPUTS], ...rest };\n};\n\n/** Inserts `cache` and `inputs` after `executor`, where the generator writes them. */\nconst migrateRdbGenerate = (\n projectName: string,\n target: TargetConfiguration,\n nextSteps: string[],\n): TargetConfiguration | undefined => {\n if (target.cache === true && sameInputs(target.inputs, RDB_INPUTS)) {\n return undefined;\n }\n if (\n target.executor !== 'nx:run-commands' ||\n command(target) !== 'prisma generate' ||\n target.cache !== undefined ||\n target.inputs !== undefined\n ) {\n nextSteps.push(\n diverged(\n projectName,\n 'generate',\n \"To cache Prisma client generation, set cache: true and inputs: ['default'], which covers the Prisma schema and config.\",\n ),\n );\n return undefined;\n }\n const { executor, ...rest } = target;\n return { executor, cache: true, inputs: [...RDB_INPUTS], ...rest };\n};\n\n/** Stops caching `output` in place and drops its inputs. */\nconst migrateTerraformOutput = (\n projectName: string,\n target: TargetConfiguration,\n nextSteps: string[],\n): TargetConfiguration | undefined => {\n if (target.cache !== true) return undefined;\n if (\n !sameInputs(target.inputs, PRE_FIX_TERRAFORM_OUTPUT_INPUTS) ||\n command(target) !== 'terraform output -json'\n ) {\n nextSteps.push(\n diverged(\n projectName,\n 'output',\n 'A cached output can replay stale values after an apply; set cache: false.',\n ),\n );\n return undefined;\n }\n const { inputs: _inputs, ...rest } = target;\n return { ...rest, cache: false };\n};\n\nconst migrateProject = (\n projectName: string,\n project: ProjectConfiguration,\n nextSteps: string[],\n): boolean => {\n const generator = (project.metadata as { generator?: string } | undefined)\n ?.generator;\n const targets = project.targets ?? {};\n\n const migrations: [string, () => TargetConfiguration | undefined][] =\n generator === SMITHY_PROJECT_GENERATOR_INFO.id\n ? SMITHY_TARGETS.map((name) => [\n name,\n () =>\n migrateSmithyTarget(projectName, name, targets[name], nextSteps),\n ])\n : generator === TS_RDB_GENERATOR_INFO.id\n ? [\n [\n 'generate',\n () =>\n migrateRdbGenerate(projectName, targets.generate, nextSteps),\n ],\n ]\n : generator === TERRAFORM_PROJECT_GENERATOR_INFO.id\n ? [\n [\n 'output',\n () =>\n migrateTerraformOutput(\n projectName,\n targets.output,\n nextSteps,\n ),\n ],\n ]\n : [];\n\n let changed = false;\n for (const [name, migrate] of migrations) {\n if (!targets[name]) continue;\n const migrated = migrate();\n if (migrated) {\n targets[name] = migrated;\n changed = true;\n }\n }\n return changed;\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n const rewroteGlob = migrateGlob(tree, nextSteps);\n\n for (const [projectName, project] of getProjects(tree)) {\n if (migrateProject(projectName, project, nextSteps)) {\n updateProjectConfiguration(tree, projectName, project);\n }\n }\n\n if (rewroteGlob) nextSteps.push(STALE_PASS_ADVISORY);\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["getProjects","readNxJson","updateNxJson","updateProjectConfiguration","SMITHY_PROJECT_GENERATOR_INFO","SMITHY_TARGET_INPUTS","TERRAFORM_PROJECT_GENERATOR_INFO","DEPENDENT_TASKS_OUTPUT_FILES_INPUT","VENDED_DEPENDENT_TASKS_OUTPUT_GLOBS","TS_RDB_GENERATOR_INFO","formatFilesInSubtree","CURRENT_GLOB","dependentTasksOutputFiles","STALE_PASS_ADVISORY","SMITHY_TARGETS","RDB_INPUTS","PRE_FIX_TERRAFORM_OUTPUT_INPUTS","sameInputs","inputs","expected","Array","isArray","length","every","input","index","command","target","options","migrateGlob","tree","nextSteps","nxJson","defaultInputs","namedInputs","default","hasVendedOrCurrentEntry","some","transitive","includes","rewrote","map","glob","push","diverged","projectName","targetName","advice","migrateSmithyTarget","undefined","executor","cache","rest","migrateRdbGenerate","migrateTerraformOutput","_inputs","migrateProject","project","generator","metadata","targets","migrations","id","name","generate","output","changed","migrate","migrated","migration","rewroteGlob"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type MigrationReturnObject, type Tree } from '@nx/devkit';
|
|
6
|
+
export default function migration(tree: Tree): Promise<MigrationReturnObject>;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { getProjects, joinPathFragments, updateProjectConfiguration } from "@nx/devkit";
|
|
5
|
+
import { INFRA_APP_GENERATOR_INFO } from "../../../infra/app/generator.js";
|
|
6
|
+
import { matchGritQL } from "../../../utils/ast.js";
|
|
7
|
+
import { addCdkTestGlobalSetup, CDK_TEST_GLOBAL_SETUP, CDK_TEST_GLOBAL_SETUP_ENTRY, findVitestConfig, renderCdkTestGlobalSetup } from "../../../utils/cdk-test-setup.js";
|
|
8
|
+
import { formatFilesInSubtree } from "../../../utils/format.js";
|
|
9
|
+
import { sortObjectKeys } from "../../../utils/object.js";
|
|
10
|
+
import { PACKAGES_DIR, SHARED_CONSTRUCTS_DIR } from "../../../utils/shared-constructs-constants.js";
|
|
11
|
+
/**
|
|
12
|
+
* Run CDK infrastructure tests against the artifacts their stacks deploy, in a
|
|
13
|
+
* per-run temp directory with CDK asset bundling skipped.
|
|
14
|
+
*
|
|
15
|
+
* The infra `test` target inherited the `^build` target default, so every
|
|
16
|
+
* infra test run first ran every deployed project's lint, test, type-check and
|
|
17
|
+
* bundle. The stacks only need the bundles: `Code.fromAsset` and its siblings
|
|
18
|
+
* throw on a missing asset path, so the edge is narrowed to `^assemble` (the
|
|
19
|
+
* artifact-only chain `synth` and `deploy` already use) rather than removed.
|
|
20
|
+
*
|
|
21
|
+
* Each `new App()` in a test synthesizes into a fresh `cdk.out*` directory
|
|
22
|
+
* under the OS temp dir, which nothing removed, so a workspace's tests leaked
|
|
23
|
+
* into the shared `/tmp`. The vended `tests/global-setup.ts` points `TMPDIR`,
|
|
24
|
+
* `TEMP` and `TMP` at a directory of its own for the run and removes it in
|
|
25
|
+
* teardown. aws-cdk-lib deletes the `cdk.out*` directories an `App` created
|
|
26
|
+
* from a `process.on('exit')` handler, and vitest runs the global teardown
|
|
27
|
+
* while its forked workers are still exiting, so a single `rmSync` can race
|
|
28
|
+
* that delete and return with the directory still there. The teardown
|
|
29
|
+
* therefore retries every 50 ms for up to 2 s, and warns (naming the
|
|
30
|
+
* directory) rather than failing the run if it is still there. It also merges `aws:cdk:bundling-stacks: []` into
|
|
31
|
+
* `CDK_CONTEXT_JSON`, which only affects user-written bundling constructs
|
|
32
|
+
* (`NodejsFunction`, `PythonFunction`); the vended constructs read prebuilt
|
|
33
|
+
* bundles. The setup is registered in the infra project's and the shared
|
|
34
|
+
* constructs' vitest configs.
|
|
35
|
+
*
|
|
36
|
+
* Only the exact shape the generator wrote before is changed. A `test` target,
|
|
37
|
+
* a `globalSetup`, a vitest config or a `tests/global-setup.ts` that differs is
|
|
38
|
+
* left untouched and reported, and a setup file the plugin did not write is
|
|
39
|
+
* never registered. The migration writes the generator's own template, so a migrated project is
|
|
40
|
+
* byte-identical to a freshly generated one. Infra READMEs are left alone: the
|
|
41
|
+
* generator writes them `KeepExisting`, and users edit them.
|
|
42
|
+
*/ const TEST_TARGET = 'test';
|
|
43
|
+
const TEST_DEPENDS_ON = [
|
|
44
|
+
'^assemble'
|
|
45
|
+
];
|
|
46
|
+
const isFixedTestTarget = (target)=>Object.keys(target).length === 1 && Array.isArray(target.dependsOn) && target.dependsOn.length === TEST_DEPENDS_ON.length && target.dependsOn.every((dep, index)=>dep === TEST_DEPENDS_ON[index]);
|
|
47
|
+
/** Any `globalSetup` property in the config. */ const ANY_GLOBAL_SETUP = '`globalSetup: $_`';
|
|
48
|
+
/** Exactly the entry the generator registers. */ const VENDED_GLOBAL_SETUP = `\`globalSetup: ['${CDK_TEST_GLOBAL_SETUP_ENTRY}']\``;
|
|
49
|
+
/** The `defineConfig(() => ({ test: { ... } }))` shape the generator inserts into. */ const RECOGNISED_CONFIG = `\`test: { $props }\` where { $props <: within \`defineConfig($_)\` }`;
|
|
50
|
+
/**
|
|
51
|
+
* Vend and register the global setup for one project, unless any of its files
|
|
52
|
+
* has diverged from the generated shape. Returns the reason it was skipped.
|
|
53
|
+
*/ const migrateGlobalSetup = async (tree, projectName, root)=>{
|
|
54
|
+
const setupPath = joinPathFragments(root, CDK_TEST_GLOBAL_SETUP);
|
|
55
|
+
const configPath = findVitestConfig(tree, root);
|
|
56
|
+
if (!configPath) {
|
|
57
|
+
return `${projectName}: no vitest config found in ${root} - add \`globalSetup: ['${CDK_TEST_GLOBAL_SETUP_ENTRY}']\` to its \`test\` options to give each test run its own temp directory.`;
|
|
58
|
+
}
|
|
59
|
+
if (tree.exists(setupPath) && (tree.read(setupPath, 'utf-8') ?? '') !== renderCdkTestGlobalSetup()) {
|
|
60
|
+
return `${projectName}: ${setupPath} differs from the vended global setup - left untouched and not registered. Compare it with a freshly generated one, which gives each test run its own temp directory and skips CDK asset bundling, then add \`globalSetup: ['${CDK_TEST_GLOBAL_SETUP_ENTRY}']\` to ${configPath}.`;
|
|
61
|
+
}
|
|
62
|
+
if (await matchGritQL(tree, configPath, ANY_GLOBAL_SETUP)) {
|
|
63
|
+
if (await matchGritQL(tree, configPath, VENDED_GLOBAL_SETUP)) {
|
|
64
|
+
await addCdkTestGlobalSetup(tree, root);
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
return `${projectName}: ${configPath} already declares a \`globalSetup\` - left untouched. Add '${CDK_TEST_GLOBAL_SETUP_ENTRY}' to it to give each test run its own temp directory.`;
|
|
68
|
+
}
|
|
69
|
+
if (!await matchGritQL(tree, configPath, RECOGNISED_CONFIG)) {
|
|
70
|
+
return `${projectName}: ${configPath} has diverged from the generated shape - left untouched. Add \`globalSetup: ['${CDK_TEST_GLOBAL_SETUP_ENTRY}']\` to its \`test\` options to give each test run its own temp directory.`;
|
|
71
|
+
}
|
|
72
|
+
await addCdkTestGlobalSetup(tree, root);
|
|
73
|
+
return undefined;
|
|
74
|
+
};
|
|
75
|
+
export default async function migration(tree) {
|
|
76
|
+
const nextSteps = [];
|
|
77
|
+
for (const [projectName, project] of getProjects(tree)){
|
|
78
|
+
const generator = project.metadata?.generator;
|
|
79
|
+
if (generator !== INFRA_APP_GENERATOR_INFO.id) continue;
|
|
80
|
+
const testTarget = project.targets?.[TEST_TARGET];
|
|
81
|
+
if (!testTarget) {
|
|
82
|
+
updateProjectConfiguration(tree, projectName, {
|
|
83
|
+
...project,
|
|
84
|
+
targets: sortObjectKeys({
|
|
85
|
+
...project.targets,
|
|
86
|
+
[TEST_TARGET]: {
|
|
87
|
+
dependsOn: [
|
|
88
|
+
...TEST_DEPENDS_ON
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
});
|
|
93
|
+
} else if (!isFixedTestTarget(testTarget)) {
|
|
94
|
+
nextSteps.push(`${projectName}: the \`test\` target in ${joinPathFragments(project.root, 'project.json')} has diverged from the generated shape - left untouched. Set its \`dependsOn\` to ["^assemble"] so tests build the deployed projects' artifacts rather than every upstream build.`);
|
|
95
|
+
}
|
|
96
|
+
const skipped = await migrateGlobalSetup(tree, projectName, project.root);
|
|
97
|
+
if (skipped) nextSteps.push(skipped);
|
|
98
|
+
}
|
|
99
|
+
const constructsRoot = joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR);
|
|
100
|
+
if (tree.exists(joinPathFragments(constructsRoot, 'project.json'))) {
|
|
101
|
+
const skipped = await migrateGlobalSetup(tree, constructsRoot, constructsRoot);
|
|
102
|
+
if (skipped) nextSteps.push(skipped);
|
|
103
|
+
}
|
|
104
|
+
await formatFilesInSubtree(tree);
|
|
105
|
+
return {
|
|
106
|
+
nextSteps
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
//# sourceMappingURL=migration.js.map
|