@aws-cdk-testing/cli-integ 2.173.4 → 3.0.0
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/.eslintrc.js +9 -0
- package/LICENSE +2 -1
- package/bin/query-github.js +3 -3
- package/bin/query-github.ts +56 -0
- package/bin/run-suite.js +3 -3
- package/bin/run-suite.ts +140 -0
- package/bin/stage-distribution.js +3 -2
- package/bin/stage-distribution.ts +267 -0
- package/bin/test-root.ts +3 -0
- package/lib/aws.js +9 -6
- package/lib/aws.ts +263 -0
- package/lib/corking.ts +33 -0
- package/lib/eventually.js +3 -3
- package/lib/eventually.ts +42 -0
- package/lib/files.js +3 -2
- package/lib/files.ts +80 -0
- package/lib/github.js +6 -5
- package/lib/github.ts +43 -0
- package/lib/index.ts +13 -0
- package/lib/integ-test.ts +81 -0
- package/lib/lists.ts +9 -0
- package/lib/memoize.ts +14 -0
- package/lib/npm.ts +41 -0
- package/lib/package-sources/release-source.js +3 -2
- package/lib/package-sources/release-source.ts +81 -0
- package/lib/package-sources/repo-source.ts +111 -0
- package/lib/package-sources/repo-tools/npm.js +5 -4
- package/lib/package-sources/repo-tools/npm.ts +48 -0
- package/lib/package-sources/source.ts +35 -0
- package/lib/package-sources/subprocess.ts +15 -0
- package/lib/resource-pool.js +2 -2
- package/lib/resource-pool.ts +140 -0
- package/lib/resources.ts +4 -0
- package/lib/shell.js +8 -5
- package/lib/shell.ts +168 -0
- package/lib/staging/codeartifact.js +11 -8
- package/lib/staging/codeartifact.ts +387 -0
- package/lib/staging/maven.js +5 -3
- package/lib/staging/maven.ts +95 -0
- package/lib/staging/npm.ts +62 -0
- package/lib/staging/nuget.ts +75 -0
- package/lib/staging/parallel-shell.js +2 -2
- package/lib/staging/parallel-shell.ts +51 -0
- package/lib/staging/pypi.ts +50 -0
- package/lib/staging/usage-dir.ts +99 -0
- package/lib/with-aws.js +3 -2
- package/lib/with-aws.ts +67 -0
- package/lib/with-cdk-app.js +23 -14
- package/lib/with-cdk-app.ts +742 -0
- package/lib/with-cli-lib.ts +134 -0
- package/lib/with-packages.ts +15 -0
- package/lib/with-sam.js +7 -4
- package/lib/with-sam.ts +288 -0
- package/lib/with-temporary-directory.ts +35 -0
- package/lib/with-timeout.ts +33 -0
- package/lib/xpmutex.js +2 -2
- package/lib/xpmutex.ts +218 -0
- package/package.json +84 -62
- package/resources/cloud-assemblies/0.36.0/cdk.out +1 -0
- package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/cdk.out +1 -0
- package/resources/cloud-assemblies/1.10.0-request-azs/cdk.out +1 -0
- package/tests/cli-integ-tests/bootstrapping.integtest.js +22 -13
- package/tests/cli-integ-tests/bootstrapping.integtest.ts +493 -0
- package/tests/cli-integ-tests/cli-lib.integtest.js +3 -2
- package/tests/cli-integ-tests/cli-lib.integtest.ts +90 -0
- package/tests/cli-integ-tests/cli.integtest.js +76 -49
- package/tests/cli-integ-tests/cli.integtest.ts +2874 -0
- package/tests/cli-integ-tests/garbage-collection.integtest.js +2 -2
- package/tests/cli-integ-tests/garbage-collection.integtest.ts +392 -0
- package/tests/init-csharp/init-csharp.integtest.ts +15 -0
- package/tests/init-fsharp/init-fsharp.integtest.ts +15 -0
- package/tests/init-go/init-go.integtest.ts +23 -0
- package/tests/init-java/init-java.integtest.ts +14 -0
- package/tests/init-javascript/init-javascript.integtest.ts +59 -0
- package/tests/init-python/init-python.integtest.ts +20 -0
- package/tests/init-typescript-app/init-typescript-app.integtest.ts +66 -0
- package/tests/init-typescript-lib/init-typescript-lib.integtest.ts +13 -0
- package/tests/tool-integrations/amplify.integtest.ts +43 -0
- package/tests/tool-integrations/with-tool-context.ts +14 -0
- package/tests/uberpackage/uberpackage.integtest.ts +11 -0
- package/resources/cdk-apps/cfn-include-app/.gitignore +0 -1
|
@@ -20,7 +20,7 @@ async function parallelShell(inputs, block, swallowError) {
|
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
22
|
catch (e) {
|
|
23
|
-
switch (swallowError
|
|
23
|
+
switch (swallowError === null || swallowError === void 0 ? void 0 : swallowError(input, output.toString())) {
|
|
24
24
|
case 'skip':
|
|
25
25
|
return;
|
|
26
26
|
case 'retry':
|
|
@@ -42,4 +42,4 @@ async function parallelShell(inputs, block, swallowError) {
|
|
|
42
42
|
}));
|
|
43
43
|
await q.onEmpty();
|
|
44
44
|
}
|
|
45
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
45
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyYWxsZWwtc2hlbGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJwYXJhbGxlbC1zaGVsbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVNBLHNDQXlDQztBQWxERCxxQ0FBNkI7QUFDN0IsZ0NBQStCO0FBQy9CLHdDQUEwQztBQUkxQzs7R0FFRztBQUNJLEtBQUssVUFBVSxhQUFhLENBQ2pDLE1BQVcsRUFDWCxLQUE2RCxFQUM3RCxZQUFzRDtJQUV0RCx5RkFBeUY7SUFDekYsTUFBTSxDQUFDLEdBQUcsSUFBSSxpQkFBTSxDQUFDLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDN0UsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLElBQUksRUFBRTtRQUM1QyxJQUFJLFFBQVEsR0FBRyxFQUFFLENBQUM7UUFDbEIsSUFBSSxPQUFPLEdBQUcsR0FBRyxDQUFDO1FBQ2xCLE9BQU8sSUFBSSxFQUFFLENBQUM7WUFDWixNQUFNLE1BQU0sR0FBRyxJQUFJLHNCQUFZLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxLQUFLLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUMzQixPQUFPO1lBQ1QsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1gsUUFBUSxZQUFZLGFBQVosWUFBWSx1QkFBWixZQUFZLENBQUcsS0FBSyxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLENBQUM7b0JBQ2pELEtBQUssTUFBTTt3QkFDVCxPQUFPO29CQUVULEtBQUssT0FBTzt3QkFDVixJQUFJLEVBQUUsUUFBUSxHQUFHLENBQUMsRUFBRSxDQUFDOzRCQUNuQixNQUFNLElBQUEsV0FBSyxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUM7NEJBQ2pELE9BQU8sSUFBSSxDQUFDLENBQUM7NEJBQ2IsU0FBUzt3QkFDWCxDQUFDO3dCQUNELE1BQU07b0JBRVIsS0FBSyxNQUFNLENBQUM7b0JBQ1osS0FBSyxTQUFTO3dCQUNaLE1BQU07Z0JBQ1YsQ0FBQztnQkFFRCxzQ0FBc0M7Z0JBQ3RDLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7Z0JBQ2pDLE1BQU0sQ0FBQyxDQUFDO1lBQ1YsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRUosTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDcEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQUXVldWUgZnJvbSAncC1xdWV1ZSc7XG5pbXBvcnQgeyBzbGVlcCB9IGZyb20gJy4uL2F3cyc7XG5pbXBvcnQgeyBNZW1vcnlTdHJlYW0gfSBmcm9tICcuLi9jb3JraW5nJztcblxuZXhwb3J0IHR5cGUgRXJyb3JSZXNwb25zZSA9ICdmYWlsJyB8ICdza2lwJyB8ICdyZXRyeSc7XG5cbi8qKlxuICogUnVuIGEgZnVuY3Rpb24gaW4gcGFyYWxsZWwgd2l0aCBjYWNoZWQgb3V0cHV0XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwYXJhbGxlbFNoZWxsPEE+KFxuICBpbnB1dHM6IEFbXSxcbiAgYmxvY2s6ICh4OiBBLCBvdXRwdXQ6IE5vZGVKUy5Xcml0YWJsZVN0cmVhbSkgPT4gUHJvbWlzZTx2b2lkPixcbiAgc3dhbGxvd0Vycm9yPzogKHg6IEEsIG91dHB1dDogc3RyaW5nKSA9PiBFcnJvclJlc3BvbnNlLFxuKSB7XG4gIC8vIExpbWl0IHRvIDEwIGZvciBub3csIHRvbyBtYW55IGluc3RhbmNlcyBvZiBNYXZlbiBleGhhdXN0IHRoZSBDb2RlQnVpbGQgaW5zdGFuY2UgbWVtb3J5XG4gIGNvbnN0IHEgPSBuZXcgUFF1ZXVlKHsgY29uY3VycmVuY3k6IE51bWJlcihwcm9jZXNzLmVudi5DT05DVVJSRU5DWSkgfHwgMTAgfSk7XG4gIGF3YWl0IHEuYWRkQWxsKGlucHV0cy5tYXAoaW5wdXQgPT4gYXN5bmMgKCkgPT4ge1xuICAgIGxldCBhdHRlbXB0cyA9IDEwO1xuICAgIGxldCBzbGVlcE1zID0gNTAwO1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBjb25zdCBvdXRwdXQgPSBuZXcgTWVtb3J5U3RyZWFtKCk7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBibG9jayhpbnB1dCwgb3V0cHV0KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBzd2l0Y2ggKHN3YWxsb3dFcnJvcj8uKGlucHV0LCBvdXRwdXQudG9TdHJpbmcoKSkpIHtcbiAgICAgICAgICBjYXNlICdza2lwJzpcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICAgIGNhc2UgJ3JldHJ5JzpcbiAgICAgICAgICAgIGlmICgtLWF0dGVtcHRzID4gMCkge1xuICAgICAgICAgICAgICBhd2FpdCBzbGVlcChNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBzbGVlcE1zKSk7XG4gICAgICAgICAgICAgIHNsZWVwTXMgKj0gMjtcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgJ2ZhaWwnOlxuICAgICAgICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICBjb25zb2xlLmVycm9yKG91dHB1dC50b1N0cmluZygpKTtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9XG4gIH0pKTtcblxuICBhd2FpdCBxLm9uRW1wdHkoKTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import PQueue from 'p-queue';
|
|
2
|
+
import { sleep } from '../aws';
|
|
3
|
+
import { MemoryStream } from '../corking';
|
|
4
|
+
|
|
5
|
+
export type ErrorResponse = 'fail' | 'skip' | 'retry';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Run a function in parallel with cached output
|
|
9
|
+
*/
|
|
10
|
+
export async function parallelShell<A>(
|
|
11
|
+
inputs: A[],
|
|
12
|
+
block: (x: A, output: NodeJS.WritableStream) => Promise<void>,
|
|
13
|
+
swallowError?: (x: A, output: string) => ErrorResponse,
|
|
14
|
+
) {
|
|
15
|
+
// Limit to 10 for now, too many instances of Maven exhaust the CodeBuild instance memory
|
|
16
|
+
const q = new PQueue({ concurrency: Number(process.env.CONCURRENCY) || 10 });
|
|
17
|
+
await q.addAll(inputs.map(input => async () => {
|
|
18
|
+
let attempts = 10;
|
|
19
|
+
let sleepMs = 500;
|
|
20
|
+
while (true) {
|
|
21
|
+
const output = new MemoryStream();
|
|
22
|
+
try {
|
|
23
|
+
await block(input, output);
|
|
24
|
+
return;
|
|
25
|
+
} catch (e) {
|
|
26
|
+
switch (swallowError?.(input, output.toString())) {
|
|
27
|
+
case 'skip':
|
|
28
|
+
return;
|
|
29
|
+
|
|
30
|
+
case 'retry':
|
|
31
|
+
if (--attempts > 0) {
|
|
32
|
+
await sleep(Math.floor(Math.random() * sleepMs));
|
|
33
|
+
sleepMs *= 2;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
break;
|
|
37
|
+
|
|
38
|
+
case 'fail':
|
|
39
|
+
case undefined:
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// eslint-disable-next-line no-console
|
|
44
|
+
console.error(output.toString());
|
|
45
|
+
throw e;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}));
|
|
49
|
+
|
|
50
|
+
await q.onEmpty();
|
|
51
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { LoginInformation } from './codeartifact';
|
|
4
|
+
import { parallelShell } from './parallel-shell';
|
|
5
|
+
import { UsageDir } from './usage-dir';
|
|
6
|
+
import { writeFile } from '../files';
|
|
7
|
+
import { shell } from '../shell';
|
|
8
|
+
|
|
9
|
+
export async function pypiLogin(login: LoginInformation, usageDir: UsageDir) {
|
|
10
|
+
// Write pip config file and set environment var
|
|
11
|
+
await writeFile(path.join(usageDir.directory, 'pip.conf'), [
|
|
12
|
+
'[global]',
|
|
13
|
+
`index-url = https://aws:${login.authToken}@${login.pypiEndpoint.replace(/^https:\/\//, '')}simple/`,
|
|
14
|
+
].join('\n'));
|
|
15
|
+
await usageDir.addToEnv({
|
|
16
|
+
PIP_CONFIG_FILE: `${usageDir.directory}/pip.conf`,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function uploadPythonPackages(packages: string[], login: LoginInformation) {
|
|
21
|
+
await shell(['pip', 'install', 'twine'], { show: 'error' });
|
|
22
|
+
|
|
23
|
+
// Even though twine supports uploading all packages in one go, we have to upload them
|
|
24
|
+
// individually since CodeArtifact does not support Twine's `--skip-existing`. Fun beans.
|
|
25
|
+
await parallelShell(packages, async (pkg, output) => {
|
|
26
|
+
console.log(`⏳ ${pkg}`);
|
|
27
|
+
|
|
28
|
+
await shell(['twine', 'upload', '--verbose', pkg], {
|
|
29
|
+
modEnv: {
|
|
30
|
+
TWINE_USERNAME: 'aws',
|
|
31
|
+
TWINE_PASSWORD: login.authToken,
|
|
32
|
+
TWINE_REPOSITORY_URL: login.pypiEndpoint,
|
|
33
|
+
},
|
|
34
|
+
show: 'error',
|
|
35
|
+
outputs: [output],
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
console.log(`✅ ${pkg}`);
|
|
39
|
+
}, (pkg, output) => {
|
|
40
|
+
if (output.toString().includes('This package is configured to block new versions') || output.toString().includes('409 Conflict')) {
|
|
41
|
+
console.log(`❌ ${pkg}: already exists. Skipped.`);
|
|
42
|
+
return 'skip';
|
|
43
|
+
}
|
|
44
|
+
if (output.includes('429 Too Many Requests ')) {
|
|
45
|
+
console.log(`♻️ ${pkg}: 429 Too Many Requests. Retrying.`);
|
|
46
|
+
return 'retry';
|
|
47
|
+
}
|
|
48
|
+
return 'fail';
|
|
49
|
+
});
|
|
50
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import * as fs from 'fs-extra';
|
|
3
|
+
import { copyDirectoryContents, homeDir, loadLines, updateIniKey, writeLines } from '../files';
|
|
4
|
+
|
|
5
|
+
export const DEFAULT_USAGE_DIR = path.join(homeDir(), '.codeartifact/usage');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The usage directory is where we write per-session config files to access the CodeArtifact repository.
|
|
9
|
+
*
|
|
10
|
+
* Some config files may be written in a system-global location, but they will not be active unless the
|
|
11
|
+
* contents of this directory have been sourced/copied into the current terminal.
|
|
12
|
+
*
|
|
13
|
+
* CONTRACT
|
|
14
|
+
*
|
|
15
|
+
* There are two special entries:
|
|
16
|
+
*
|
|
17
|
+
* - `env`, a file with `key=value` entries for environment variables to set.
|
|
18
|
+
* - `cwd/`, a directory with files that need to be copied into the current directory before each command.
|
|
19
|
+
*
|
|
20
|
+
* Other than these, code may write tempfiles to this directory if it wants, but there is no meaning
|
|
21
|
+
* implied for other files.
|
|
22
|
+
*/
|
|
23
|
+
export class UsageDir {
|
|
24
|
+
public static default() {
|
|
25
|
+
return new UsageDir(DEFAULT_USAGE_DIR);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public readonly envFile: string;
|
|
29
|
+
public readonly cwdDir: string;
|
|
30
|
+
|
|
31
|
+
private constructor(public readonly directory: string) {
|
|
32
|
+
this.envFile = path.join(this.directory, 'env');
|
|
33
|
+
this.cwdDir = path.join(this.directory, 'cwd');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public async clean() {
|
|
37
|
+
await fs.rm(this.directory, { recursive: true, force: true });
|
|
38
|
+
await fs.mkdirp(path.join(this.directory, 'cwd'));
|
|
39
|
+
await fs.writeFile(path.join(this.directory, 'env'), '', { encoding: 'utf-8' });
|
|
40
|
+
|
|
41
|
+
await this.addToEnv({
|
|
42
|
+
CWD_FILES_DIR: path.join(this.directory, 'cwd'),
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Write a bash helper to load these settings
|
|
46
|
+
await fs.writeFile(path.join(this.directory, 'activate.bash'), [
|
|
47
|
+
`while read -u10 line; do [[ -z $line ]] || export "$line"; done 10<${this.directory}/env`,
|
|
48
|
+
'cp -R $CWD_FILES_DIR/ .', // Copy files from directory even if it is empty
|
|
49
|
+
].join('\n'), { encoding: 'utf-8' });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public async addToEnv(settings: Record<string, string>) {
|
|
53
|
+
const lines = await loadLines(this.envFile);
|
|
54
|
+
for (const [k, v] of Object.entries(settings)) {
|
|
55
|
+
updateIniKey(lines, k, v);
|
|
56
|
+
}
|
|
57
|
+
await writeLines(this.envFile, lines);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public async currentEnv(): Promise<Record<string, string>> {
|
|
61
|
+
const lines = await loadLines(this.envFile);
|
|
62
|
+
|
|
63
|
+
const splitter = /^([a-zA-Z0-9_-]+)\s*=\s*(.*)$/;
|
|
64
|
+
|
|
65
|
+
const ret: Record<string, string> = {};
|
|
66
|
+
for (const line of lines) {
|
|
67
|
+
const m = line.match(splitter);
|
|
68
|
+
if (m) {
|
|
69
|
+
ret[m[1]] = m[2];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return ret;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public cwdFile(filename: string) {
|
|
76
|
+
return path.join(this.cwdDir, filename);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public async activateInCurrentProcess() {
|
|
80
|
+
for (const [k, v] of Object.entries(await this.currentEnv())) {
|
|
81
|
+
process.env[k] = v;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
await copyDirectoryContents(this.cwdDir, '.');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public async copyCwdFileHere(...filenames: string[]) {
|
|
88
|
+
for (const file of filenames) {
|
|
89
|
+
await fs.copyFile(path.join(this.cwdDir, file), file);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public advertise() {
|
|
94
|
+
// eslint-disable-next-line no-console
|
|
95
|
+
console.log('To activate these settings in the current terminal:');
|
|
96
|
+
// eslint-disable-next-line no-console
|
|
97
|
+
console.log(` source ${this.directory}/activate.bash`);
|
|
98
|
+
}
|
|
99
|
+
}
|
package/lib/with-aws.js
CHANGED
|
@@ -18,12 +18,13 @@ function withAws(block, disableBootstrap = false) {
|
|
|
18
18
|
}
|
|
19
19
|
let _regionPool;
|
|
20
20
|
function regionPool() {
|
|
21
|
+
var _a, _b;
|
|
21
22
|
if (_regionPool !== undefined) {
|
|
22
23
|
return _regionPool;
|
|
23
24
|
}
|
|
24
25
|
const REGIONS = process.env.AWS_REGIONS
|
|
25
26
|
? process.env.AWS_REGIONS.split(',')
|
|
26
|
-
: [process.env.AWS_REGION
|
|
27
|
+
: [(_b = (_a = process.env.AWS_REGION) !== null && _a !== void 0 ? _a : process.env.AWS_DEFAULT_REGION) !== null && _b !== void 0 ? _b : 'us-east-1'];
|
|
27
28
|
// eslint-disable-next-line no-console
|
|
28
29
|
console.log(`Using regions: ${REGIONS}\n`);
|
|
29
30
|
_regionPool = resource_pool_1.ResourcePool.withResources('aws_regions', REGIONS);
|
|
@@ -56,4 +57,4 @@ async function sanityCheck(aws) {
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
let sanityChecked;
|
|
59
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
60
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2l0aC1hd3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ3aXRoLWF3cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVlBLDBCQVVDO0FBR0QsZ0NBY0M7QUF2Q0QsK0JBQW1DO0FBRW5DLG1EQUErQztBQUsvQzs7OztHQUlHO0FBQ0gsU0FBZ0IsT0FBTyxDQUNyQixLQUEyRSxFQUMzRSxtQkFBNEIsS0FBSztJQUVqQyxPQUFPLENBQUMsT0FBVSxFQUFFLEVBQUUsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQ3pELE1BQU0sR0FBRyxHQUFHLE1BQU0sZ0JBQVUsQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvRCxNQUFNLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUV2QixPQUFPLEtBQUssQ0FBQyxFQUFFLEdBQUcsT0FBTyxFQUFFLGdCQUFnQixFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFDdEQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsSUFBSSxXQUFxQyxDQUFDO0FBQzFDLFNBQWdCLFVBQVU7O0lBQ3hCLElBQUksV0FBVyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzlCLE9BQU8sV0FBVyxDQUFDO0lBQ3JCLENBQUM7SUFFRCxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVc7UUFDckMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUMsTUFBQSxNQUFBLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxtQ0FBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixtQ0FBSSxXQUFXLENBQUMsQ0FBQztJQUU5RSxzQ0FBc0M7SUFDdEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsT0FBTyxJQUFJLENBQUMsQ0FBQztJQUUzQyxXQUFXLEdBQUcsNEJBQVksQ0FBQyxhQUFhLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ2pFLE9BQU8sV0FBVyxDQUFDO0FBQ3JCLENBQUM7QUFFRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsS0FBSyxVQUFVLFdBQVcsQ0FBQyxHQUFlO0lBQ3hDLElBQUksYUFBYSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQztZQUNILE1BQU0sR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3BCLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDdkIsQ0FBQztRQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7WUFDaEIsYUFBYSxHQUFHLEtBQUssQ0FBQztZQUN0QixNQUFNLElBQUksS0FBSyxDQUFDLHVEQUF1RCxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUN0RixDQUFDO0lBQ0gsQ0FBQztJQUNELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNuQixNQUFNLElBQUksS0FBSyxDQUFDLDZEQUE2RCxDQUFDLENBQUM7SUFDakYsQ0FBQztBQUNILENBQUM7QUFDRCxJQUFJLGFBQWtDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBd3NDbGllbnRzIH0gZnJvbSAnLi9hd3MnO1xuaW1wb3J0IHsgVGVzdENvbnRleHQgfSBmcm9tICcuL2ludGVnLXRlc3QnO1xuaW1wb3J0IHsgUmVzb3VyY2VQb29sIH0gZnJvbSAnLi9yZXNvdXJjZS1wb29sJztcbmltcG9ydCB7IERpc2FibGVCb290c3RyYXBDb250ZXh0IH0gZnJvbSAnLi93aXRoLWNkay1hcHAnO1xuXG5leHBvcnQgdHlwZSBBd3NDb250ZXh0ID0geyByZWFkb25seSBhd3M6IEF3c0NsaWVudHMgfTtcblxuLyoqXG4gKiBIaWdoZXIgb3JkZXIgZnVuY3Rpb24gdG8gZXhlY3V0ZSBhIGJsb2NrIHdpdGggYW4gQVdTIGNsaWVudCBzZXR1cFxuICpcbiAqIEFsbG9jYXRlIHRoZSBuZXh0IHJlZ2lvbiBmcm9tIHRoZSBSRUdJT04gcG9vbCBhbmQgZGlzcG9zZSBpdCBhZnRlcndhcmRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2l0aEF3czxBIGV4dGVuZHMgVGVzdENvbnRleHQ+KFxuICBibG9jazogKGNvbnRleHQ6IEEgJiBBd3NDb250ZXh0ICYgRGlzYWJsZUJvb3RzdHJhcENvbnRleHQpID0+IFByb21pc2U8dm9pZD4sXG4gIGRpc2FibGVCb290c3RyYXA6IGJvb2xlYW4gPSBmYWxzZSxcbik6IChjb250ZXh0OiBBKSA9PiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIChjb250ZXh0OiBBKSA9PiByZWdpb25Qb29sKCkudXNpbmcoYXN5bmMgKHJlZ2lvbikgPT4ge1xuICAgIGNvbnN0IGF3cyA9IGF3YWl0IEF3c0NsaWVudHMuZm9yUmVnaW9uKHJlZ2lvbiwgY29udGV4dC5vdXRwdXQpO1xuICAgIGF3YWl0IHNhbml0eUNoZWNrKGF3cyk7XG5cbiAgICByZXR1cm4gYmxvY2soeyAuLi5jb250ZXh0LCBkaXNhYmxlQm9vdHN0cmFwLCBhd3MgfSk7XG4gIH0pO1xufVxuXG5sZXQgX3JlZ2lvblBvb2w6IHVuZGVmaW5lZCB8IFJlc291cmNlUG9vbDtcbmV4cG9ydCBmdW5jdGlvbiByZWdpb25Qb29sKCk6IFJlc291cmNlUG9vbCB7XG4gIGlmIChfcmVnaW9uUG9vbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIF9yZWdpb25Qb29sO1xuICB9XG5cbiAgY29uc3QgUkVHSU9OUyA9IHByb2Nlc3MuZW52LkFXU19SRUdJT05TXG4gICAgPyBwcm9jZXNzLmVudi5BV1NfUkVHSU9OUy5zcGxpdCgnLCcpXG4gICAgOiBbcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTiA/PyBwcm9jZXNzLmVudi5BV1NfREVGQVVMVF9SRUdJT04gPz8gJ3VzLWVhc3QtMSddO1xuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gIGNvbnNvbGUubG9nKGBVc2luZyByZWdpb25zOiAke1JFR0lPTlN9XFxuYCk7XG5cbiAgX3JlZ2lvblBvb2wgPSBSZXNvdXJjZVBvb2wud2l0aFJlc291cmNlcygnYXdzX3JlZ2lvbnMnLCBSRUdJT05TKTtcbiAgcmV0dXJuIF9yZWdpb25Qb29sO1xufVxuXG4vKipcbiAqIFBlcmZvcm0gYSBvbmUtdGltZSBxdWljayBzYW5pdHkgY2hlY2sgdGhhdCB0aGUgQVdTIGNsaWVudHMgaGF2ZSBwcm9wZXJseSBjb25maWd1cmVkIGNyZWRlbnRpYWxzXG4gKlxuICogSWYgd2UgZG9uJ3QgZG8gdGhpcywgY2FsbHMgYXJlIGdvaW5nIHRvIGZhaWwgYW5kIHRoZXknbGwgYmUgcmV0cmllZCBhbmQgZXZlcnl0aGluZyB3aWxsIHRha2VcbiAqIGZvcmV2ZXIgYmVmb3JlIHRoZSB1c2VyIG5vdGljZXMgYSBzaW1wbGUgbWlzY29uZmlndXJhdGlvbi5cbiAqXG4gKiBXZSBjYW4ndCBjaGVjayBmb3IgdGhlIHByZXNlbmNlIG9mIGVudmlyb25tZW50IHZhcmlhYmxlcyBzaW5jZSBjcmVkZW50aWFscyBjb3VsZCBjb21lIGZyb21cbiAqIGFueXdoZXJlLCBzbyBkbyBzaW1wbGUgYWNjb3VudCByZXRyaWV2YWwuXG4gKlxuICogT25seSBkbyBpdCBvbmNlIHBlciBwcm9jZXNzLlxuICovXG5hc3luYyBmdW5jdGlvbiBzYW5pdHlDaGVjayhhd3M6IEF3c0NsaWVudHMpIHtcbiAgaWYgKHNhbml0eUNoZWNrZWQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBhd3MuYWNjb3VudCgpO1xuICAgICAgc2FuaXR5Q2hlY2tlZCA9IHRydWU7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBzYW5pdHlDaGVja2VkID0gZmFsc2U7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEFXUyBjcmVkZW50aWFscyBwcm9iYWJseSBub3QgY29uZmlndXJlZCwgZ290IGVycm9yOiAke2UubWVzc2FnZX1gKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFzYW5pdHlDaGVja2VkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBV1MgY3JlZGVudGlhbHMgcHJvYmFibHkgbm90IGNvbmZpZ3VyZWQsIHNlZSBwcmV2aW91cyBlcnJvcicpO1xuICB9XG59XG5sZXQgc2FuaXR5Q2hlY2tlZDogYm9vbGVhbiB8IHVuZGVmaW5lZDtcbiJdfQ==
|
package/lib/with-aws.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { AwsClients } from './aws';
|
|
2
|
+
import { TestContext } from './integ-test';
|
|
3
|
+
import { ResourcePool } from './resource-pool';
|
|
4
|
+
import { DisableBootstrapContext } from './with-cdk-app';
|
|
5
|
+
|
|
6
|
+
export type AwsContext = { readonly aws: AwsClients };
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Higher order function to execute a block with an AWS client setup
|
|
10
|
+
*
|
|
11
|
+
* Allocate the next region from the REGION pool and dispose it afterwards.
|
|
12
|
+
*/
|
|
13
|
+
export function withAws<A extends TestContext>(
|
|
14
|
+
block: (context: A & AwsContext & DisableBootstrapContext) => Promise<void>,
|
|
15
|
+
disableBootstrap: boolean = false,
|
|
16
|
+
): (context: A) => Promise<void> {
|
|
17
|
+
return (context: A) => regionPool().using(async (region) => {
|
|
18
|
+
const aws = await AwsClients.forRegion(region, context.output);
|
|
19
|
+
await sanityCheck(aws);
|
|
20
|
+
|
|
21
|
+
return block({ ...context, disableBootstrap, aws });
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let _regionPool: undefined | ResourcePool;
|
|
26
|
+
export function regionPool(): ResourcePool {
|
|
27
|
+
if (_regionPool !== undefined) {
|
|
28
|
+
return _regionPool;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const REGIONS = process.env.AWS_REGIONS
|
|
32
|
+
? process.env.AWS_REGIONS.split(',')
|
|
33
|
+
: [process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? 'us-east-1'];
|
|
34
|
+
|
|
35
|
+
// eslint-disable-next-line no-console
|
|
36
|
+
console.log(`Using regions: ${REGIONS}\n`);
|
|
37
|
+
|
|
38
|
+
_regionPool = ResourcePool.withResources('aws_regions', REGIONS);
|
|
39
|
+
return _regionPool;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Perform a one-time quick sanity check that the AWS clients have properly configured credentials
|
|
44
|
+
*
|
|
45
|
+
* If we don't do this, calls are going to fail and they'll be retried and everything will take
|
|
46
|
+
* forever before the user notices a simple misconfiguration.
|
|
47
|
+
*
|
|
48
|
+
* We can't check for the presence of environment variables since credentials could come from
|
|
49
|
+
* anywhere, so do simple account retrieval.
|
|
50
|
+
*
|
|
51
|
+
* Only do it once per process.
|
|
52
|
+
*/
|
|
53
|
+
async function sanityCheck(aws: AwsClients) {
|
|
54
|
+
if (sanityChecked === undefined) {
|
|
55
|
+
try {
|
|
56
|
+
await aws.account();
|
|
57
|
+
sanityChecked = true;
|
|
58
|
+
} catch (e: any) {
|
|
59
|
+
sanityChecked = false;
|
|
60
|
+
throw new Error(`AWS credentials probably not configured, got error: ${e.message}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (!sanityChecked) {
|
|
64
|
+
throw new Error('AWS credentials probably not configured, see previous error');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
let sanityChecked: boolean | undefined;
|