Skip to content

Commit f2294ba

Browse files
authored
fix(core): output folder checksum is computed unnecessarily (#25392)
The output folder checksum is being at least once in every synthesis. This is only necessary if a validation plugin was registered. Also reusing the `FileSystem.fingerprint()` function while I'm at it. Fixes #25286 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 53d24f1 commit f2294ba

File tree

2 files changed

+19
-18
lines changed

2 files changed

+19
-18
lines changed

packages/aws-cdk-lib/core/lib/private/synthesis.ts

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { createHash } from 'crypto';
21
import * as fs from 'fs';
32
import * as path from 'path';
43
import * as cxapi from '../../../cx-api';
@@ -16,6 +15,7 @@ import { Stage, StageSynthesisOptions } from '../stage';
1615
import { IPolicyValidationPluginBeta1 } from '../validation';
1716
import { ConstructTree } from '../validation/private/construct-tree';
1817
import { PolicyValidationReportFormatter, NamedValidationPluginReport } from '../validation/private/report';
18+
import { FileSystem } from '../fs';
1919

2020
const POLICY_VALIDATION_FILE_PATH = 'policy-validation-report.json';
2121
const VALIDATION_REPORT_JSON_CONTEXT = '@aws-cdk/core:validationReportJson';
@@ -90,7 +90,7 @@ function getAssemblies(root: App, rootAssembly: CloudAssembly): Map<string, Clou
9090
*/
9191
function invokeValidationPlugins(root: IConstruct, outdir: string, assembly: CloudAssembly) {
9292
if (!App.isApp(root)) return;
93-
const hash = computeChecksumOfFolder(outdir);
93+
let hash: string | undefined;
9494
const assemblies = getAssemblies(root, assembly);
9595
const templatePathsByPlugin: Map<IPolicyValidationPluginBeta1, string[]> = new Map();
9696
visitAssemblies(root, 'post', construct => {
@@ -111,6 +111,11 @@ function invokeValidationPlugins(root: IConstruct, outdir: string, assembly: Clo
111111
// eslint-disable-next-line no-console
112112
console.log('Performing Policy Validations\n');
113113
}
114+
115+
if (templatePathsByPlugin.size > 0) {
116+
hash = FileSystem.fingerprint(outdir);
117+
}
118+
114119
for (const [plugin, paths] of templatePathsByPlugin.entries()) {
115120
try {
116121
const report = plugin.validate({ templatePaths: paths });
@@ -126,7 +131,7 @@ function invokeValidationPlugins(root: IConstruct, outdir: string, assembly: Clo
126131
},
127132
});
128133
}
129-
if (computeChecksumOfFolder(outdir) !== hash) {
134+
if (FileSystem.fingerprint(outdir) !== hash) {
130135
throw new Error(`Illegal operation: validation plugin '${plugin.name}' modified the cloud assembly`);
131136
}
132137
}
@@ -162,21 +167,6 @@ function invokeValidationPlugins(root: IConstruct, outdir: string, assembly: Clo
162167
}
163168
}
164169

165-
function computeChecksumOfFolder(folder: string): string {
166-
const hash = createHash('sha256');
167-
const files = fs.readdirSync(folder, { withFileTypes: true });
168-
169-
for (const file of files) {
170-
const fullPath = path.join(folder, file.name);
171-
if (file.isDirectory()) {
172-
hash.update(computeChecksumOfFolder(fullPath));
173-
} else if (file.isFile()) {
174-
hash.update(fs.readFileSync(fullPath));
175-
}
176-
}
177-
return hash.digest().toString('hex');
178-
}
179-
180170
const CUSTOM_SYNTHESIS_SYM = Symbol.for('@aws-cdk/core:customSynthesis');
181171

182172
/**

packages/aws-cdk-lib/core/test/synthesis.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,17 @@ describe('synthesis', () => {
272272
expect(stack.parameters).toEqual({ paramId: 'paramValue', paramId2: 'paramValue2' });
273273
expect(stack.environment).toEqual({ region: 'us-east-1', account: 'unknown-account', name: 'aws://unknown-account/us-east-1' });
274274
});
275+
276+
test('output folder checksum is not computed by default', () => {
277+
const fingerprint = jest.spyOn(cdk.FileSystem, 'fingerprint');
278+
const app = new cdk.App(); // <-- no validation plugins
279+
const stack = new cdk.Stack(app, 'one-stack');
280+
synthesize(stack);
281+
282+
expect(fingerprint).not.toHaveBeenCalled();
283+
284+
jest.restoreAllMocks();
285+
});
275286
});
276287

277288
function list(outdir: string) {

0 commit comments

Comments
 (0)