From ef69599343072257e46eb08b638f9565540d367e Mon Sep 17 00:00:00 2001 From: Matthew Cane Date: Mon, 9 Jun 2025 17:07:56 +0100 Subject: [PATCH 1/3] add chartName option to synth command when synth format is Helm Signed-off-by: Matthew Cane --- src/cli/cmds/synth.ts | 10 ++++++---- src/config.ts | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/cli/cmds/synth.ts b/src/cli/cmds/synth.ts index 223d0aad9..97efbebfb 100644 --- a/src/cli/cmds/synth.ts +++ b/src/cli/cmds/synth.ts @@ -32,7 +32,8 @@ class Command implements yargs.CommandModule { .option('validation-reports-output-file', { required: false, desc: 'File to write a JSON representation of the validation reports to' }) .option('format', { required: false, desc: 'Synthesis format for Kubernetes manifests. The default synthesis format is plain kubernetes manifests.', type: 'string' }) .option('chart-api-version', { required: false, desc: 'Chart API version of helm chart. The default value would be \'v2\' api version when synthesis format is helm. There is no default set when synthesis format is plain.', type: 'string' }) - .option('chart-version', { required: false, desc: 'Chart version of helm chart. This is required if synthesis format is helm.' }); + .option('chart-version', { required: false, desc: 'Chart version of helm chart. This is required if synthesis format is helm.' }) + .option('chart-name', { required: false, desc: 'Chart name of helm chart. Use when synthesis format is helm. The default is the applications base directory name.' }); public async handler(argv: any) { @@ -45,6 +46,7 @@ class Command implements yargs.CommandModule { const format = argv.format ?? config?.synthConfig?.format ?? SynthesisFormat.PLAIN; const chartVersion = argv.chartVersion ?? config?.synthConfig?.chartVersion; const chartApiVersion = argv.chartApiVersion ?? config?.synthConfig?.chartApiVersion ?? getDefaultChartApiVersion(format); + const chartName = argv.chartName ?? config?.synthConfig?.chartName ?? path.basename(path.resolve()); if (outdir && outdir !== config?.output && stdout) { throw new Error('\'--output\' and \'--stdout\' are mutually exclusive. Please only use one.'); @@ -104,7 +106,7 @@ class Command implements yargs.CommandModule { let manifests: SynthesizedApp; if (format === SynthesisFormat.HELM) { - await createHelmScaffolding(chartApiVersion, chartVersion, outdir); + await createHelmScaffolding(chartApiVersion, chartVersion, chartName, outdir); const templateDir = path.join(outdir, 'templates'); manifests = await synthApp(command, templateDir, stdout, recordConstructMetadata); @@ -130,13 +132,13 @@ async function fetchValidations(): Promise { } } -async function createHelmScaffolding(apiVersion: string, chartVersion: string, outdir: string) { +async function createHelmScaffolding(apiVersion: string, chartVersion: string, chartName: string, outdir: string) { const tempHelmStructure = createFolderStructure(); const substituteValues = { apiVersion: apiVersion, version: chartVersion, - app: path.basename(path.resolve()), + app: chartName, }; try { diff --git a/src/config.ts b/src/config.ts index 512d6275e..a8dfbd028 100644 --- a/src/config.ts +++ b/src/config.ts @@ -31,6 +31,7 @@ export interface SynthConfig { readonly format?: SynthesisFormat; readonly chartApiVersion?: HelmChartApiVersion; readonly chartVersion?: string; + readonly chartName?: string; } export interface Config { From d8cae2a08a67927bc79befa0f341b56883b24aa5 Mon Sep 17 00:00:00 2001 From: Matthew Cane Date: Tue, 10 Jun 2025 10:50:46 +0100 Subject: [PATCH 2/3] Add tests for Helm synthesis with chart-name option Signed-off-by: Matthew Cane --- .../__snapshots__/synth-stdout.test.ts.snap | 136 ++++++++++++++++++ test/synth/synth-stdout.test.ts | 112 +++++++++++++++ 2 files changed, 248 insertions(+) diff --git a/test/synth/__snapshots__/synth-stdout.test.ts.snap b/test/synth/__snapshots__/synth-stdout.test.ts.snap index bdc3cdfb2..9a061b99c 100644 --- a/test/synth/__snapshots__/synth-stdout.test.ts.snap +++ b/test/synth/__snapshots__/synth-stdout.test.ts.snap @@ -16104,6 +16104,142 @@ metadata: } `; +exports[`Helm synthesis --chart-name is used when specified with all inputs from cli and no config file is present 1`] = ` +Object { + "Chart.yaml": "apiVersion: \\"v2\\" +name: \\"cdk8s-synth-test\\" +version: \\"1.1.1\\" +description: Generated chart for cdk8s-synth-test +type: application +", + "README.md": "This Helm chart is generated using cdk8s. Any manual changes to the chart would be discarded once cdk8s app is synthesized again with \`--format helm\`.", + "templates/chart-c86185a7.k8s.yaml": "apiVersion: v1 +kind: ConfigMap +metadata: + name: config-map +", +} +`; + +exports[`Helm synthesis --chart-name is used when specified with all inputs from config file and no related cli inputs 1`] = ` +Object { + "Chart.yaml": "apiVersion: \\"v2\\" +name: \\"custom-chart-name\\" +version: \\"1.1.1\\" +description: Generated chart for custom-chart-name +type: application +", + "README.md": "This Helm chart is generated using cdk8s. Any manual changes to the chart would be discarded once cdk8s app is synthesized again with \`--format helm\`.", + "templates/chart-c86185a7.k8s.yaml": "apiVersion: v1 +kind: ConfigMap +metadata: + name: config-map +", +} +`; + +exports[`Helm synthesis --chart-name is used when specified with different inputs in cli and config file 1`] = ` +Object { + "Chart.yaml": "apiVersion: \\"v2\\" +name: \\"config-chart-name\\" +version: \\"1.1.1\\" +description: Generated chart for config-chart-name +type: application +", + "README.md": "This Helm chart is generated using cdk8s. Any manual changes to the chart would be discarded once cdk8s app is synthesized again with \`--format helm\`.", + "templates/chart-c86185a7.k8s.yaml": "apiVersion: v1 +kind: ConfigMap +metadata: + name: config-map +", +} +`; + +exports[`Helm synthesis --chart-name is used when specified with inputs duplicated in cli and config file 1`] = ` +Object { + "Chart.yaml": "apiVersion: \\"v2\\" +name: \\"custom-chart-name\\" +version: \\"1.1.1\\" +description: Generated chart for custom-chart-name +type: application +", + "README.md": "This Helm chart is generated using cdk8s. Any manual changes to the chart would be discarded once cdk8s app is synthesized again with \`--format helm\`.", + "templates/chart-c86185a7.k8s.yaml": "apiVersion: v1 +kind: ConfigMap +metadata: + name: config-map +", +} +`; + +exports[`Helm synthesis default chart name is used when --chart-name is not specified with all inputs from cli and no config file is present 1`] = ` +Object { + "Chart.yaml": "apiVersion: \\"v2\\" +name: \\"cdk8s-synth-test\\" +version: \\"1.1.1\\" +description: Generated chart for cdk8s-synth-test +type: application +", + "README.md": "This Helm chart is generated using cdk8s. Any manual changes to the chart would be discarded once cdk8s app is synthesized again with \`--format helm\`.", + "templates/chart-c86185a7.k8s.yaml": "apiVersion: v1 +kind: ConfigMap +metadata: + name: config-map +", +} +`; + +exports[`Helm synthesis default chart name is used when --chart-name is not specified with all inputs from config file and no related cli inputs 1`] = ` +Object { + "Chart.yaml": "apiVersion: \\"v2\\" +name: \\"cdk8s-synth-test\\" +version: \\"1.1.1\\" +description: Generated chart for cdk8s-synth-test +type: application +", + "README.md": "This Helm chart is generated using cdk8s. Any manual changes to the chart would be discarded once cdk8s app is synthesized again with \`--format helm\`.", + "templates/chart-c86185a7.k8s.yaml": "apiVersion: v1 +kind: ConfigMap +metadata: + name: config-map +", +} +`; + +exports[`Helm synthesis default chart name is used when --chart-name is not specified with different inputs in cli and config file 1`] = ` +Object { + "Chart.yaml": "apiVersion: \\"v2\\" +name: \\"cdk8s-synth-test\\" +version: \\"1.1.1\\" +description: Generated chart for cdk8s-synth-test +type: application +", + "README.md": "This Helm chart is generated using cdk8s. Any manual changes to the chart would be discarded once cdk8s app is synthesized again with \`--format helm\`.", + "templates/chart-c86185a7.k8s.yaml": "apiVersion: v1 +kind: ConfigMap +metadata: + name: config-map +", +} +`; + +exports[`Helm synthesis default chart name is used when --chart-name is not specified with inputs duplicated in cli and config file 1`] = ` +Object { + "Chart.yaml": "apiVersion: \\"v2\\" +name: \\"cdk8s-synth-test\\" +version: \\"1.1.1\\" +description: Generated chart for cdk8s-synth-test +type: application +", + "README.md": "This Helm chart is generated using cdk8s. Any manual changes to the chart would be discarded once cdk8s app is synthesized again with \`--format helm\`.", + "templates/chart-c86185a7.k8s.yaml": "apiVersion: v1 +kind: ConfigMap +metadata: + name: config-map +", +} +`; + exports[`Helm synthesis filename url hash remains the same across synthesis with all inputs from cli and no config file is present 1`] = ` Object { "Chart.yaml": "apiVersion: \\"v2\\" diff --git a/test/synth/synth-stdout.test.ts b/test/synth/synth-stdout.test.ts index fb32b5a36..f99405f03 100644 --- a/test/synth/synth-stdout.test.ts +++ b/test/synth/synth-stdout.test.ts @@ -1009,6 +1009,118 @@ describe('Helm synthesis', () => { // This would be run 4 times with test.each await synth(synthOptions); }); + + test.each([ + [ + withOnlyCliInputs, + { + format: SynthesisFormat.HELM, + chartVersion: '1.1.1', + chartName: 'custom-chart-name', + postSynth: matchSynthSnapshot, + }, + ], + [ + withOnlyConfigInputs, + { + config: { + synthConfig: { + format: SynthesisFormat.HELM, + chartVersion: '1.1.1', + chartName: 'custom-chart-name', + }, + }, + postSynth: matchSynthSnapshot, + }, + ], + [ + withSameInputsInBoth, + { + format: SynthesisFormat.HELM, + chartVersion: '1.1.1', + chartName: 'custom-chart-name', + config: { + synthConfig: { + format: SynthesisFormat.HELM, + chartVersion: '1.1.1', + chartName: 'custom-chart-name', + }, + }, + postSynth: matchSynthSnapshot, + }, + ], + [ + withDifferentInputsInBoth, + { + format: SynthesisFormat.HELM, + chartVersion: '1.1.1', + chartName: 'cli-chart-name', + config: { + synthConfig: { + format: SynthesisFormat.HELM, + chartVersion: '1.1.1', + chartName: 'config-chart-name', + }, + }, + postSynth: matchSynthSnapshot, + }, + ], + ])('--chart-name is used when specified %s', async (_testName, synthOptions) => { + await synth(synthOptions); + }); + + test.each([ + [ + withOnlyCliInputs, + { + format: SynthesisFormat.HELM, + chartVersion: '1.1.1', + postSynth: matchSynthSnapshot, + }, + ], + [ + withOnlyConfigInputs, + { + config: { + synthConfig: { + format: SynthesisFormat.HELM, + chartVersion: '1.1.1', + }, + }, + postSynth: matchSynthSnapshot, + }, + ], + [ + withSameInputsInBoth, + { + format: SynthesisFormat.HELM, + chartVersion: '1.1.1', + config: { + synthConfig: { + format: SynthesisFormat.HELM, + chartVersion: '1.1.1', + }, + }, + postSynth: matchSynthSnapshot, + }, + ], + [ + withDifferentInputsInBoth, + { + format: SynthesisFormat.HELM, + chartVersion: '1.1.1', + config: { + synthConfig: { + format: SynthesisFormat.PLAIN, + chartVersion: '1.1.1', + }, + }, + postSynth: matchSynthSnapshot, + }, + ], + ])('default chart name is used when --chart-name is not specified %s', async (_testName, synthOptions) => { + await synth(synthOptions); + }); }); interface SynthCliOptions { From b7e82105377f38d4f3dc6addc703ad9a9c524da0 Mon Sep 17 00:00:00 2001 From: Matthew Cane Date: Wed, 2 Jul 2025 12:11:45 +0100 Subject: [PATCH 3/3] Add custom chart name to Helm synthesis test configuration Signed-off-by: Matthew Cane --- test/synth/synth-stdout.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/synth/synth-stdout.test.ts b/test/synth/synth-stdout.test.ts index f99405f03..998152074 100644 --- a/test/synth/synth-stdout.test.ts +++ b/test/synth/synth-stdout.test.ts @@ -1085,6 +1085,7 @@ describe('Helm synthesis', () => { synthConfig: { format: SynthesisFormat.HELM, chartVersion: '1.1.1', + chartName: 'custom-chart-name', }, }, postSynth: matchSynthSnapshot,