@aws/nx-plugin 1.0.0-rc.86 → 1.0.0-rc.87
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/migrations.json +11 -1
- package/package.json +1 -1
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +34 -8
- package/src/infra/app/files/app/README.md.template +14 -0
- package/src/infra/app/generator.js +15 -2
- package/src/infra/app/generator.js.map +1 -1
- package/src/mcp-server/tools/general-guidance.js +1 -1
- package/src/mcp-server/tools/general-guidance.js.map +1 -1
- package/src/migrations/latest/add-destroy-sandbox-target/metadata.json +3 -0
- package/src/migrations/latest/add-destroy-sandbox-target/migration.d.ts +6 -0
- package/src/migrations/latest/add-destroy-sandbox-target/migration.js +150 -0
- package/src/migrations/latest/add-destroy-sandbox-target/migration.js.map +1 -0
- package/src/migrations/latest/terraform-rdb-proxy-iam-connect-grant/__snapshots__/migration.spec.ts.snap +23 -0
- package/src/migrations/latest/terraform-rdb-proxy-iam-connect-grant/metadata.json +3 -0
- package/src/migrations/latest/terraform-rdb-proxy-iam-connect-grant/migration.d.ts +6 -0
- package/src/migrations/latest/terraform-rdb-proxy-iam-connect-grant/migration.js +88 -0
- package/src/migrations/latest/terraform-rdb-proxy-iam-connect-grant/migration.js.map +1 -0
- package/src/open-api/ts-client/generator.js.map +1 -1
- package/src/open-api/ts-hooks/generator.spec.tsx +1 -1
- package/src/py/project/generator.js +5 -5
- package/src/py/project/generator.js.map +1 -1
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +8 -8
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +16 -16
- package/src/ts/dcr-proxy/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/ts/lambda-function/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +4 -11
- package/src/ts/react-website/cognito-auth/generator.js +1 -1
- package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
- package/src/ts/react-website/runtime-config/generator.js +1 -1
- package/src/ts/react-website/runtime-config/generator.js.map +1 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.js +3 -2
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/agentcore-gateway.ts.template +1 -1
- package/src/utils/api-constructs/api-constructs.js +7 -4
- package/src/utils/api-constructs/api-constructs.js.map +1 -1
- package/src/utils/api-constructs/files/cdk/app/apis/http/__apiNameKebabCase__.ts.template +4 -4
- package/src/utils/api-constructs/files/cdk/app/apis/rest/__apiNameKebabCase__.ts.template +4 -4
- package/src/utils/api-constructs/files/cdk/core/api/rest/api-gateway-account.ts.template +1 -1
- package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +4 -4
- package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +4 -4
- package/src/utils/ast.d.ts +13 -0
- package/src/utils/ast.js +36 -0
- package/src/utils/ast.js.map +1 -1
- package/src/utils/bundle/bundle.js +5 -2
- package/src/utils/bundle/bundle.js.map +1 -1
- package/src/utils/dcr-proxy-constructs/dcr-proxy-constructs.js +5 -3
- package/src/utils/dcr-proxy-constructs/dcr-proxy-constructs.js.map +1 -1
- package/src/utils/dcr-proxy-constructs/files/cdk/app/dcr-proxies/__nameKebabCase__/__nameKebabCase__.ts.template +1 -1
- package/src/utils/dcr-proxy-constructs/files/terraform/app/dcr-proxies/__nameKebabCase__/__nameKebabCase__.tf.template +2 -2
- package/src/utils/files/common/scripts/src/infra/stage-credentials/cdk-command.ts.template +7 -3
- package/src/utils/function-constructs/function-constructs.js +3 -3
- package/src/utils/function-constructs/function-constructs.js.map +1 -1
- package/src/utils/lambda-runtime-resolution.d.ts +74 -0
- package/src/utils/lambda-runtime-resolution.js +97 -0
- package/src/utils/lambda-runtime-resolution.js.map +1 -0
- package/src/utils/rdb-constructs/files/cdk/app/dbs/__nameKebabCase__.ts.template +3 -3
- package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +4 -21
- package/src/utils/rdb-constructs/rdb-constructs.js +5 -3
- package/src/utils/rdb-constructs/rdb-constructs.js.map +1 -1
- package/src/utils/version-upgrade-migration/sync-lambda-runtimes.d.ts +28 -0
- package/src/utils/version-upgrade-migration/sync-lambda-runtimes.js +148 -0
- package/src/utils/version-upgrade-migration/sync-lambda-runtimes.js.map +1 -0
- package/src/utils/version-upgrade-migration/sync-python-language-version.d.ts +31 -0
- package/src/utils/version-upgrade-migration/sync-python-language-version.js +110 -0
- package/src/utils/version-upgrade-migration/sync-python-language-version.js.map +1 -0
- package/src/utils/version-upgrade-migration/sync-vended-versions.js +36 -7
- package/src/utils/version-upgrade-migration/sync-vended-versions.js.map +1 -1
- package/src/utils/versions.d.ts +60 -0
- package/src/utils/versions.js +51 -0
- package/src/utils/versions.js.map +1 -1
|
@@ -4,14 +4,14 @@ import { readFileSync } from 'fs';
|
|
|
4
4
|
import { Construct } from 'constructs';
|
|
5
5
|
import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
|
|
6
6
|
import {
|
|
7
|
-
<%_ if (framework
|
|
7
|
+
<%_ if (framework === 'prisma') { _%>
|
|
8
8
|
Code,
|
|
9
9
|
<%_ } _%>
|
|
10
10
|
DockerImageCode,
|
|
11
11
|
DockerImageFunction,
|
|
12
12
|
Function,
|
|
13
13
|
FunctionOptions,
|
|
14
|
-
<%_ if (framework
|
|
14
|
+
<%_ if (framework === 'prisma') { _%>
|
|
15
15
|
Runtime,
|
|
16
16
|
<%_ } _%>
|
|
17
17
|
} from 'aws-cdk-lib/aws-lambda';
|
|
@@ -76,7 +76,7 @@ export class <%= nameClassName %> extends AuroraDatabase {
|
|
|
76
76
|
...baseProps,
|
|
77
77
|
code: Code.fromAsset(createDbUserBundleDir),
|
|
78
78
|
handler: 'index.handler',
|
|
79
|
-
runtime:
|
|
79
|
+
runtime: <%- nodeRuntime %>,
|
|
80
80
|
environment: {
|
|
81
81
|
NODE_EXTRA_CA_CERTS: '/var/runtime/ca-cert.pem',
|
|
82
82
|
},
|
|
@@ -138,7 +138,7 @@ variable "create_db_user_docker_image_tag" {
|
|
|
138
138
|
}
|
|
139
139
|
<%_ } _%>
|
|
140
140
|
|
|
141
|
-
<%_ if (framework
|
|
141
|
+
<%_ if (framework === 'prisma') { _%>
|
|
142
142
|
variable "asset_bucket_name" {
|
|
143
143
|
description = "Name of the shared asset S3 bucket used to stage the Lambda deployment zip. Instantiate the `core/asset-bucket` module once per deployment and pass its `bucket_name` output here."
|
|
144
144
|
type = string
|
|
@@ -157,7 +157,7 @@ resource "random_string" "suffix" {
|
|
|
157
157
|
locals {
|
|
158
158
|
config = jsondecode(file("${path.module}/../../../../../../../<%= projectRoot %>/config.json"))
|
|
159
159
|
runtime_config_key = local.config.runtimeConfigKey
|
|
160
|
-
<%_ if (framework
|
|
160
|
+
<%_ if (framework === 'prisma') { _%>
|
|
161
161
|
create_db_user_bundle_path = "${path.module}/../../../../../../../<%- createDbUserBundleDir %>"
|
|
162
162
|
<%_ } _%>
|
|
163
163
|
migration_function_name = "<%= nameKebabCase %>-migration-${random_string.suffix.result}"
|
|
@@ -198,22 +198,6 @@ resource "aws_iam_role_policy" "proxy_db_user_connect" {
|
|
|
198
198
|
policy = jsonencode({
|
|
199
199
|
Version = "2012-10-17"
|
|
200
200
|
Statement = [
|
|
201
|
-
<%_ if (engine === 'mysql' && framework !== 'sqlmodel') { _%>
|
|
202
|
-
{
|
|
203
|
-
Effect = "Allow"
|
|
204
|
-
Action = [
|
|
205
|
-
"secretsmanager:GetSecretValue"
|
|
206
|
-
]
|
|
207
|
-
Resource = [module.aurora.secret_arn]
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
Effect = "Allow"
|
|
211
|
-
Action = [
|
|
212
|
-
"kms:Decrypt"
|
|
213
|
-
]
|
|
214
|
-
Resource = [module.aurora.kms_key_arn]
|
|
215
|
-
}
|
|
216
|
-
<%_ } else { _%>
|
|
217
201
|
{
|
|
218
202
|
Effect = "Allow"
|
|
219
203
|
Action = ["rds-db:connect"]
|
|
@@ -221,12 +205,11 @@ resource "aws_iam_role_policy" "proxy_db_user_connect" {
|
|
|
221
205
|
"arn:aws:rds-db:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:dbuser:${module.aurora.cluster_resource_id}/${local.database_runtime_user}"
|
|
222
206
|
]
|
|
223
207
|
}
|
|
224
|
-
<%_ } _%>
|
|
225
208
|
]
|
|
226
209
|
})
|
|
227
210
|
}
|
|
228
211
|
|
|
229
|
-
<%_ if (framework
|
|
212
|
+
<%_ if (framework === 'prisma') { _%>
|
|
230
213
|
data "archive_file" "create_db_user_zip" {
|
|
231
214
|
type = "zip"
|
|
232
215
|
source_dir = local.create_db_user_bundle_path
|
|
@@ -587,7 +570,7 @@ resource "aws_lambda_function" "create_db_user" {
|
|
|
587
570
|
role = aws_iam_role.create_db_user.arn
|
|
588
571
|
handler = "index.handler"
|
|
589
572
|
source_code_hash = data.archive_file.create_db_user_zip.output_base64sha256
|
|
590
|
-
runtime = "
|
|
573
|
+
runtime = "<%- nodeRuntime %>"
|
|
591
574
|
timeout = 300
|
|
592
575
|
architectures = ["arm64"]
|
|
593
576
|
<%_ } _%>
|
|
@@ -6,7 +6,7 @@ import { addStarExport } from "../ast.js";
|
|
|
6
6
|
import { esmVars } from "../module-format.js";
|
|
7
7
|
import { addDependencyToTargetIfNotPresent } from "../nx.js";
|
|
8
8
|
import { PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, SHARED_TERRAFORM_DIR } from "../shared-constructs-constants.js";
|
|
9
|
-
import { terraformProviderVersions } from "../versions.js";
|
|
9
|
+
import { cdkLambdaRuntimeVars, terraformLambdaRuntimeVars, terraformProviderVersions } from "../versions.js";
|
|
10
10
|
/**
|
|
11
11
|
* Aurora Serverless v2 scaling bounds, in ACUs, that both IaC providers derive
|
|
12
12
|
* from so the same generator options vend the same ceiling regardless of `--iac`.
|
|
@@ -48,7 +48,8 @@ export const addRdbCdkConstructs = async (tree, options)=>{
|
|
|
48
48
|
});
|
|
49
49
|
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'cdk', 'app', 'dbs'), joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, 'src', 'app', 'dbs'), {
|
|
50
50
|
...options,
|
|
51
|
-
...esmVars(tree)
|
|
51
|
+
...esmVars(tree),
|
|
52
|
+
...cdkLambdaRuntimeVars()
|
|
52
53
|
}, {
|
|
53
54
|
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
54
55
|
});
|
|
@@ -66,7 +67,8 @@ export const addRdbTerraformModules = (tree, options)=>{
|
|
|
66
67
|
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'terraform', 'app', 'dbs'), joinPathFragments(PACKAGES_DIR, SHARED_TERRAFORM_DIR, 'src', 'app', 'dbs'), {
|
|
67
68
|
...options,
|
|
68
69
|
...terraformProviderVersions(),
|
|
69
|
-
...auroraServerlessV2Capacity()
|
|
70
|
+
...auroraServerlessV2Capacity(),
|
|
71
|
+
...terraformLambdaRuntimeVars()
|
|
70
72
|
}, {
|
|
71
73
|
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
72
74
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/rdb-constructs/rdb-constructs.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n type Tree,\n updateJson,\n} from '@nx/devkit';\nimport { addStarExport } from '../ast.js';\nimport type { Containers } from '../containers.js';\nimport type { Iac } from '../iac.js';\nimport { esmVars } from '../module-format.js';\nimport { addDependencyToTargetIfNotPresent } from '../nx.js';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../shared-constructs-constants.js';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/rdb-constructs/rdb-constructs.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n type Tree,\n updateJson,\n} from '@nx/devkit';\nimport { addStarExport } from '../ast.js';\nimport type { Containers } from '../containers.js';\nimport type { Iac } from '../iac.js';\nimport { esmVars } from '../module-format.js';\nimport { addDependencyToTargetIfNotPresent } from '../nx.js';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../shared-constructs-constants.js';\nimport {\n cdkLambdaRuntimeVars,\n terraformLambdaRuntimeVars,\n terraformProviderVersions,\n} from '../versions.js';\n\n/**\n * Aurora Serverless v2 scaling bounds, in ACUs, that both IaC providers derive\n * from so the same generator options vend the same ceiling regardless of `--iac`.\n *\n * Set explicitly on CDK rather than inheriting `DatabaseClusterProps`, whose\n * default moves with `aws-cdk-lib`. Serverless v2 bills on ACUs consumed, not on\n * the ceiling, so the maximum is headroom rather than a cost commitment.\n */\nexport const AURORA_SERVERLESS_V2_CAPACITY = {\n min: 0.5,\n max: 4,\n} as const;\n\n/**\n * Substitution variables exposing the Aurora Serverless v2 scaling bounds to\n * generated CDK and Terraform templates.\n */\nconst auroraServerlessV2Capacity = () => ({\n serverlessMinCapacity: AURORA_SERVERLESS_V2_CAPACITY.min,\n serverlessMaxCapacity: AURORA_SERVERLESS_V2_CAPACITY.max,\n});\n\nexport interface AddRdbConstructOptions {\n projectName: string;\n projectRoot: string;\n nameClassName: string;\n nameKebabCase: string;\n databasePackageAlias: string;\n databaseName: string;\n adminUser: string;\n engine: 'postgres' | 'mysql';\n migrationBundleDir: string;\n /**\n * Node.js zip bundle directory for the create-db-user Lambda (ts#rdb).\n * When absent the migration Docker image is reused with the\n * `create_db_user_handler.handler` command (py#rdb).\n */\n createDbUserBundleDir: string;\n /** ORM framework used by the create-db-user Lambda. */\n framework: 'prisma' | 'sqlmodel';\n /** Local Docker tag for the Python create-db-user Lambda image. */\n createDbUserDockerImageTag?: string;\n /** Local Docker tag for the migration Lambda image. */\n migrationDockerImageTag: string;\n containerEngine: Containers;\n}\n\nexport const addRdbInfra = async (\n tree: Tree,\n options: AddRdbConstructOptions & { iac: Iac },\n) => {\n if (options.iac === 'cdk') {\n await addRdbCdkConstructs(tree, options);\n } else if (options.iac === 'terraform') {\n addRdbTerraformModules(tree, options);\n } else {\n throw new Error(`Unsupported iac ${options.iac}`);\n }\n\n updateJson(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n options.iac === 'cdk' ? SHARED_CONSTRUCTS_DIR : SHARED_TERRAFORM_DIR,\n 'project.json',\n ),\n (config: ProjectConfiguration) => {\n addDependencyToTargetIfNotPresent(\n config,\n 'build',\n `${options.projectName}:build`,\n );\n return config;\n },\n );\n};\n\nexport const addRdbCdkConstructs = async (\n tree: Tree,\n options: AddRdbConstructOptions,\n) => {\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'cdk', 'core', 'rdb'),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'core',\n 'rdb',\n ),\n { ...options, ...esmVars(tree), ...auroraServerlessV2Capacity() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'cdk', 'app', 'dbs'),\n joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, 'src', 'app', 'dbs'),\n { ...options, ...esmVars(tree), ...cdkLambdaRuntimeVars() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'core',\n 'index.ts',\n ),\n './rdb/aurora.js',\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'dbs',\n 'index.ts',\n ),\n `./${options.nameKebabCase}.js`,\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'index.ts',\n ),\n './dbs/index.js',\n );\n};\n\nexport const addRdbTerraformModules = (\n tree: Tree,\n options: AddRdbConstructOptions,\n) => {\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'terraform', 'core', 'rdb'),\n joinPathFragments(PACKAGES_DIR, SHARED_TERRAFORM_DIR, 'src', 'core', 'rdb'),\n { ...terraformProviderVersions(), ...auroraServerlessV2Capacity() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'terraform', 'app', 'dbs'),\n joinPathFragments(PACKAGES_DIR, SHARED_TERRAFORM_DIR, 'src', 'app', 'dbs'),\n {\n ...options,\n ...terraformProviderVersions(),\n ...auroraServerlessV2Capacity(),\n ...terraformLambdaRuntimeVars(),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n};\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateJson","addStarExport","esmVars","addDependencyToTargetIfNotPresent","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","cdkLambdaRuntimeVars","terraformLambdaRuntimeVars","terraformProviderVersions","AURORA_SERVERLESS_V2_CAPACITY","min","max","auroraServerlessV2Capacity","serverlessMinCapacity","serverlessMaxCapacity","addRdbInfra","tree","options","iac","addRdbCdkConstructs","addRdbTerraformModules","Error","config","projectName","dirname","overwriteStrategy","KeepExisting","nameKebabCase"],"mappings":"AAAA;;;CAGC,GACD,SACEA,aAAa,EACbC,iBAAiB,EACjBC,iBAAiB,EAGjBC,UAAU,QACL,aAAa;AACpB,SAASC,aAAa,QAAQ,YAAY;AAG1C,SAASC,OAAO,QAAQ,sBAAsB;AAC9C,SAASC,iCAAiC,QAAQ,WAAW;AAC7D,SACEC,YAAY,EACZC,qBAAqB,EACrBC,oBAAoB,QACf,oCAAoC;AAC3C,SACEC,oBAAoB,EACpBC,0BAA0B,EAC1BC,yBAAyB,QACpB,iBAAiB;AAExB;;;;;;;CAOC,GACD,OAAO,MAAMC,gCAAgC;IAC3CC,KAAK;IACLC,KAAK;AACP,EAAW;AAEX;;;CAGC,GACD,MAAMC,6BAA6B,IAAO,CAAA;QACxCC,uBAAuBJ,8BAA8BC,GAAG;QACxDI,uBAAuBL,8BAA8BE,GAAG;IAC1D,CAAA;AA2BA,OAAO,MAAMI,cAAc,OACzBC,MACAC;IAEA,IAAIA,QAAQC,GAAG,KAAK,OAAO;QACzB,MAAMC,oBAAoBH,MAAMC;IAClC,OAAO,IAAIA,QAAQC,GAAG,KAAK,aAAa;QACtCE,uBAAuBJ,MAAMC;IAC/B,OAAO;QACL,MAAM,IAAII,MAAM,CAAC,gBAAgB,EAAEJ,QAAQC,GAAG,EAAE;IAClD;IAEAnB,WACEiB,MACAnB,kBACEM,cACAc,QAAQC,GAAG,KAAK,QAAQd,wBAAwBC,sBAChD,iBAEF,CAACiB;QACCpB,kCACEoB,QACA,SACA,GAAGL,QAAQM,WAAW,CAAC,MAAM,CAAC;QAEhC,OAAOD;IACT;AAEJ,EAAE;AAEF,OAAO,MAAMH,sBAAsB,OACjCH,MACAC;IAEArB,cACEoB,MACAnB,kBAAkB,YAAY2B,OAAO,EAAE,SAAS,OAAO,QAAQ,QAC/D3B,kBACEM,cACAC,uBACA,OACA,QACA,QAEF;QAAE,GAAGa,OAAO;QAAE,GAAGhB,QAAQe,KAAK;QAAE,GAAGJ,4BAA4B;IAAC,GAChE;QACEa,mBAAmB3B,kBAAkB4B,YAAY;IACnD;IAGF9B,cACEoB,MACAnB,kBAAkB,YAAY2B,OAAO,EAAE,SAAS,OAAO,OAAO,QAC9D3B,kBAAkBM,cAAcC,uBAAuB,OAAO,OAAO,QACrE;QAAE,GAAGa,OAAO;QAAE,GAAGhB,QAAQe,KAAK;QAAE,GAAGV,sBAAsB;IAAC,GAC1D;QACEmB,mBAAmB3B,kBAAkB4B,YAAY;IACnD;IAGF,MAAM1B,cACJgB,MACAnB,kBACEM,cACAC,uBACA,OACA,QACA,aAEF;IAEF,MAAMJ,cACJgB,MACAnB,kBACEM,cACAC,uBACA,OACA,OACA,OACA,aAEF,CAAC,EAAE,EAAEa,QAAQU,aAAa,CAAC,GAAG,CAAC;IAEjC,MAAM3B,cACJgB,MACAnB,kBACEM,cACAC,uBACA,OACA,OACA,aAEF;AAEJ,EAAE;AAEF,OAAO,MAAMgB,yBAAyB,CACpCJ,MACAC;IAEArB,cACEoB,MACAnB,kBAAkB,YAAY2B,OAAO,EAAE,SAAS,aAAa,QAAQ,QACrE3B,kBAAkBM,cAAcE,sBAAsB,OAAO,QAAQ,QACrE;QAAE,GAAGG,2BAA2B;QAAE,GAAGI,4BAA4B;IAAC,GAClE;QACEa,mBAAmB3B,kBAAkB4B,YAAY;IACnD;IAGF9B,cACEoB,MACAnB,kBAAkB,YAAY2B,OAAO,EAAE,SAAS,aAAa,OAAO,QACpE3B,kBAAkBM,cAAcE,sBAAsB,OAAO,OAAO,QACpE;QACE,GAAGY,OAAO;QACV,GAAGT,2BAA2B;QAC9B,GAAGI,4BAA4B;QAC/B,GAAGL,4BAA4B;IACjC,GACA;QACEkB,mBAAmB3B,kBAAkB4B,YAAY;IACnD;AAEJ,EAAE"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type Tree } from '@nx/devkit';
|
|
6
|
+
/**
|
|
7
|
+
* Sync the Lambda runtimes vended into the projects this plugin owns.
|
|
8
|
+
*
|
|
9
|
+
* The runtimes present are read from each file rather than compared against a
|
|
10
|
+
* list of what past releases vended, which would need maintaining by hand for the
|
|
11
|
+
* same reason the pin itself does.
|
|
12
|
+
*/
|
|
13
|
+
/** The IaC provider a vended file belongs to, decided by the directory it sits in. */
|
|
14
|
+
export type VendedIac = 'cdk' | 'terraform';
|
|
15
|
+
/**
|
|
16
|
+
* Sync the Lambda runtimes in the directories this plugin owns.
|
|
17
|
+
*
|
|
18
|
+
* A runtime below the pin is ours to move, as is a `_LATEST` alias — its value is
|
|
19
|
+
* decided by `aws-cdk-lib`, which is the drift this closes. A runtime at or ahead
|
|
20
|
+
* of the pin is the user's and is left, as is any Lambda outside these
|
|
21
|
+
* directories. One the rewrite cannot reach is reported instead.
|
|
22
|
+
*
|
|
23
|
+
* @returns the files changed, and the owned files still holding an older runtime
|
|
24
|
+
*/
|
|
25
|
+
export declare const syncLambdaRuntimes: (tree: Tree, dirs: Readonly<Record<VendedIac, string>>) => Promise<{
|
|
26
|
+
updated: string[];
|
|
27
|
+
diverged: string[];
|
|
28
|
+
}>;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { visitNotIgnoredFiles } from "@nx/devkit";
|
|
5
|
+
import { applyGritQL, captureAllGritQLVariable } from "../ast.js";
|
|
6
|
+
import { cdkLambdaRuntime, LAMBDA_RUNTIME_VERSIONS, terraformLambdaRuntime } from "../versions.js";
|
|
7
|
+
import { isVendedUpgrade } from "./vended-upgrade.js";
|
|
8
|
+
/**
|
|
9
|
+
* GritQL binding the value of a `runtime` assignment.
|
|
10
|
+
*
|
|
11
|
+
* Structure is matched here and nowhere else: the binding is the runtime alone, so
|
|
12
|
+
* no caller re-derives the assignment around it, and a `runtime` that isn't a real
|
|
13
|
+
* property or attribute — inside a comment, say — never matches.
|
|
14
|
+
*/ const RUNTIME_ASSIGNMENT = {
|
|
15
|
+
cdk: '`runtime: $value`',
|
|
16
|
+
terraform: 'language hcl\n`runtime = $value`'
|
|
17
|
+
};
|
|
18
|
+
/** `NODEJS_22_X` -> `22`, `PYTHON_3_14` -> `3.14`; undefined for an alias. */ const cdkMemberVersion = (member)=>/^NODEJS_(\d+)_X$/.exec(member)?.[1] ?? /^PYTHON_(\d+)_(\d+)$/.exec(member)?.slice(1).join('.');
|
|
19
|
+
/**
|
|
20
|
+
* Read a bound CDK runtime, or undefined when the value is not a versioned managed
|
|
21
|
+
* runtime.
|
|
22
|
+
*
|
|
23
|
+
* GritQL has already established this is a `runtime` property and isolated its
|
|
24
|
+
* value, so the regex only reads that scalar.
|
|
25
|
+
*/ const readCdkRuntime = (value)=>{
|
|
26
|
+
const member = /^(?:lambda\.)?Runtime\.((?:NODEJS|PYTHON)_[A-Z0-9_]+)$/.exec(value.trim())?.[1];
|
|
27
|
+
if (!member) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
value: value.trim(),
|
|
32
|
+
language: member.startsWith('NODEJS') ? 'node' : 'python',
|
|
33
|
+
version: cdkMemberVersion(member)
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
/** Read a bound Terraform runtime, or undefined for a non-runtime value. */ const readTerraformRuntime = (value)=>{
|
|
37
|
+
const identifier = /^"((?:nodejs|python)[0-9][^"]*)"$/.exec(value.trim())?.[1];
|
|
38
|
+
if (!identifier) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
value: value.trim(),
|
|
43
|
+
language: identifier.startsWith('nodejs') ? 'node' : 'python',
|
|
44
|
+
version: /^nodejs([\d.]+?)\.x$/.exec(identifier)?.[1] ?? /^python([\d.]+)$/.exec(identifier)?.[1]
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Every runtime a vended file assigns, or undefined when the pattern could not be
|
|
49
|
+
* applied to it.
|
|
50
|
+
*
|
|
51
|
+
* The two are distinguished so a file the parser rejected is reported rather than
|
|
52
|
+
* mistaken for one with nothing to do, which would make this a silent no-op.
|
|
53
|
+
*/ const declaredRuntimes = async (tree, path, iac)=>{
|
|
54
|
+
const values = await captureAllGritQLVariable(tree, path, RUNTIME_ASSIGNMENT[iac], 'value');
|
|
55
|
+
if (values === undefined) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
const read = iac === 'terraform' ? readTerraformRuntime : readCdkRuntime;
|
|
59
|
+
return values.flatMap((value)=>{
|
|
60
|
+
const runtime = read(value);
|
|
61
|
+
return runtime ? [
|
|
62
|
+
runtime
|
|
63
|
+
] : [];
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* The runtime this release vends, written the way the declared one was.
|
|
68
|
+
*
|
|
69
|
+
* A namespace-imported construct writes `lambda.Runtime.X`, so the prefix on the
|
|
70
|
+
* declared value is carried over rather than dropped.
|
|
71
|
+
*/ const vendedRuntime = (iac, declared)=>{
|
|
72
|
+
if (iac === 'terraform') {
|
|
73
|
+
return `"${terraformLambdaRuntime(declared.language)}"`;
|
|
74
|
+
}
|
|
75
|
+
const namespace = declared.value.startsWith('lambda.') ? 'lambda.' : '';
|
|
76
|
+
return `${namespace}${cdkLambdaRuntime(declared.language)}`;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Sync the Lambda runtimes in the directories this plugin owns.
|
|
80
|
+
*
|
|
81
|
+
* A runtime below the pin is ours to move, as is a `_LATEST` alias — its value is
|
|
82
|
+
* decided by `aws-cdk-lib`, which is the drift this closes. A runtime at or ahead
|
|
83
|
+
* of the pin is the user's and is left, as is any Lambda outside these
|
|
84
|
+
* directories. One the rewrite cannot reach is reported instead.
|
|
85
|
+
*
|
|
86
|
+
* @returns the files changed, and the owned files still holding an older runtime
|
|
87
|
+
*/ export const syncLambdaRuntimes = async (tree, dirs)=>{
|
|
88
|
+
const updated = [];
|
|
89
|
+
const diverged = [];
|
|
90
|
+
for (const [iac, dir] of Object.entries(dirs)){
|
|
91
|
+
if (!tree.exists(dir)) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const extension = iac === 'terraform' ? '.tf' : '.ts';
|
|
95
|
+
const files = [];
|
|
96
|
+
// Started at the owned directory, so the provider follows from where a file
|
|
97
|
+
// sits rather than being inferred from it.
|
|
98
|
+
visitNotIgnoredFiles(tree, dir, (path)=>{
|
|
99
|
+
if (path.endsWith(extension)) {
|
|
100
|
+
files.push(path);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
for (const path of files){
|
|
104
|
+
const declared = await declaredRuntimes(tree, path, iac);
|
|
105
|
+
if (declared === undefined) {
|
|
106
|
+
diverged.push(path);
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
let changed = false;
|
|
110
|
+
let stale = false;
|
|
111
|
+
// Deduped: one rewrite covers every occurrence of the same value.
|
|
112
|
+
const seen = new Set();
|
|
113
|
+
for (const runtime of declared){
|
|
114
|
+
if (seen.has(runtime.value)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
seen.add(runtime.value);
|
|
118
|
+
const vended = vendedRuntime(iac, runtime);
|
|
119
|
+
if (runtime.value === vended) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
// An alias carries no version to compare, and is always ours to pin.
|
|
123
|
+
if (runtime.version !== undefined && !isVendedUpgrade(LAMBDA_RUNTIME_VERSIONS[runtime.language], runtime.version)) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const assignment = iac === 'terraform' ? 'runtime = ' : 'runtime: ';
|
|
127
|
+
const prefix = iac === 'terraform' ? 'language hcl\n' : '';
|
|
128
|
+
if (await applyGritQL(tree, path, `${prefix}\`${assignment}${runtime.value}\` => \`${assignment}${vended}\``)) {
|
|
129
|
+
changed = true;
|
|
130
|
+
} else {
|
|
131
|
+
stale = true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (changed) {
|
|
135
|
+
updated.push(path);
|
|
136
|
+
}
|
|
137
|
+
if (stale) {
|
|
138
|
+
diverged.push(path);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
updated,
|
|
144
|
+
diverged
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
//# sourceMappingURL=sync-lambda-runtimes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/version-upgrade-migration/sync-lambda-runtimes.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { type Tree, visitNotIgnoredFiles } from '@nx/devkit';\nimport { applyGritQL, captureAllGritQLVariable } from '../ast.js';\nimport {\n cdkLambdaRuntime,\n type ILambdaRuntime,\n LAMBDA_RUNTIME_VERSIONS,\n terraformLambdaRuntime,\n} from '../versions.js';\nimport { isVendedUpgrade } from './vended-upgrade.js';\n\n/**\n * Sync the Lambda runtimes vended into the projects this plugin owns.\n *\n * The runtimes present are read from each file rather than compared against a\n * list of what past releases vended, which would need maintaining by hand for the\n * same reason the pin itself does.\n */\n\n/** The IaC provider a vended file belongs to, decided by the directory it sits in. */\nexport type VendedIac = 'cdk' | 'terraform';\n\n/** A Lambda runtime a vended file declares. */\ninterface DeclaredRuntime {\n /** The runtime as written, e.g. `lambda.Runtime.NODEJS_22_X` or `\"nodejs22.x\"`. */\n readonly value: string;\n readonly language: ILambdaRuntime;\n /**\n * Version the runtime names, or undefined for an alias like `NODEJS_LATEST`\n * whose value `aws-cdk-lib` decides rather than this repo.\n */\n readonly version?: string;\n}\n\n/**\n * GritQL binding the value of a `runtime` assignment.\n *\n * Structure is matched here and nowhere else: the binding is the runtime alone, so\n * no caller re-derives the assignment around it, and a `runtime` that isn't a real\n * property or attribute — inside a comment, say — never matches.\n */\nconst RUNTIME_ASSIGNMENT: Record<VendedIac, string> = {\n cdk: '`runtime: $value`',\n terraform: 'language hcl\\n`runtime = $value`',\n};\n\n/** `NODEJS_22_X` -> `22`, `PYTHON_3_14` -> `3.14`; undefined for an alias. */\nconst cdkMemberVersion = (member: string): string | undefined =>\n /^NODEJS_(\\d+)_X$/.exec(member)?.[1] ??\n /^PYTHON_(\\d+)_(\\d+)$/.exec(member)?.slice(1).join('.');\n\n/**\n * Read a bound CDK runtime, or undefined when the value is not a versioned managed\n * runtime.\n *\n * GritQL has already established this is a `runtime` property and isolated its\n * value, so the regex only reads that scalar.\n */\nconst readCdkRuntime = (value: string): DeclaredRuntime | undefined => {\n const member = /^(?:lambda\\.)?Runtime\\.((?:NODEJS|PYTHON)_[A-Z0-9_]+)$/.exec(\n value.trim(),\n )?.[1];\n if (!member) {\n return undefined;\n }\n return {\n value: value.trim(),\n language: member.startsWith('NODEJS') ? 'node' : 'python',\n version: cdkMemberVersion(member),\n };\n};\n\n/** Read a bound Terraform runtime, or undefined for a non-runtime value. */\nconst readTerraformRuntime = (value: string): DeclaredRuntime | undefined => {\n const identifier = /^\"((?:nodejs|python)[0-9][^\"]*)\"$/.exec(\n value.trim(),\n )?.[1];\n if (!identifier) {\n return undefined;\n }\n return {\n value: value.trim(),\n language: identifier.startsWith('nodejs') ? 'node' : 'python',\n version:\n /^nodejs([\\d.]+?)\\.x$/.exec(identifier)?.[1] ??\n /^python([\\d.]+)$/.exec(identifier)?.[1],\n };\n};\n\n/**\n * Every runtime a vended file assigns, or undefined when the pattern could not be\n * applied to it.\n *\n * The two are distinguished so a file the parser rejected is reported rather than\n * mistaken for one with nothing to do, which would make this a silent no-op.\n */\nconst declaredRuntimes = async (\n tree: Tree,\n path: string,\n iac: VendedIac,\n): Promise<DeclaredRuntime[] | undefined> => {\n const values = await captureAllGritQLVariable(\n tree,\n path,\n RUNTIME_ASSIGNMENT[iac],\n 'value',\n );\n if (values === undefined) {\n return undefined;\n }\n\n const read = iac === 'terraform' ? readTerraformRuntime : readCdkRuntime;\n return values.flatMap((value) => {\n const runtime = read(value);\n return runtime ? [runtime] : [];\n });\n};\n\n/**\n * The runtime this release vends, written the way the declared one was.\n *\n * A namespace-imported construct writes `lambda.Runtime.X`, so the prefix on the\n * declared value is carried over rather than dropped.\n */\nconst vendedRuntime = (iac: VendedIac, declared: DeclaredRuntime): string => {\n if (iac === 'terraform') {\n return `\"${terraformLambdaRuntime(declared.language)}\"`;\n }\n const namespace = declared.value.startsWith('lambda.') ? 'lambda.' : '';\n return `${namespace}${cdkLambdaRuntime(declared.language)}`;\n};\n\n/**\n * Sync the Lambda runtimes in the directories this plugin owns.\n *\n * A runtime below the pin is ours to move, as is a `_LATEST` alias — its value is\n * decided by `aws-cdk-lib`, which is the drift this closes. A runtime at or ahead\n * of the pin is the user's and is left, as is any Lambda outside these\n * directories. One the rewrite cannot reach is reported instead.\n *\n * @returns the files changed, and the owned files still holding an older runtime\n */\nexport const syncLambdaRuntimes = async (\n tree: Tree,\n dirs: Readonly<Record<VendedIac, string>>,\n): Promise<{ updated: string[]; diverged: string[] }> => {\n const updated: string[] = [];\n const diverged: string[] = [];\n\n for (const [iac, dir] of Object.entries(dirs) as [VendedIac, string][]) {\n if (!tree.exists(dir)) {\n continue;\n }\n const extension = iac === 'terraform' ? '.tf' : '.ts';\n const files: string[] = [];\n // Started at the owned directory, so the provider follows from where a file\n // sits rather than being inferred from it.\n visitNotIgnoredFiles(tree, dir, (path) => {\n if (path.endsWith(extension)) {\n files.push(path);\n }\n });\n\n for (const path of files) {\n const declared = await declaredRuntimes(tree, path, iac);\n if (declared === undefined) {\n diverged.push(path);\n continue;\n }\n\n let changed = false;\n let stale = false;\n\n // Deduped: one rewrite covers every occurrence of the same value.\n const seen = new Set<string>();\n for (const runtime of declared) {\n if (seen.has(runtime.value)) {\n continue;\n }\n seen.add(runtime.value);\n\n const vended = vendedRuntime(iac, runtime);\n if (runtime.value === vended) {\n continue;\n }\n // An alias carries no version to compare, and is always ours to pin.\n if (\n runtime.version !== undefined &&\n !isVendedUpgrade(\n LAMBDA_RUNTIME_VERSIONS[runtime.language],\n runtime.version,\n )\n ) {\n continue;\n }\n\n const assignment = iac === 'terraform' ? 'runtime = ' : 'runtime: ';\n const prefix = iac === 'terraform' ? 'language hcl\\n' : '';\n if (\n await applyGritQL(\n tree,\n path,\n `${prefix}\\`${assignment}${runtime.value}\\` => \\`${assignment}${vended}\\``,\n )\n ) {\n changed = true;\n } else {\n stale = true;\n }\n }\n\n if (changed) {\n updated.push(path);\n }\n if (stale) {\n diverged.push(path);\n }\n }\n }\n\n return { updated, diverged };\n};\n"],"names":["visitNotIgnoredFiles","applyGritQL","captureAllGritQLVariable","cdkLambdaRuntime","LAMBDA_RUNTIME_VERSIONS","terraformLambdaRuntime","isVendedUpgrade","RUNTIME_ASSIGNMENT","cdk","terraform","cdkMemberVersion","member","exec","slice","join","readCdkRuntime","value","trim","undefined","language","startsWith","version","readTerraformRuntime","identifier","declaredRuntimes","tree","path","iac","values","read","flatMap","runtime","vendedRuntime","declared","namespace","syncLambdaRuntimes","dirs","updated","diverged","dir","Object","entries","exists","extension","files","endsWith","push","changed","stale","seen","Set","has","add","vended","assignment","prefix"],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type Tree } from '@nx/devkit';
|
|
6
|
+
/**
|
|
7
|
+
* Sync the Python language version a generated workspace builds and lints against
|
|
8
|
+
* to the Lambda Python runtime it deploys onto.
|
|
9
|
+
*
|
|
10
|
+
* These are workspace-wide rather than scoped to the infrastructure projects: uv
|
|
11
|
+
* writes a `.python-version` per Python project wherever it sits, and a bundle
|
|
12
|
+
* target lives in the project it belongs to.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Sync the interpreter a uv project pins to the Lambda Python runtime.
|
|
16
|
+
*
|
|
17
|
+
* `.python-version` holds the exact interpreter and `[project].requires-python`
|
|
18
|
+
* its lower bound; Ruff's `target-version` is derived from the latter, so leaving
|
|
19
|
+
* these behind lints against a different version than the function runs on. Only
|
|
20
|
+
* moved forward, and only from a value this plugin vended.
|
|
21
|
+
*/
|
|
22
|
+
export declare const syncProjectPythonVersion: (tree: Tree) => string[];
|
|
23
|
+
/**
|
|
24
|
+
* Sync the Python version a `bundle` target resolves wheels against.
|
|
25
|
+
*
|
|
26
|
+
* The target pins `--python-platform` but earlier releases pinned no
|
|
27
|
+
* `--python-version`, so wheels resolved against whichever interpreter the build
|
|
28
|
+
* machine had rather than the Lambda runtime. Both the missing flag and a stale
|
|
29
|
+
* one are corrected, keyed on the `uv pip install` the generators write.
|
|
30
|
+
*/
|
|
31
|
+
export declare const syncPythonBundleVersion: (tree: Tree) => string[];
|
|
@@ -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 { updateJson, visitNotIgnoredFiles } from "@nx/devkit";
|
|
5
|
+
import { updateToml } from "../toml.js";
|
|
6
|
+
import { LAMBDA_RUNTIME_VERSIONS, pyenvPythonVersion, pyprojectPythonDependency } from "../versions.js";
|
|
7
|
+
import { isVendedUpgrade } from "./vended-upgrade.js";
|
|
8
|
+
/**
|
|
9
|
+
* Sync the Python language version a generated workspace builds and lints against
|
|
10
|
+
* to the Lambda Python runtime it deploys onto.
|
|
11
|
+
*
|
|
12
|
+
* These are workspace-wide rather than scoped to the infrastructure projects: uv
|
|
13
|
+
* writes a `.python-version` per Python project wherever it sits, and a bundle
|
|
14
|
+
* target lives in the project it belongs to.
|
|
15
|
+
*/ /**
|
|
16
|
+
* Sync the interpreter a uv project pins to the Lambda Python runtime.
|
|
17
|
+
*
|
|
18
|
+
* `.python-version` holds the exact interpreter and `[project].requires-python`
|
|
19
|
+
* its lower bound; Ruff's `target-version` is derived from the latter, so leaving
|
|
20
|
+
* these behind lints against a different version than the function runs on. Only
|
|
21
|
+
* moved forward, and only from a value this plugin vended.
|
|
22
|
+
*/ export const syncProjectPythonVersion = (tree)=>{
|
|
23
|
+
const updated = [];
|
|
24
|
+
const vendedInterpreter = pyenvPythonVersion();
|
|
25
|
+
const vendedRequires = pyprojectPythonDependency();
|
|
26
|
+
// Every `.python-version`, not just the root: uv writes one per project too,
|
|
27
|
+
// and a project left behind resolves a different interpreter than it deploys on.
|
|
28
|
+
visitNotIgnoredFiles(tree, '.', (path)=>{
|
|
29
|
+
if (path !== '.python-version' && !path.endsWith('/.python-version')) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const declared = (tree.read(path, 'utf-8') ?? '').trim();
|
|
33
|
+
if (declared && isVendedUpgrade(vendedInterpreter, declared)) {
|
|
34
|
+
tree.write(path, `${vendedInterpreter}\n`);
|
|
35
|
+
updated.push(path);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
visitNotIgnoredFiles(tree, '.', (path)=>{
|
|
39
|
+
if (!path.endsWith('pyproject.toml')) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
let changed = false;
|
|
43
|
+
updateToml(tree, path, (toml)=>{
|
|
44
|
+
const project = toml.project;
|
|
45
|
+
const declared = project?.['requires-python'];
|
|
46
|
+
if (typeof declared !== 'string') {
|
|
47
|
+
return toml;
|
|
48
|
+
}
|
|
49
|
+
// Only the `>=<major>.<minor>` shape the generators write, so a specifier
|
|
50
|
+
// the user tightened or widened is theirs to keep.
|
|
51
|
+
const lower = /^>=\s*(\d+\.\d+)$/.exec(declared.trim());
|
|
52
|
+
if (lower && isVendedUpgrade(LAMBDA_RUNTIME_VERSIONS.python, lower[1])) {
|
|
53
|
+
project['requires-python'] = vendedRequires;
|
|
54
|
+
changed = true;
|
|
55
|
+
}
|
|
56
|
+
return toml;
|
|
57
|
+
});
|
|
58
|
+
if (changed) {
|
|
59
|
+
updated.push(path);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return updated;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Sync the Python version a `bundle` target resolves wheels against.
|
|
66
|
+
*
|
|
67
|
+
* The target pins `--python-platform` but earlier releases pinned no
|
|
68
|
+
* `--python-version`, so wheels resolved against whichever interpreter the build
|
|
69
|
+
* machine had rather than the Lambda runtime. Both the missing flag and a stale
|
|
70
|
+
* one are corrected, keyed on the `uv pip install` the generators write.
|
|
71
|
+
*/ export const syncPythonBundleVersion = (tree)=>{
|
|
72
|
+
const updated = [];
|
|
73
|
+
const vended = LAMBDA_RUNTIME_VERSIONS.python;
|
|
74
|
+
visitNotIgnoredFiles(tree, '.', (path)=>{
|
|
75
|
+
if (!path.endsWith('project.json')) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
let changed = false;
|
|
79
|
+
updateJson(tree, path, (json)=>{
|
|
80
|
+
for (const target of Object.values(json.targets ?? {})){
|
|
81
|
+
const options = target.options;
|
|
82
|
+
if (!Array.isArray(options?.commands)) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
options.commands = options.commands.map((command)=>{
|
|
86
|
+
if (typeof command !== 'string' || !command.includes('uv pip install') || !command.includes('--python-platform')) {
|
|
87
|
+
return command;
|
|
88
|
+
}
|
|
89
|
+
const declared = /--python-version (\S+)/.exec(command);
|
|
90
|
+
if (!declared) {
|
|
91
|
+
changed = true;
|
|
92
|
+
return command.replace(/(--python-platform \S+)/, `$1 --python-version ${vended}`);
|
|
93
|
+
}
|
|
94
|
+
if (isVendedUpgrade(vended, declared[1])) {
|
|
95
|
+
changed = true;
|
|
96
|
+
return command.replace(/--python-version \S+/, `--python-version ${vended}`);
|
|
97
|
+
}
|
|
98
|
+
return command;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return json;
|
|
102
|
+
});
|
|
103
|
+
if (changed) {
|
|
104
|
+
updated.push(path);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return updated;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
//# sourceMappingURL=sync-python-language-version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/version-upgrade-migration/sync-python-language-version.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { type Tree, updateJson, visitNotIgnoredFiles } from '@nx/devkit';\nimport { updateToml } from '../toml.js';\nimport {\n LAMBDA_RUNTIME_VERSIONS,\n pyenvPythonVersion,\n pyprojectPythonDependency,\n} from '../versions.js';\nimport { isVendedUpgrade } from './vended-upgrade.js';\n\n/**\n * Sync the Python language version a generated workspace builds and lints against\n * to the Lambda Python runtime it deploys onto.\n *\n * These are workspace-wide rather than scoped to the infrastructure projects: uv\n * writes a `.python-version` per Python project wherever it sits, and a bundle\n * target lives in the project it belongs to.\n */\n\n/**\n * Sync the interpreter a uv project pins to the Lambda Python runtime.\n *\n * `.python-version` holds the exact interpreter and `[project].requires-python`\n * its lower bound; Ruff's `target-version` is derived from the latter, so leaving\n * these behind lints against a different version than the function runs on. Only\n * moved forward, and only from a value this plugin vended.\n */\nexport const syncProjectPythonVersion = (tree: Tree): string[] => {\n const updated: string[] = [];\n const vendedInterpreter = pyenvPythonVersion();\n const vendedRequires = pyprojectPythonDependency();\n\n // Every `.python-version`, not just the root: uv writes one per project too,\n // and a project left behind resolves a different interpreter than it deploys on.\n visitNotIgnoredFiles(tree, '.', (path) => {\n if (path !== '.python-version' && !path.endsWith('/.python-version')) {\n return;\n }\n const declared = (tree.read(path, 'utf-8') ?? '').trim();\n if (declared && isVendedUpgrade(vendedInterpreter, declared)) {\n tree.write(path, `${vendedInterpreter}\\n`);\n updated.push(path);\n }\n });\n\n visitNotIgnoredFiles(tree, '.', (path) => {\n if (!path.endsWith('pyproject.toml')) {\n return;\n }\n let changed = false;\n updateToml(tree, path, (toml) => {\n const project = toml.project as Record<string, unknown> | undefined;\n const declared = project?.['requires-python'];\n if (typeof declared !== 'string') {\n return toml;\n }\n // Only the `>=<major>.<minor>` shape the generators write, so a specifier\n // the user tightened or widened is theirs to keep.\n const lower = /^>=\\s*(\\d+\\.\\d+)$/.exec(declared.trim());\n if (lower && isVendedUpgrade(LAMBDA_RUNTIME_VERSIONS.python, lower[1])) {\n project!['requires-python'] = vendedRequires;\n changed = true;\n }\n return toml;\n });\n if (changed) {\n updated.push(path);\n }\n });\n\n return updated;\n};\n\n/**\n * Sync the Python version a `bundle` target resolves wheels against.\n *\n * The target pins `--python-platform` but earlier releases pinned no\n * `--python-version`, so wheels resolved against whichever interpreter the build\n * machine had rather than the Lambda runtime. Both the missing flag and a stale\n * one are corrected, keyed on the `uv pip install` the generators write.\n */\nexport const syncPythonBundleVersion = (tree: Tree): string[] => {\n const updated: string[] = [];\n const vended = LAMBDA_RUNTIME_VERSIONS.python;\n\n visitNotIgnoredFiles(tree, '.', (path) => {\n if (!path.endsWith('project.json')) {\n return;\n }\n let changed = false;\n updateJson(tree, path, (json) => {\n for (const target of Object.values(\n (json.targets ?? {}) as Record<string, { options?: unknown }>,\n )) {\n const options = target.options as { commands?: unknown[] } | undefined;\n if (!Array.isArray(options?.commands)) {\n continue;\n }\n options.commands = options.commands.map((command) => {\n if (\n typeof command !== 'string' ||\n !command.includes('uv pip install') ||\n !command.includes('--python-platform')\n ) {\n return command;\n }\n const declared = /--python-version (\\S+)/.exec(command);\n if (!declared) {\n changed = true;\n return command.replace(\n /(--python-platform \\S+)/,\n `$1 --python-version ${vended}`,\n );\n }\n if (isVendedUpgrade(vended, declared[1])) {\n changed = true;\n return command.replace(\n /--python-version \\S+/,\n `--python-version ${vended}`,\n );\n }\n return command;\n });\n }\n return json;\n });\n if (changed) {\n updated.push(path);\n }\n });\n\n return updated;\n};\n"],"names":["updateJson","visitNotIgnoredFiles","updateToml","LAMBDA_RUNTIME_VERSIONS","pyenvPythonVersion","pyprojectPythonDependency","isVendedUpgrade","syncProjectPythonVersion","tree","updated","vendedInterpreter","vendedRequires","path","endsWith","declared","read","trim","write","push","changed","toml","project","lower","exec","python","syncPythonBundleVersion","vended","json","target","Object","values","targets","options","Array","isArray","commands","map","command","includes","replace"],"mappings":"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"}
|
|
@@ -6,15 +6,18 @@ import yaml from "js-yaml";
|
|
|
6
6
|
import { getCatalogManager } from "nx/src/utils/catalog";
|
|
7
7
|
import { parsePipRequirementsLine } from "pip-requirements-js";
|
|
8
8
|
import { coerce, parse, satisfies, validRange } from "semver";
|
|
9
|
-
import { applyGritQL,
|
|
9
|
+
import { applyGritQL, captureAllGritQLVariable } from "../ast.js";
|
|
10
10
|
import { buildInstallCommand } from "../commands.js";
|
|
11
11
|
import { formatFilesInSubtree } from "../format.js";
|
|
12
|
+
import { PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, SHARED_TERRAFORM_DIR } from "../shared-constructs-constants.js";
|
|
12
13
|
import { updateToml } from "../toml.js";
|
|
13
|
-
import { PY_VERSIONS, TERRAFORM_VERSIONS, TS_VERSIONS } from "../versions.js";
|
|
14
|
+
import { cdkLambdaRuntime, PY_VERSIONS, TERRAFORM_VERSIONS, TS_VERSIONS, terraformLambdaRuntime } from "../versions.js";
|
|
14
15
|
import { isNxPackage } from "./nx-package-updates.js";
|
|
15
16
|
import { ownedDependencies } from "./owned-dependencies.js";
|
|
16
17
|
import { syncEmbeddedVersions } from "./sync-embedded-versions.js";
|
|
18
|
+
import { syncLambdaRuntimes } from "./sync-lambda-runtimes.js";
|
|
17
19
|
import { syncMetricsVersion } from "./sync-metrics-version.js";
|
|
20
|
+
import { syncProjectPythonVersion, syncPythonBundleVersion } from "./sync-python-language-version.js";
|
|
18
21
|
import { isVendedUpgrade } from "./vended-upgrade.js";
|
|
19
22
|
/**
|
|
20
23
|
* Syncs the versions a generated workspace pins to those this release vends:
|
|
@@ -451,9 +454,9 @@ const syncOverrides = (tree, owned)=>{
|
|
|
451
454
|
* `language hcl` is required — without it the pattern silently matches nothing.
|
|
452
455
|
*/ const providerVersionPattern = (provider, rewrite = '')=>`language hcl\n\`version = $version\`${rewrite} where {` + ` $version <: within \`{ source = "hashicorp/${provider}" $... }\` }`;
|
|
453
456
|
/** Version a provider currently declares, if it declares one. */ const declaredProviderVersion = async (tree, path, provider)=>{
|
|
454
|
-
const [
|
|
455
|
-
// The
|
|
456
|
-
return
|
|
457
|
+
const [bound] = await captureAllGritQLVariable(tree, path, providerVersionPattern(provider), 'version') ?? [];
|
|
458
|
+
// The binding is the quoted version, e.g. `"6.40.0"`.
|
|
459
|
+
return bound?.replace(/^"|"$/g, '');
|
|
457
460
|
};
|
|
458
461
|
/** Sync vended provider versions in every `.tf` file. */ const syncTerraformProviders = async (tree)=>{
|
|
459
462
|
const updated = [];
|
|
@@ -478,6 +481,16 @@ const syncOverrides = (tree, owned)=>{
|
|
|
478
481
|
}
|
|
479
482
|
return updated;
|
|
480
483
|
};
|
|
484
|
+
/**
|
|
485
|
+
* The projects this plugin generates infrastructure into, per provider.
|
|
486
|
+
*
|
|
487
|
+
* A runtime is not a dependency, so there is no per-package ownership to consult —
|
|
488
|
+
* these directories are the scope. A Lambda a user defined in their own project
|
|
489
|
+
* keeps whatever runtime they chose, even though it is the same shape.
|
|
490
|
+
*/ const OWNED_INFRA_DIRS = {
|
|
491
|
+
cdk: `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}`,
|
|
492
|
+
terraform: `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}`
|
|
493
|
+
};
|
|
481
494
|
/**
|
|
482
495
|
* Sync the versions this release vends, for the dependencies the workspace's
|
|
483
496
|
* generators own.
|
|
@@ -489,6 +502,9 @@ const syncOverrides = (tree, owned)=>{
|
|
|
489
502
|
const overrides = syncOverrides(tree, owned);
|
|
490
503
|
const pyProjects = syncPyProjects(tree, owned);
|
|
491
504
|
const terraformFiles = await syncTerraformProviders(tree);
|
|
505
|
+
const lambdaRuntimes = await syncLambdaRuntimes(tree, OWNED_INFRA_DIRS);
|
|
506
|
+
const projectPython = syncProjectPythonVersion(tree);
|
|
507
|
+
const pythonBundles = syncPythonBundleVersion(tree);
|
|
492
508
|
const skippedEmbedded = await syncEmbeddedVersions(tree, owned);
|
|
493
509
|
await syncMetricsVersion(tree);
|
|
494
510
|
// Lock files are left to the user: `nx migrate` only installs when the root
|
|
@@ -496,8 +512,21 @@ const syncOverrides = (tree, owned)=>{
|
|
|
496
512
|
if (catalogs.length > 0 || packageJsons.length > 0 || overrides.length > 0) {
|
|
497
513
|
nextSteps.push(`TypeScript dependency versions were updated. Run \`${buildInstallCommand(detectPackageManager(tree.root))}\` to update the lock file.`);
|
|
498
514
|
}
|
|
499
|
-
if (pyProjects.length > 0) {
|
|
500
|
-
nextSteps.push(`Python dependency versions were updated in ${
|
|
515
|
+
if (pyProjects.length > 0 || projectPython.length > 0 || pythonBundles.length > 0) {
|
|
516
|
+
nextSteps.push(`Python dependency versions were updated in ${[
|
|
517
|
+
...new Set([
|
|
518
|
+
...pyProjects,
|
|
519
|
+
...projectPython,
|
|
520
|
+
...pythonBundles
|
|
521
|
+
])
|
|
522
|
+
].join(', ')}. Run \`uv sync\` to update uv.lock.`);
|
|
523
|
+
}
|
|
524
|
+
// A runtime the sync recognised is simply moved; one it doesn't recognise is
|
|
525
|
+
// the user's choice, so it is reported rather than rewritten.
|
|
526
|
+
if (lambdaRuntimes.diverged.length > 0) {
|
|
527
|
+
nextSteps.push(`Lambda runtimes in ${[
|
|
528
|
+
...new Set(lambdaRuntimes.diverged)
|
|
529
|
+
].join(', ')} have diverged from the generated shape and were left untouched. Set them to \`${cdkLambdaRuntime('node')}\` (CDK) or \`"${terraformLambdaRuntime('node')}"\` (Terraform) if you want them on the runtime this release vends.`);
|
|
501
530
|
}
|
|
502
531
|
if (terraformFiles.length > 0) {
|
|
503
532
|
nextSteps.push(`Terraform provider versions were updated in ${terraformFiles.length} file(s). Run \`terraform init -upgrade\` in each Terraform project to update its lock file.`);
|