diff --git a/.github/workflows/cdktf-provider-docs-rollout.yml b/.github/workflows/cdktf-provider-docs-rollout.yml index 2b1f909061..962dbbadc8 100644 --- a/.github/workflows/cdktf-provider-docs-rollout.yml +++ b/.github/workflows/cdktf-provider-docs-rollout.yml @@ -47,7 +47,7 @@ jobs: languages: "typescript,python" parallelFileConversions: 1 maxRunners: 20 - cdktfRegistryDocsVersion: "1.20.0" + cdktfRegistryDocsVersion: "1.21.0" reportFailureToSlack: needs: cdktfDocs diff --git a/.github/workflows/registry-docs-pr-based.yml b/.github/workflows/registry-docs-pr-based.yml index 7357b1e552..45632f7f6c 100644 --- a/.github/workflows/registry-docs-pr-based.yml +++ b/.github/workflows/registry-docs-pr-based.yml @@ -53,7 +53,7 @@ on: cdktfRegistryDocsVersion: description: "Version of cdktf-registry-docs to use" required: false - default: "1.20.0" + default: "1.21.0" type: string secrets: GH_PR_TOKEN: diff --git a/.github/workflows/yarn-upgrade.yml b/.github/workflows/yarn-upgrade.yml index 6a374664ed..0fffaa9f59 100644 --- a/.github/workflows/yarn-upgrade.yml +++ b/.github/workflows/yarn-upgrade.yml @@ -85,7 +85,7 @@ jobs: run: '[ -s ./upgrade.patch ] && git apply ./upgrade.patch || echo "Empty patch. Skipping."' - name: Remove patch file - run: '[ -s ./upgrade.patch ] && rm ./upgrade.patch || echo "Empty patch. Skipping."' + run: rm -f ./upgrade.patch - name: Make Pull Request uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38 # v5.0.2 diff --git a/CHANGELOG.md b/CHANGELOG.md index ffe5aade77..61f3203684 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,30 @@ +## 0.20.1 + +**AWS Provider changes (breaking)** + +The AWS pre-built provider for Go is currently too large to be installed due to a hard limit in Go. This release adds skipping the `statement` block in the `rule` block of the `aws_wafv2_web_acl` and `aws_wafv2_rule_group` resources. Our [resource docs page](https://developer.hashicorp.com/terraform/cdktf/concepts/resources#special-cases) previously already mentioned that these resources have skipped attributes but they weren't actually skipped. This almost doubled AWS provider bindings in size due to the recursive nature of the `statement` block. +If you are using any of these two resources, the `statement` now has to be passed as a plain object instead and its keys have to be snake-cased (e.g. `and_statement` or `regex_match_statement`). + +### feat + +- feat(hcl2cdk): support import blocks in cdktf convert [\#3415](https://github.com/hashicorp/terraform-cdk/pull/3415) + +### fix + +- fix(provider-generator): Skip `statement` block for `rule` block in `aws_wafv2_web_acl` and `aws_wafv2_rule_group` resources [\#3414](https://github.com/hashicorp/terraform-cdk/pull/3414) +- fix(cli): Fix version range matching for 0.x version ranges with the ~> operator [\#3403](https://github.com/hashicorp/terraform-cdk/pull/3403) +- fix(docs): fix complex iterator example [\#3410](https://github.com/hashicorp/terraform-cdk/pull/3410) +- fix(docs): product relative links [\#3401](https://github.com/hashicorp/terraform-cdk/pull/3401) + +### chore + +- chore: Upgrade dependencies for @cdktf/provider-generator [\#3423](https://github.com/hashicorp/terraform-cdk/pull/3423) +- chore: break loop properly [\#3413](https://github.com/hashicorp/terraform-cdk/pull/3413) +- chore: abort rebase when retrying pushing doc updates [\#3412](https://github.com/hashicorp/terraform-cdk/pull/3412) +- chore: update registry docs tool [\#3407](https://github.com/hashicorp/terraform-cdk/pull/3407) +- chore: update registry docs tool [\#3406](https://github.com/hashicorp/terraform-cdk/pull/3406) +- chore: update provider docs tool [\#3404](https://github.com/hashicorp/terraform-cdk/pull/3404) + ## 0.20.0 **Breaking changes** diff --git a/cdk.tf/vercel.json b/cdk.tf/vercel.json index c865e4eebb..9cb32d8533 100644 --- a/cdk.tf/vercel.json +++ b/cdk.tf/vercel.json @@ -218,6 +218,11 @@ "destination": "https://developer.hashicorp.com/terraform/cdktf/concepts/modules#configure-modules", "permanent": false }, + { + "source": "/adding-modules", + "destination": "https://developer.hashicorp.com/terraform/cdktf/concepts/modules#add-module-to-cdktf-json", + "permanent": false + }, { "source": "/registry-providers", "destination": "https://registry.terraform.io/browse/providers", diff --git a/package.json b/package.json index 3a19a6b7f6..d74d2a88c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "0.20.0", + "version": "0.20.1", "private": true, "scripts": { "build-and-package": "lerna run --scope 'cdktf*' --scope @cdktf/* build,package && tools/collect-dist.sh", diff --git a/packages/@cdktf/cli-core/ambient.d.ts b/packages/@cdktf/cli-core/ambient.d.ts index b6d6868c78..29ff9faf5b 100644 --- a/packages/@cdktf/cli-core/ambient.d.ts +++ b/packages/@cdktf/cli-core/ambient.d.ts @@ -9,4 +9,5 @@ declare module 'child_process' { } } -declare module 'tunnel-agent'; \ No newline at end of file +declare module 'tunnel-agent'; +declare module "archiver"; diff --git a/packages/@cdktf/commons/ambient.d.ts b/packages/@cdktf/commons/ambient.d.ts index b6d6868c78..87b761f0fe 100644 --- a/packages/@cdktf/commons/ambient.d.ts +++ b/packages/@cdktf/commons/ambient.d.ts @@ -9,4 +9,6 @@ declare module 'child_process' { } } -declare module 'tunnel-agent'; \ No newline at end of file +declare module 'tunnel-agent'; + +declare module "archiver"; \ No newline at end of file diff --git a/packages/@cdktf/commons/package.json b/packages/@cdktf/commons/package.json index 8c0ad4662d..84f080fd62 100644 --- a/packages/@cdktf/commons/package.json +++ b/packages/@cdktf/commons/package.json @@ -37,12 +37,12 @@ ], "license": "MPL-2.0", "dependencies": { - "@sentry/node": "7.92.0", + "@sentry/node": "7.93.0", "cdktf": "0.0.0", "ci-info": "3.9.0", - "codemaker": "1.93.0", + "codemaker": "1.94.0", "cross-spawn": "7.0.3", - "follow-redirects": "1.15.4", + "follow-redirects": "1.15.5", "fs-extra": "11.2.0", "is-valid-domain": "0.1.6", "log4js": "6.9.1", diff --git a/packages/@cdktf/commons/tsconfig.json b/packages/@cdktf/commons/tsconfig.json index 00f55b2a10..d15cbbbbfe 100644 --- a/packages/@cdktf/commons/tsconfig.json +++ b/packages/@cdktf/commons/tsconfig.json @@ -38,6 +38,7 @@ "exclude": [ "node_modules", "../../node_modules/**", + "../../cdktf/**", "**/*.d.ts", "**/*.test.tsx" ], diff --git a/packages/@cdktf/hcl2cdk/ambient.d.ts b/packages/@cdktf/hcl2cdk/ambient.d.ts index 94e9a93d4c..680f3bb1c4 100644 --- a/packages/@cdktf/hcl2cdk/ambient.d.ts +++ b/packages/@cdktf/hcl2cdk/ambient.d.ts @@ -10,4 +10,5 @@ declare module 'child_process' { } declare module 'tunnel-agent'; -declare module 'deep-equal'; \ No newline at end of file +declare module 'deep-equal'; +declare module "archiver"; diff --git a/packages/@cdktf/provider-generator/ambient.d.ts b/packages/@cdktf/provider-generator/ambient.d.ts index b6d6868c78..29ff9faf5b 100644 --- a/packages/@cdktf/provider-generator/ambient.d.ts +++ b/packages/@cdktf/provider-generator/ambient.d.ts @@ -9,4 +9,5 @@ declare module 'child_process' { } } -declare module 'tunnel-agent'; \ No newline at end of file +declare module 'tunnel-agent'; +declare module "archiver"; diff --git a/packages/@cdktf/provider-generator/package.json b/packages/@cdktf/provider-generator/package.json index 7a0c4f22f4..6bd8126cbd 100644 --- a/packages/@cdktf/provider-generator/package.json +++ b/packages/@cdktf/provider-generator/package.json @@ -36,11 +36,11 @@ "dependencies": { "@cdktf/commons": "0.0.0", "@cdktf/provider-schema": "0.0.0", - "@types/node": "18.19.5", - "codemaker": "1.93.0", + "@types/node": "18.19.7", + "codemaker": "1.94.0", "fs-extra": "8.1.0", "glob": "10.3.10", - "jsii-srcmak": "0.1.999" + "jsii-srcmak": "0.1.1005" }, "devDependencies": { "@types/deepmerge": "2.2.0", diff --git a/packages/@cdktf/provider-schema/ambient.d.ts b/packages/@cdktf/provider-schema/ambient.d.ts index 3f93f46752..a6eb2ccdbd 100644 --- a/packages/@cdktf/provider-schema/ambient.d.ts +++ b/packages/@cdktf/provider-schema/ambient.d.ts @@ -6,3 +6,5 @@ declare module 'child_process' { signal?: AbortSignal; } } + +declare module "archiver"; diff --git a/packages/@cdktf/provider-schema/src/read.ts b/packages/@cdktf/provider-schema/src/read.ts index 1a5e0188ab..9968cfb290 100644 --- a/packages/@cdktf/provider-schema/src/read.ts +++ b/packages/@cdktf/provider-schema/src/read.ts @@ -13,6 +13,8 @@ import { TerraformDependencyConstraint, LANGUAGES, ConstructsMakerProviderTarget, + ConstructsMakerModuleTarget, + Errors, } from "@cdktf/commons"; import deepmerge from "deepmerge"; import { readModuleSchema, readProviderSchema } from "./provider-schema"; @@ -31,6 +33,9 @@ export async function readSchema( const targets = constraints.map((constraint) => ConstructsMakerProviderTarget.from(constraint, LANGUAGES[0]) ); + + throwIfTargetsConflict(targets); + const schemas = await Promise.all( targets.map((t) => t.isModule @@ -53,3 +58,21 @@ export async function readSchema( return deepmerge.all(schemas); } + +function throwIfTargetsConflict( + targets: (ConstructsMakerProviderTarget | ConstructsMakerModuleTarget)[] +) { + const modules = targets.filter( + (t) => t.isModule + ) as ConstructsMakerModuleTarget[]; + + modules.forEach((moduleA) => { + modules.forEach((moduleB) => { + if (moduleA !== moduleB && moduleA.name === moduleB.name) { + throw Errors.Usage( + `Found two modules with the same name "${moduleA.name}" which is not supported. Please rename one of the modules in your cdktf.json config. For more information on how to set the name refer to https://cdk.tf/adding-modules` + ); + } + }); + }); +} diff --git a/packages/cdktf-cli/ambient.d.ts b/packages/cdktf-cli/ambient.d.ts index b6d6868c78..29ff9faf5b 100644 --- a/packages/cdktf-cli/ambient.d.ts +++ b/packages/cdktf-cli/ambient.d.ts @@ -9,4 +9,5 @@ declare module 'child_process' { } } -declare module 'tunnel-agent'; \ No newline at end of file +declare module 'tunnel-agent'; +declare module "archiver"; diff --git a/packages/cdktf-cli/src/bin/cmds/handlers.ts b/packages/cdktf-cli/src/bin/cmds/handlers.ts index 11509b591e..fd5dc23362 100644 --- a/packages/cdktf-cli/src/bin/cmds/handlers.ts +++ b/packages/cdktf-cli/src/bin/cmds/handlers.ts @@ -65,6 +65,7 @@ import path from "path"; import os from "os"; import { readPackageJson, projectRootPath } from "./helper/utilities"; import { readSchema } from "@cdktf/provider-schema"; +import { editor } from "@inquirer/prompts"; const chalkColour = new chalk.Instance(); const config = readConfigSync(); @@ -109,10 +110,24 @@ export async function convert({ experimentalProviderSchemaCachePath ); - const input = await readStreamAsString( - process.stdin, - "No stdin was passed, please use it like this: cat main.tf | cdktf convert > imported.ts" - ); + let input: string | undefined = undefined; + try { + input = await readStreamAsString(process.stdin); + } catch (e) { + logger.debug(`No TTY stream passed to convert, using interactive input`); + try { + input = await editor({ + message: + "Enter your Terrafrom code to convert to cdktf (or run the command again and pass it as stdin):", + postfix: ".tf", + waitForUseInput: true, + }); + } catch (err) { + throw Errors.Usage( + "No Terraform code to convert was provided. Please provide Terraform code to convert as stdin or run the command again and let the CLI open the editor." + ); + } + } const needsProject = language !== "typescript"; @@ -128,7 +143,7 @@ export async function convert({ logger.setLevel("ERROR"); await init({ template: "typescript", - providers: provider, + providers: provider || [], projectName: path.basename(tempDir), projectDescription: "Temporary project for conversion", local: true, @@ -137,6 +152,7 @@ export async function convert({ dist: pkg.version === "0.0.0" ? dist : undefined, cdktfVersion: pkg.version, silent: true, + nonInteractive: true, }); logger.useDefaultLevel(); } @@ -401,7 +417,7 @@ export async function login(argv: { tfeHostname: string }) { const terraformLogin = new TerraformLogin(argv.tfeHostname); let token = ""; try { - token = await readStreamAsString(process.stdin, "No stdin was passed"); + token = await readStreamAsString(process.stdin); } catch (e) { logger.debug(`No TTY stream passed to login`); } @@ -413,7 +429,7 @@ export async function login(argv: { tfeHostname: string }) { if (token) { await terraformLogin.saveTerraformCredentials(sanitizedToken); } else { - token = await terraformLogin.askToLogin(); + token = await terraformLogin.askToLogin(false); if (token === "") { throw Errors.Usage(`No Terraform Cloud token was provided.`); } diff --git a/packages/cdktf-cli/src/bin/cmds/helper/init.ts b/packages/cdktf-cli/src/bin/cmds/helper/init.ts index 4f9e769374..ed250e203b 100644 --- a/packages/cdktf-cli/src/bin/cmds/helper/init.ts +++ b/packages/cdktf-cli/src/bin/cmds/helper/init.ts @@ -80,6 +80,7 @@ type Options = { enableCrashReporting?: boolean; tfeHostname?: string; silent?: boolean; + nonInteractive?: boolean; }; export async function runInit(argv: Options) { @@ -93,7 +94,7 @@ export async function runInit(argv: Options) { // without a token and set up the project. const terraformLogin = new TerraformLogin(terraformRemoteHostname); - token = await terraformLogin.askToLogin(); + token = await terraformLogin.askToLogin(argv.nonInteractive ?? false); } else { if (!argv.silent) { console.log(chalkColour`{yellow Note: By supplying '--local' option you have chosen local storage mode for storing the state of your stack. @@ -116,9 +117,21 @@ This means that your Terraform state file will be stored locally on disk in a fi } // Gather information about the template and the project - const templateInfo = await getTemplate(template); + const templateInfo = await getTemplate( + template, + argv.nonInteractive ?? false + ); telemetryData.template = templateInfo.Name; + if (!argv.projectName && argv.nonInteractive) { + throw Errors.Usage( + "You are trying to initialize a project without specifying a project name in non-interactive mode. This can also happen when running cdktf convert against a project not using Typescript, since we need to create a temporary cdktf project for an accurate translation. If this happens using convert, please report it as a bug. Please specify a project name using the --project-name option." + ); + } + if (!argv.projectDescription && argv.nonInteractive) { + ("You are trying to initialize a project without specifying a project description in non-interactive mode. This can also happen when running cdktf convert against a project not using Typescript, since we need to create a temporary cdktf project for an accurate translation. If this happens using convert, please report it as a bug. Please specify a project name using the --project-description option."); + } + const { projectInfo, useTerraformCloud } = await gatherInfo( token, terraformRemoteHostname, @@ -131,7 +144,9 @@ This means that your Terraform state file will be stored locally on disk in a fi let fromTerraformProject = argv.fromTerraformProject || undefined; if (!fromTerraformProject) { if (templateInfo.Name === "typescript") { - fromTerraformProject = await getTerraformProject(); + fromTerraformProject = await getTerraformProject( + argv.nonInteractive ?? false + ); } } else if (fromTerraformProject === "no") { fromTerraformProject = undefined; @@ -159,9 +174,10 @@ This means that your Terraform state file will be stored locally on disk in a fi const sendCrashReports = argv.enableCrashReporting ?? (ci ? false : await askForCrashReportingConsent()); - const providers = argv.providers?.length - ? argv.providers - : await askForProviders(); + const providers = + argv.providers?.length || argv.nonInteractive + ? argv.providers + : await askForProviders(); let convertResult, importPath; if (fromTerraformProject) { @@ -422,8 +438,10 @@ You can create one here: https://${terraformRemoteHostname}/app/organizations/ne }; } -async function getTerraformProject(): Promise { - if (!isInteractiveTerminal()) { +async function getTerraformProject( + nonInteractive: boolean +): Promise { + if (!isInteractiveTerminal() || nonInteractive) { return Promise.resolve(undefined); } const shouldUseTerraformProject = await confirm({ @@ -461,8 +479,16 @@ async function getTerraformProject(): Promise { * * @param templateName either the name of built-in templates or an url pointing to a zip archive */ -async function getTemplate(templateName: string): Promise