diff --git a/packages/aws-cdk/lib/archive.ts b/packages/aws-cdk/lib/archive.ts index c924035bca369..9b7272ed668f2 100644 --- a/packages/aws-cdk/lib/archive.ts +++ b/packages/aws-cdk/lib/archive.ts @@ -1,23 +1,39 @@ import archiver = require('archiver'); import crypto = require('crypto'); import fs = require('fs-extra'); +import glob = require('glob'); +import path = require('path'); export function zipDirectory(directory: string, outputFile: string): Promise { return new Promise((ok, fail) => { const output = fs.createWriteStream(outputFile); const archive = archiver('zip'); + // The below options are needed to support following symlinks when building zip files: - // - nodir: This will prevent symlinks themselves from being copied into the zip. + // - nodir: This will prevent symlinks themselves from being copied into the zip. // - follow: This will follow symlinks and copy the files within. const globOptions = { dot: true, nodir: true, follow: true, - cwd: directory + cwd: directory, }; - archive.glob('**', globOptions); - archive.pipe(output); - archive.finalize(); + const files = glob.sync('**', globOptions); // The output here is already sorted + + output.on('open', async () => { + archive.pipe(output); + + await files.reduce(async (acc, file) => { // Append files serially to ensure file order + await acc; + const data = await fs.readFile(path.join(directory, file)); + archive.append(data, { + name: file, + date: new Date(0), // reset dates to get the same hash for the same content + }); + }, Promise.resolve()); + + archive.finalize(); + }); archive.on('warning', fail); archive.on('error', fail); diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index 07ef895d4d465..589eb6ca98399 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -60,6 +60,7 @@ "colors": "^1.3.3", "decamelize": "^3.2.0", "fs-extra": "^8.0.1", + "glob": "^7.1.4", "json-diff": "^0.5.4", "minimatch": ">=3.0", "promptly": "^3.0.3",