From 7257bf9a326605f7e343e0cf07b963b788d7907a Mon Sep 17 00:00:00 2001 From: AmmarKarachi Date: Thu, 11 Mar 2021 12:43:22 -0800 Subject: [PATCH 1/6] feat: added new fields to usage data Added * project setting * accountId --- packages/amplify-cli/src/app-config/config.ts | 2 +- packages/amplify-cli/src/context-manager.ts | 25 ++++++++++++++-- .../domain/amplify-usageData/IUsageData.ts | 3 +- .../domain/amplify-usageData/NoUsageData.ts | 2 +- .../src/domain/amplify-usageData/UsageData.ts | 27 ++++++++++++++--- .../amplify-usageData/UsageDataPayload.ts | 29 ++++++++++++++++++- packages/amplify-cli/src/index.ts | 4 +-- .../src/amplify-sts.ts | 11 +++++++ .../src/aws-utils/aws-sts.ts | 25 ++++++++++++++++ .../src/utility-functions.js | 18 +++++++----- 10 files changed, 126 insertions(+), 20 deletions(-) create mode 100644 packages/amplify-provider-awscloudformation/src/amplify-sts.ts create mode 100644 packages/amplify-provider-awscloudformation/src/aws-utils/aws-sts.ts diff --git a/packages/amplify-cli/src/app-config/config.ts b/packages/amplify-cli/src/app-config/config.ts index d38a9169344..62d7821506f 100644 --- a/packages/amplify-cli/src/app-config/config.ts +++ b/packages/amplify-cli/src/app-config/config.ts @@ -54,7 +54,7 @@ class Config { } class UsageDataConfig { - installationUuid: String; + installationUuid: string; isUsageTrackingEnabled: boolean; constructor() { diff --git a/packages/amplify-cli/src/context-manager.ts b/packages/amplify-cli/src/context-manager.ts index 9648937ab87..486ce06a9f3 100644 --- a/packages/amplify-cli/src/context-manager.ts +++ b/packages/amplify-cli/src/context-manager.ts @@ -4,6 +4,8 @@ import { PluginPlatform } from './domain/plugin-platform'; import { attachExtentions } from './context-extensions'; import { init } from './app-config'; import { UsageData, NoUsageData } from './domain/amplify-usageData'; +import { ProjectSettings } from './domain/amplify-usageData/UsageDataPayload'; +import { stateManager } from 'amplify-cli-core'; export function constructContext(pluginPlatform: PluginPlatform, input: Input): Context { const context = new Context(pluginPlatform, input); @@ -11,22 +13,41 @@ export function constructContext(pluginPlatform: PluginPlatform, input: Input): return context; } -export function attachUsageData(context: Context) { +export async function attachUsageData(context: Context) { const { AMPLIFY_CLI_ENABLE_USAGE_DATA } = process.env; const config = init(context); const usageTrackingEnabled = AMPLIFY_CLI_ENABLE_USAGE_DATA ? AMPLIFY_CLI_ENABLE_USAGE_DATA === 'true' : config.usageDataConfig.isUsageTrackingEnabled; + const accountId = await context.amplify.executeProviderUtils(context, 'awscloudformation', 'getAccountId'); if (usageTrackingEnabled) { context.usageData = UsageData.Instance; } else { context.usageData = NoUsageData.Instance; } - context.usageData.init(config.usageDataConfig.installationUuid, getVersion(context), context.input); + context.usageData.init(config.usageDataConfig.installationUuid, getVersion(context), context.input, accountId, getProjectSettings()); } const getVersion = (context: Context) => context.pluginPlatform.plugins.core[0].packageVersion; +const getProjectSettings = (): ProjectSettings => { + const projectSettings = {}; + if (stateManager.projectConfigExists()) { + const projectConfig = stateManager.getProjectConfig(); + const frontend = projectConfig['frontend']; + projectSettings['frontend'] = frontend; + if (projectConfig[frontend] && projectConfig[frontend].framework) { + projectSettings['framework'] = projectConfig[frontend].framework; + } + } + + if (stateManager.localEnvInfoExists()) { + const { defaultEditor } = stateManager.getLocalEnvInfo(); + projectSettings['editor'] = defaultEditor; + } + + return projectSettings; +}; export function persistContext(context: Context): void { // write to the backend and current backend // and get the frontend plugin to write to the config files. diff --git a/packages/amplify-cli/src/domain/amplify-usageData/IUsageData.ts b/packages/amplify-cli/src/domain/amplify-usageData/IUsageData.ts index ff80af877f0..31f5697c2f6 100644 --- a/packages/amplify-cli/src/domain/amplify-usageData/IUsageData.ts +++ b/packages/amplify-cli/src/domain/amplify-usageData/IUsageData.ts @@ -1,9 +1,10 @@ import { Input } from '../input'; +import { ProjectSettings } from './UsageDataPayload'; export interface IUsageData { emitError(error: Error): Promise; emitInvoke(): Promise; emitAbort(): Promise; emitSuccess(): Promise; - init(installationUuid: String, version: String, input: Input): void; + init(installationUuid: string, version: string, input: Input, accountId: string, projectSettings: ProjectSettings): void; } diff --git a/packages/amplify-cli/src/domain/amplify-usageData/NoUsageData.ts b/packages/amplify-cli/src/domain/amplify-usageData/NoUsageData.ts index e76c980ddec..132ca243112 100644 --- a/packages/amplify-cli/src/domain/amplify-usageData/NoUsageData.ts +++ b/packages/amplify-cli/src/domain/amplify-usageData/NoUsageData.ts @@ -13,7 +13,7 @@ export class NoUsageData implements IUsageData { emitSuccess(): Promise { return Promise.resolve(); } - init(installationUuid: String, version: String, input: any): void {} + init(installationUuid: String, version: String, input: any, accountId: string): void {} private static instance: NoUsageData; static get Instance(): IUsageData { diff --git a/packages/amplify-cli/src/domain/amplify-usageData/UsageData.ts b/packages/amplify-cli/src/domain/amplify-usageData/UsageData.ts index 07211325914..843ceb66c48 100644 --- a/packages/amplify-cli/src/domain/amplify-usageData/UsageData.ts +++ b/packages/amplify-cli/src/domain/amplify-usageData/UsageData.ts @@ -3,17 +3,20 @@ import { Input } from '../input'; import https from 'https'; import { UrlWithStringQuery } from 'url'; import redactInput from './identifiable-input-regex'; -import { UsageDataPayload } from './UsageDataPayload'; +import { ProjectSettings, UsageDataPayload, InputOptions } from './UsageDataPayload'; import { getUrl } from './getUsageDataUrl'; import { IUsageData } from './IUsageData'; import { JSONUtilities } from 'amplify-cli-core'; - +import _ from 'lodash'; export class UsageData implements IUsageData { sessionUuid: string; + accountId: string = ''; installationUuid: string = ''; version: string = ''; input: Input; + projectSettings: ProjectSettings; url: UrlWithStringQuery; + inputOptions: InputOptions; requestTimeout: number = 100; private static instance: UsageData; @@ -21,11 +24,16 @@ export class UsageData implements IUsageData { this.sessionUuid = uuid.v4(); this.url = getUrl(); this.input = new Input([]); + this.projectSettings = {}; + this.inputOptions = {}; } - init(installationUuid: string, version: string, input: Input): void { + init(installationUuid: string, version: string, input: Input, accountId: string, projectSettings: ProjectSettings): void { this.installationUuid = installationUuid; + this.accountId = accountId; + this.projectSettings = projectSettings; this.version = version; + this.inputOptions = input.options ? _.pick(input.options as InputOptions, ['sandboxId']) : {}; this.input = redactInput(input, true); } @@ -48,7 +56,18 @@ export class UsageData implements IUsageData { } async emit(error: Error | null, state: string): Promise { - const payload = new UsageDataPayload(this.sessionUuid, this.installationUuid, this.version, this.input, error, state); + const payload = new UsageDataPayload( + this.sessionUuid, + this.installationUuid, + this.version, + this.input, + error, + state, + this.accountId, + this.projectSettings, + this.inputOptions, + ); + console.log(JSON.stringify(payload, null, 4)); return this.send(payload); } diff --git a/packages/amplify-cli/src/domain/amplify-usageData/UsageDataPayload.ts b/packages/amplify-cli/src/domain/amplify-usageData/UsageDataPayload.ts index cb29474222d..10d4ef8a370 100644 --- a/packages/amplify-cli/src/domain/amplify-usageData/UsageDataPayload.ts +++ b/packages/amplify-cli/src/domain/amplify-usageData/UsageDataPayload.ts @@ -7,6 +7,7 @@ export class UsageDataPayload { installationUuid: string; amplifyCliVersion: string; input: Input | null; + inputOptions: InputOptions; timestamp: string; error!: SerializableError; payloadVersion: string; @@ -15,7 +16,19 @@ export class UsageDataPayload { nodeVersion: string; state: string; isCi: boolean; - constructor(sessionUuid: string, installationUuid: string, version: string, input: Input, error: Error | null, state: string) { + accountId: string; + projectSetting: ProjectSettings; + constructor( + sessionUuid: string, + installationUuid: string, + version: string, + input: Input, + error: Error | null, + state: string, + accountId: string, + project: ProjectSettings, + inputOptions: InputOptions, + ) { this.sessionUuid = sessionUuid; this.installationUuid = installationUuid; this.amplifyCliVersion = version; @@ -26,12 +39,26 @@ export class UsageDataPayload { this.nodeVersion = process.versions.node; this.state = state; this.payloadVersion = getLatestPayloadVersion(); + this.accountId = accountId; this.isCi = ci.isCI; + this.projectSetting = project; + this.inputOptions = inputOptions; if (error) { this.error = new SerializableError(error); } } } + +export type ProjectSettings = { + frontend?: string; + editor?: string; + framework?: string; +}; + +export type InputOptions = { + [key: string]: string | boolean; +}; + export class SerializableError { name: string; constructor(error: Error) { diff --git a/packages/amplify-cli/src/index.ts b/packages/amplify-cli/src/index.ts index c0b65ad8266..930f8d2b272 100644 --- a/packages/amplify-cli/src/index.ts +++ b/packages/amplify-cli/src/index.ts @@ -110,7 +110,7 @@ export async function run() { await FeatureFlags.initialize(contextEnvironmentProvider, useNewDefaults); - attachUsageData(context); + await attachUsageData(context); if (!(await migrateTeamProviderInfo(context))) { context.usageData.emitError(new TeamProviderInfoMigrateError()); @@ -262,7 +262,7 @@ export async function execute(input: Input): Promise { const context = constructContext(pluginPlatform, input); - attachUsageData(context); + await attachUsageData(context); errorHandler = boundErrorHandler.bind(context); diff --git a/packages/amplify-provider-awscloudformation/src/amplify-sts.ts b/packages/amplify-provider-awscloudformation/src/amplify-sts.ts new file mode 100644 index 00000000000..d27451da93d --- /dev/null +++ b/packages/amplify-provider-awscloudformation/src/amplify-sts.ts @@ -0,0 +1,11 @@ +import { STS } from './aws-utils/aws-sts'; + +export async function getAccountId(context) { + const amplifySts = await new STS(context); + try { + const data = await amplifySts.sts.getCallerIdentity().promise(); + return data.Account; + } catch (ex) { + return ''; + } +} diff --git a/packages/amplify-provider-awscloudformation/src/aws-utils/aws-sts.ts b/packages/amplify-provider-awscloudformation/src/aws-utils/aws-sts.ts new file mode 100644 index 00000000000..8db887b6c8e --- /dev/null +++ b/packages/amplify-provider-awscloudformation/src/aws-utils/aws-sts.ts @@ -0,0 +1,25 @@ +import AWS from 'aws-sdk'; +import aws from './aws'; +import { loadConfiguration } from '../configuration-manager'; +import { $TSContext } from 'amplify-cli-core'; + +export class STS { + public sts: AWS.STS; + + constructor(private readonly context: $TSContext, options = {}) { + const instancePromise = (async () => { + let cred = {}; + try { + cred = await loadConfiguration(context); + } catch (e) { + // ignore missing config + } + + this.sts = new (aws as typeof AWS).STS({ ...cred, ...options }); + + return this; + })(); + + return (instancePromise); + } +} diff --git a/packages/amplify-provider-awscloudformation/src/utility-functions.js b/packages/amplify-provider-awscloudformation/src/utility-functions.js index 7d8d39cb38d..03c6e69b7e1 100644 --- a/packages/amplify-provider-awscloudformation/src/utility-functions.js +++ b/packages/amplify-provider-awscloudformation/src/utility-functions.js @@ -14,13 +14,13 @@ const ECR = require('./aws-utils/aws-ecr'); const { pagedAWSCall } = require('./aws-utils/paged-call'); const { fileLogger } = require('./utils/aws-logger'); const logger = fileLogger('utility-functions'); +const { getAccountId } = require('./amplify-sts'); module.exports = { zipFiles: (context, [srcDir, dstZipFilePath]) => { - return archiver(srcDir, dstZipFilePath) + return archiver(srcDir, dstZipFilePath); }, isDomainInZones: async (context, { domain }) => { - const client = await new Route53(context); let Marker; @@ -28,17 +28,18 @@ module.exports = { let zoneFound; do { - const { NextMarker, IsTruncated, HostedZones } = await client.route53.listHostedZones({ - Marker, - MaxItems: '100' - }).promise(); + const { NextMarker, IsTruncated, HostedZones } = await client.route53 + .listHostedZones({ + Marker, + MaxItems: '100', + }) + .promise(); zoneFound = HostedZones.find(zone => `${domain}.`.endsWith(zone.Name)); Marker = NextMarker; truncated = IsTruncated; - - } while (truncated && !zoneFound) + } while (truncated && !zoneFound); return zoneFound; }, @@ -137,6 +138,7 @@ module.exports = { return response; }, + getAccountId, getTransformerDirectives: async (context, options) => { const { resourceDir } = options; if (!resourceDir) { From bf86282f5312d848a59b5bcf489a3db63d487027 Mon Sep 17 00:00:00 2001 From: AmmarKarachi Date: Thu, 18 Mar 2021 17:02:47 -0700 Subject: [PATCH 2/6] test: test fixes after usage data --- jest.config.js | 1 - .../src/__tests__/context-manager.test.ts | 34 ++++++++++++++----- .../src/__tests__/usage-data.test.ts | 4 +-- .../src/__tests__/version-manager.test.ts | 12 ++++++- .../src/domain/amplify-usageData/UsageData.ts | 1 - .../amplify-usageData/VersionManager.ts | 2 +- 6 files changed, 39 insertions(+), 15 deletions(-) diff --git a/jest.config.js b/jest.config.js index 9785593db81..4b998709cdf 100644 --- a/jest.config.js +++ b/jest.config.js @@ -37,7 +37,6 @@ module.exports = { '/packages/amplify-cli', '/packages/amplify-cli-core', '/packages/amplify-cli-logger', - '/packages/amplify-codegen', '/packages/amplify-codegen-appsync-model-plugin', '/packages/amplify-dynamodb-simulator', '/packages/amplify-frontend-android', diff --git a/packages/amplify-cli/src/__tests__/context-manager.test.ts b/packages/amplify-cli/src/__tests__/context-manager.test.ts index 52331b31c2a..9246b4d8086 100644 --- a/packages/amplify-cli/src/__tests__/context-manager.test.ts +++ b/packages/amplify-cli/src/__tests__/context-manager.test.ts @@ -25,7 +25,7 @@ jest.mock('../app-config'); describe('test attachUsageData', () => { const version = 'latestversion'; - const mockContext: Context = jest.genMockFromModule('../domain/context'); + let mockContext = jest.genMockFromModule('../domain/context'); mockContext.input = new Input([ '/Users/userName/.nvm/versions/node/v8.11.4/bin/node', @@ -35,10 +35,14 @@ describe('test attachUsageData', () => { mockContext.pluginPlatform = new PluginPlatform(); mockContext.pluginPlatform.plugins['core'] = [new PluginInfo('', version, '', new PluginManifest('', ''))]; - beforeAll(() => {}); - afterEach(() => { + beforeEach(() => { + jest.clearAllMocks(); + const amplifyToolkit = jest.createMockFromModule('../domain/amplify-toolkit').AmplifyToolkit; + amplifyToolkit['executeProviderUtils'] = jest.fn().mockReturnValue('accountId'); + mockContext.amplify = amplifyToolkit; jest.clearAllMocks(); }); + afterEach(() => {}); it('constructContext', () => { const context = constructContext(mockContext.pluginPlatform, mockContext.input); @@ -48,7 +52,7 @@ describe('test attachUsageData', () => { expect(context.input).toEqual(mockContext.input); }); - it('test with usage data enabled', () => { + it('test with usage data enabled', async () => { const returnValue = { usageDataConfig: { installationUuid: 'uuid', @@ -58,11 +62,17 @@ describe('test attachUsageData', () => { }; const mockedInit = appConfig.init as jest.Mock; mockedInit.mockReturnValue(returnValue); - attachUsageData(mockContext); - expect(UsageData.UsageData.Instance.init).toBeCalledWith(returnValue.usageDataConfig.installationUuid, version, mockContext.input); + await attachUsageData(mockContext); + expect(UsageData.UsageData.Instance.init).toBeCalledWith( + returnValue.usageDataConfig.installationUuid, + version, + mockContext.input, + 'accountId', + {}, + ); }); - it('test with usage data enabled', () => { + it('test with usage data disabled', async () => { const returnValue = { usageDataConfig: { installationUuid: 'uuid', @@ -72,7 +82,13 @@ describe('test attachUsageData', () => { }; const mockedInit = appConfig.init as jest.Mock; mockedInit.mockReturnValue(returnValue); - attachUsageData(mockContext); - expect(UsageData.NoUsageData.Instance.init).toBeCalledWith(returnValue.usageDataConfig.installationUuid, version, mockContext.input); + await attachUsageData(mockContext); + expect(UsageData.NoUsageData.Instance.init).toBeCalledWith( + returnValue.usageDataConfig.installationUuid, + version, + mockContext.input, + 'accountId', + {}, + ); }); }); diff --git a/packages/amplify-cli/src/__tests__/usage-data.test.ts b/packages/amplify-cli/src/__tests__/usage-data.test.ts index 0a90837bb01..da948179471 100644 --- a/packages/amplify-cli/src/__tests__/usage-data.test.ts +++ b/packages/amplify-cli/src/__tests__/usage-data.test.ts @@ -28,8 +28,8 @@ describe('test usageData', () => { it('test instance', () => { const a = UsageData.Instance; const b = UsageData.Instance; - a.init(uuid.v4(), '', new Input([])); - b.init(uuid.v4(), '', new Input([])); + a.init(uuid.v4(), '', new Input([]), 'accountId', { editor: 'vscode', framework: 'react', frontend: 'javascript' }); + b.init(uuid.v4(), '', new Input([]), 'accountId', { editor: 'vscode', framework: 'react', frontend: 'javascript' }); expect(a).toEqual(b); }); }); diff --git a/packages/amplify-cli/src/__tests__/version-manager.test.ts b/packages/amplify-cli/src/__tests__/version-manager.test.ts index 42bb2e247bb..7c285436b2d 100644 --- a/packages/amplify-cli/src/__tests__/version-manager.test.ts +++ b/packages/amplify-cli/src/__tests__/version-manager.test.ts @@ -11,7 +11,17 @@ describe('test version manager', () => { }); it('payload version should be the latest', () => { - const payload = new UsageDataPayload('', '', '', new Input([]), new Error(''), ''); + const payload = new UsageDataPayload( + '', + '', + '', + new Input([]), + new Error(''), + '', + '12311232', + { frontend: 'javascript', editor: 'vscode', framework: 'react' }, + {}, + ); expect(payload.payloadVersion).toEqual(getLatestPayloadVersion()); }); }); diff --git a/packages/amplify-cli/src/domain/amplify-usageData/UsageData.ts b/packages/amplify-cli/src/domain/amplify-usageData/UsageData.ts index 843ceb66c48..892d1e7a6b3 100644 --- a/packages/amplify-cli/src/domain/amplify-usageData/UsageData.ts +++ b/packages/amplify-cli/src/domain/amplify-usageData/UsageData.ts @@ -67,7 +67,6 @@ export class UsageData implements IUsageData { this.projectSettings, this.inputOptions, ); - console.log(JSON.stringify(payload, null, 4)); return this.send(payload); } diff --git a/packages/amplify-cli/src/domain/amplify-usageData/VersionManager.ts b/packages/amplify-cli/src/domain/amplify-usageData/VersionManager.ts index d230abc38cd..f62adbadaef 100644 --- a/packages/amplify-cli/src/domain/amplify-usageData/VersionManager.ts +++ b/packages/amplify-cli/src/domain/amplify-usageData/VersionManager.ts @@ -1,6 +1,6 @@ import semver from 'semver'; -const APIVersionToPayloadVersion = new Map>([['v1.0', ['1.0.0', '1.0.1']]]); +const APIVersionToPayloadVersion = new Map>([['v1.0', ['1.0.0', '1.0.1', '1.1.0']]]); export function getLatestApiVersion(): string { return [...APIVersionToPayloadVersion.keys()].reduce(getMaxVersion, '0'); From 221a8bd8b2969d2bda67e292a0b2eec7ec93557d Mon Sep 17 00:00:00 2001 From: AmmarKarachi Date: Mon, 29 Mar 2021 13:09:08 -0700 Subject: [PATCH 3/6] fix: add collection on exit --- .circleci/config.yml | 64 +++++++++---------- packages/amplify-cli-core/src/errors/index.ts | 1 + .../amplify-cli/src/commands/configure.ts | 2 +- packages/amplify-cli/src/commands/publish.ts | 2 +- packages/amplify-cli/src/commands/pull.ts | 4 +- packages/amplify-cli/src/initialize-env.ts | 1 + 6 files changed, 39 insertions(+), 35 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6734ea63d4e..75e62493884 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1077,37 +1077,37 @@ jobs: environment: TEST_SUITE: src/__tests__/plugin.test.ts CLI_REGION: ap-northeast-1 - migration-node-function-amplify_e2e_tests: + schema-iterative-update-locking-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 resource_class: large steps: *ref_4 environment: - TEST_SUITE: src/__tests__/migration/node.function.test.ts + TEST_SUITE: src/__tests__/schema-iterative-update-locking.test.ts CLI_REGION: ap-southeast-1 - api_4-amplify_e2e_tests: + migration-node-function-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 resource_class: large steps: *ref_4 environment: - TEST_SUITE: src/__tests__/api_4.test.ts + TEST_SUITE: src/__tests__/migration/node.function.test.ts CLI_REGION: ap-southeast-2 - schema-iterative-update-locking-amplify_e2e_tests: + function_5-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 resource_class: large steps: *ref_4 environment: - TEST_SUITE: src/__tests__/schema-iterative-update-locking.test.ts + TEST_SUITE: src/__tests__/function_5.test.ts CLI_REGION: us-east-2 - function_5-amplify_e2e_tests: + api_4-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 resource_class: large steps: *ref_4 environment: - TEST_SUITE: src/__tests__/function_5.test.ts + TEST_SUITE: src/__tests__/api_4.test.ts CLI_REGION: us-west-2 schema-iterative-update-4-amplify_e2e_tests_pkg_linux: working_directory: ~/repo @@ -1719,44 +1719,44 @@ jobs: TEST_SUITE: src/__tests__/plugin.test.ts CLI_REGION: ap-northeast-1 steps: *ref_5 - migration-node-function-amplify_e2e_tests_pkg_linux: + schema-iterative-update-locking-amplify_e2e_tests_pkg_linux: working_directory: ~/repo docker: *ref_1 resource_class: large environment: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux - TEST_SUITE: src/__tests__/migration/node.function.test.ts + TEST_SUITE: src/__tests__/schema-iterative-update-locking.test.ts CLI_REGION: ap-southeast-1 steps: *ref_5 - api_4-amplify_e2e_tests_pkg_linux: + migration-node-function-amplify_e2e_tests_pkg_linux: working_directory: ~/repo docker: *ref_1 resource_class: large environment: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux - TEST_SUITE: src/__tests__/api_4.test.ts + TEST_SUITE: src/__tests__/migration/node.function.test.ts CLI_REGION: ap-southeast-2 steps: *ref_5 - schema-iterative-update-locking-amplify_e2e_tests_pkg_linux: + function_5-amplify_e2e_tests_pkg_linux: working_directory: ~/repo docker: *ref_1 resource_class: large environment: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux - TEST_SUITE: src/__tests__/schema-iterative-update-locking.test.ts + TEST_SUITE: src/__tests__/function_5.test.ts CLI_REGION: us-east-2 steps: *ref_5 - function_5-amplify_e2e_tests_pkg_linux: + api_4-amplify_e2e_tests_pkg_linux: working_directory: ~/repo docker: *ref_1 resource_class: large environment: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux - TEST_SUITE: src/__tests__/function_5.test.ts + TEST_SUITE: src/__tests__/api_4.test.ts CLI_REGION: us-west-2 steps: *ref_5 workflows: @@ -1854,11 +1854,11 @@ workflows: - hostingPROD-amplify_e2e_tests - amplify-app-amplify_e2e_tests - init-amplify_e2e_tests - - schema-iterative-update-locking-amplify_e2e_tests + - function_5-amplify_e2e_tests - predictions-amplify_e2e_tests - schema-predictions-amplify_e2e_tests - amplify-configure-amplify_e2e_tests - - function_5-amplify_e2e_tests + - api_4-amplify_e2e_tests - function_3-amplify_e2e_tests - containers-api-amplify_e2e_tests - interactions-amplify_e2e_tests @@ -1874,22 +1874,22 @@ workflows: - schema-key-amplify_e2e_tests - analytics-amplify_e2e_tests - notifications-amplify_e2e_tests - - migration-node-function-amplify_e2e_tests + - schema-iterative-update-locking-amplify_e2e_tests - schema-auth-10-amplify_e2e_tests - hosting-amplify_e2e_tests - tags-amplify_e2e_tests - - api_4-amplify_e2e_tests + - migration-node-function-amplify_e2e_tests - done_with_pkg_linux_e2e_tests: context: amplify-cli-ecr requires: - hostingPROD-amplify_e2e_tests_pkg_linux - amplify-app-amplify_e2e_tests_pkg_linux - init-amplify_e2e_tests_pkg_linux - - schema-iterative-update-locking-amplify_e2e_tests_pkg_linux + - function_5-amplify_e2e_tests_pkg_linux - predictions-amplify_e2e_tests_pkg_linux - schema-predictions-amplify_e2e_tests_pkg_linux - amplify-configure-amplify_e2e_tests_pkg_linux - - function_5-amplify_e2e_tests_pkg_linux + - api_4-amplify_e2e_tests_pkg_linux - function_3-amplify_e2e_tests_pkg_linux - containers-api-amplify_e2e_tests_pkg_linux - interactions-amplify_e2e_tests_pkg_linux @@ -1905,11 +1905,11 @@ workflows: - schema-key-amplify_e2e_tests_pkg_linux - analytics-amplify_e2e_tests_pkg_linux - notifications-amplify_e2e_tests_pkg_linux - - migration-node-function-amplify_e2e_tests_pkg_linux + - schema-iterative-update-locking-amplify_e2e_tests_pkg_linux - schema-auth-10-amplify_e2e_tests_pkg_linux - hosting-amplify_e2e_tests_pkg_linux - tags-amplify_e2e_tests_pkg_linux - - api_4-amplify_e2e_tests_pkg_linux + - migration-node-function-amplify_e2e_tests_pkg_linux - amplify_migration_tests_latest: context: amplify-cli-ecr filters: @@ -2059,7 +2059,7 @@ workflows: filters: *ref_8 requires: - schema-auth-7-amplify_e2e_tests - - schema-iterative-update-locking-amplify_e2e_tests: + - function_5-amplify_e2e_tests: context: amplify-cli-ecr post-steps: *ref_7 filters: *ref_8 @@ -2119,7 +2119,7 @@ workflows: filters: *ref_8 requires: - auth_4-amplify_e2e_tests - - function_5-amplify_e2e_tests: + - api_4-amplify_e2e_tests: context: amplify-cli-ecr post-steps: *ref_7 filters: *ref_8 @@ -2335,7 +2335,7 @@ workflows: filters: *ref_8 requires: - schema-searchable-amplify_e2e_tests - - migration-node-function-amplify_e2e_tests: + - schema-iterative-update-locking-amplify_e2e_tests: context: amplify-cli-ecr post-steps: *ref_7 filters: *ref_8 @@ -2389,7 +2389,7 @@ workflows: filters: *ref_8 requires: - schema-auth-8-amplify_e2e_tests - - api_4-amplify_e2e_tests: + - migration-node-function-amplify_e2e_tests: context: amplify-cli-ecr post-steps: *ref_7 filters: *ref_8 @@ -2457,7 +2457,7 @@ workflows: filters: *ref_10 requires: - schema-auth-7-amplify_e2e_tests_pkg_linux - - schema-iterative-update-locking-amplify_e2e_tests_pkg_linux: + - function_5-amplify_e2e_tests_pkg_linux: context: amplify-cli-ecr post-steps: *ref_9 filters: *ref_10 @@ -2521,7 +2521,7 @@ workflows: filters: *ref_10 requires: - auth_4-amplify_e2e_tests_pkg_linux - - function_5-amplify_e2e_tests_pkg_linux: + - api_4-amplify_e2e_tests_pkg_linux: context: amplify-cli-ecr post-steps: *ref_9 filters: *ref_10 @@ -2753,7 +2753,7 @@ workflows: filters: *ref_10 requires: - schema-searchable-amplify_e2e_tests_pkg_linux - - migration-node-function-amplify_e2e_tests_pkg_linux: + - schema-iterative-update-locking-amplify_e2e_tests_pkg_linux: context: amplify-cli-ecr post-steps: *ref_9 filters: *ref_10 @@ -2811,7 +2811,7 @@ workflows: filters: *ref_10 requires: - schema-auth-8-amplify_e2e_tests_pkg_linux - - api_4-amplify_e2e_tests_pkg_linux: + - migration-node-function-amplify_e2e_tests_pkg_linux: context: amplify-cli-ecr post-steps: *ref_9 filters: *ref_10 diff --git a/packages/amplify-cli-core/src/errors/index.ts b/packages/amplify-cli-core/src/errors/index.ts index 1fb2bd1da3f..bcad7f9a356 100644 --- a/packages/amplify-cli-core/src/errors/index.ts +++ b/packages/amplify-cli-core/src/errors/index.ts @@ -15,3 +15,4 @@ export class AppNotFoundError extends Error {} export class AppAlreadyDeployedError extends Error {} export class SchemaDoesNotExistError extends Error {} export class AngularConfigNotFoundError extends Error {} +export class AppIdMismatchError extends Error {} diff --git a/packages/amplify-cli/src/commands/configure.ts b/packages/amplify-cli/src/commands/configure.ts index 86dd8167e8b..a7e52eb3659 100644 --- a/packages/amplify-cli/src/commands/configure.ts +++ b/packages/amplify-cli/src/commands/configure.ts @@ -27,7 +27,7 @@ export const run = async (context: Context) => { await providerPlugin.adminLoginFlow(context, appId, envName); } catch (e) { context.print.error(`Failed to authenticate: ${e.message || 'Unknown error occurred.'}`); - context.usageData.emitError(e); + await context.usageData.emitError(e); process.exit(1); } return; diff --git a/packages/amplify-cli/src/commands/publish.ts b/packages/amplify-cli/src/commands/publish.ts index 6bfb2031322..18ff7a77a6e 100644 --- a/packages/amplify-cli/src/commands/publish.ts +++ b/packages/amplify-cli/src/commands/publish.ts @@ -43,7 +43,7 @@ export const run = async context => { } } catch (e) { context.print.error(`An error occurred during the publish operation: ${e.message || 'Unknown error occurred.'}`); - context.usageData.emitError(new FrontendBuildError(e.message)); + await context.usageData.emitError(new FrontendBuildError(e.message)); process.exit(1); } }; diff --git a/packages/amplify-cli/src/commands/pull.ts b/packages/amplify-cli/src/commands/pull.ts index d07fb84eb2f..ac262edeff1 100644 --- a/packages/amplify-cli/src/commands/pull.ts +++ b/packages/amplify-cli/src/commands/pull.ts @@ -3,7 +3,7 @@ import { preDeployPullBackend } from '../pre-deployment-pull'; import { attachBackend } from '../attach-backend'; import { constructInputParams } from '../amplify-service-helper'; import { run as envCheckout } from './env/checkout'; -import { $TSContext, stateManager } from 'amplify-cli-core'; +import { $TSContext, stateManager, EnvironmentDoesNotExistError, AppIdMismatchError } from 'amplify-cli-core'; import _ from 'lodash'; export const run = async (context: $TSContext) => { @@ -31,11 +31,13 @@ export const run = async (context: $TSContext) => { if (inputAppId && appId && inputAppId !== appId) { context.print.error('Amplify appId mismatch.'); context.print.info(`You are currently working in the amplify project with Id ${appId}`); + await context.usageData.emitError(new AppIdMismatchError()); process.exit(1); } else if (!appId) { context.print.error(`Environment '${envName}' not found.`); context.print.info(`Try running "amplify env add" to add a new environment.`); context.print.info(`If this backend already exists, try restoring its definition in your team-provider-info.json file.`); + await context.usageData.emitError(new EnvironmentDoesNotExistError()); process.exit(1); } diff --git a/packages/amplify-cli/src/initialize-env.ts b/packages/amplify-cli/src/initialize-env.ts index ef153c3145e..0679d9d99c1 100644 --- a/packages/amplify-cli/src/initialize-env.ts +++ b/packages/amplify-cli/src/initialize-env.ts @@ -66,6 +66,7 @@ export async function initializeEnv(context: $TSContext, currentAmplifyMeta?: $T await sequential(initializationTasks); } catch (e) { context.print.error(`Could not initialize '${currentEnv}': ${e.message}`); + context.usageData.emitError(e); process.exit(1); } From 77bf95aa397a9f8593347723995fc9517de44555 Mon Sep 17 00:00:00 2001 From: AmmarKarachi Date: Tue, 30 Mar 2021 10:56:28 -0700 Subject: [PATCH 4/6] refactor: simplify assign --- packages/amplify-cli/src/context-manager.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/amplify-cli/src/context-manager.ts b/packages/amplify-cli/src/context-manager.ts index 486ce06a9f3..aa2eec0cfac 100644 --- a/packages/amplify-cli/src/context-manager.ts +++ b/packages/amplify-cli/src/context-manager.ts @@ -31,19 +31,17 @@ export async function attachUsageData(context: Context) { const getVersion = (context: Context) => context.pluginPlatform.plugins.core[0].packageVersion; const getProjectSettings = (): ProjectSettings => { - const projectSettings = {}; + const projectSettings: ProjectSettings = {}; if (stateManager.projectConfigExists()) { const projectConfig = stateManager.getProjectConfig(); const frontend = projectConfig['frontend']; - projectSettings['frontend'] = frontend; - if (projectConfig[frontend] && projectConfig[frontend].framework) { - projectSettings['framework'] = projectConfig[frontend].framework; - } + projectSettings.frontend = frontend; + projectSettings.framework = projectConfig?.[frontend].framework; } if (stateManager.localEnvInfoExists()) { const { defaultEditor } = stateManager.getLocalEnvInfo(); - projectSettings['editor'] = defaultEditor; + projectSettings.editor = defaultEditor; } return projectSettings; From 36d9dae0529fd3aa9682246e5a17a61741a3c859 Mon Sep 17 00:00:00 2001 From: AmmarKarachi Date: Tue, 6 Apr 2021 15:15:20 -0700 Subject: [PATCH 5/6] refactor: pr comments --- packages/amplify-cli/src/__tests__/context-manager.test.ts | 2 +- .../amplify-cli/src/domain/amplify-usageData/NoUsageData.ts | 3 ++- .../src/domain/amplify-usageData/UsageDataPayload.ts | 5 +---- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/amplify-cli/src/__tests__/context-manager.test.ts b/packages/amplify-cli/src/__tests__/context-manager.test.ts index 9246b4d8086..5a6783ace5f 100644 --- a/packages/amplify-cli/src/__tests__/context-manager.test.ts +++ b/packages/amplify-cli/src/__tests__/context-manager.test.ts @@ -25,7 +25,7 @@ jest.mock('../app-config'); describe('test attachUsageData', () => { const version = 'latestversion'; - let mockContext = jest.genMockFromModule('../domain/context'); + const mockContext = jest.genMockFromModule('../domain/context'); mockContext.input = new Input([ '/Users/userName/.nvm/versions/node/v8.11.4/bin/node', diff --git a/packages/amplify-cli/src/domain/amplify-usageData/NoUsageData.ts b/packages/amplify-cli/src/domain/amplify-usageData/NoUsageData.ts index 132ca243112..b24b66caade 100644 --- a/packages/amplify-cli/src/domain/amplify-usageData/NoUsageData.ts +++ b/packages/amplify-cli/src/domain/amplify-usageData/NoUsageData.ts @@ -13,7 +13,8 @@ export class NoUsageData implements IUsageData { emitSuccess(): Promise { return Promise.resolve(); } - init(installationUuid: String, version: String, input: any, accountId: string): void {} + + init(installationUuid: string, version: String, input: any, accountId: string): void {} private static instance: NoUsageData; static get Instance(): IUsageData { diff --git a/packages/amplify-cli/src/domain/amplify-usageData/UsageDataPayload.ts b/packages/amplify-cli/src/domain/amplify-usageData/UsageDataPayload.ts index 10d4ef8a370..e042d49541a 100644 --- a/packages/amplify-cli/src/domain/amplify-usageData/UsageDataPayload.ts +++ b/packages/amplify-cli/src/domain/amplify-usageData/UsageDataPayload.ts @@ -55,10 +55,7 @@ export type ProjectSettings = { framework?: string; }; -export type InputOptions = { - [key: string]: string | boolean; -}; - +export type InputOptions = Record; export class SerializableError { name: string; constructor(error: Error) { From a76bf0be6a7148f9ebb4f88a1633106b6aa454d2 Mon Sep 17 00:00:00 2001 From: AmmarKarachi Date: Tue, 6 Apr 2021 16:45:48 -0700 Subject: [PATCH 6/6] refactor: changed sts to singleton --- .../src/amplify-sts.ts | 4 +-- .../src/aws-utils/aws-sts.ts | 27 ++++++++++++------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/packages/amplify-provider-awscloudformation/src/amplify-sts.ts b/packages/amplify-provider-awscloudformation/src/amplify-sts.ts index d27451da93d..c6ecedcbd96 100644 --- a/packages/amplify-provider-awscloudformation/src/amplify-sts.ts +++ b/packages/amplify-provider-awscloudformation/src/amplify-sts.ts @@ -1,9 +1,9 @@ import { STS } from './aws-utils/aws-sts'; export async function getAccountId(context) { - const amplifySts = await new STS(context); + const amplifySts = await STS.getInstance(context); try { - const data = await amplifySts.sts.getCallerIdentity().promise(); + const data = await amplifySts.getCallerIdentity(); return data.Account; } catch (ex) { return ''; diff --git a/packages/amplify-provider-awscloudformation/src/aws-utils/aws-sts.ts b/packages/amplify-provider-awscloudformation/src/aws-utils/aws-sts.ts index 8db887b6c8e..f2e6b2a024c 100644 --- a/packages/amplify-provider-awscloudformation/src/aws-utils/aws-sts.ts +++ b/packages/amplify-provider-awscloudformation/src/aws-utils/aws-sts.ts @@ -1,13 +1,14 @@ -import AWS from 'aws-sdk'; -import aws from './aws'; +import aws from './aws.js'; import { loadConfiguration } from '../configuration-manager'; -import { $TSContext } from 'amplify-cli-core'; +import { $TSAny, $TSContext } from 'amplify-cli-core'; export class STS { - public sts: AWS.STS; + private static instance: STS; + private readonly context: $TSContext; + private readonly sts: AWS.STS; - constructor(private readonly context: $TSContext, options = {}) { - const instancePromise = (async () => { + static async getInstance(context: $TSContext, options = {}): Promise { + if (!STS.instance) { let cred = {}; try { cred = await loadConfiguration(context); @@ -15,11 +16,17 @@ export class STS { // ignore missing config } - this.sts = new (aws as typeof AWS).STS({ ...cred, ...options }); + STS.instance = new STS(context, cred, options); + } + return STS.instance; + } - return this; - })(); + private constructor(context: $TSContext, cred: $TSAny, options = {}) { + this.context = context; + this.sts = new aws.STS({ ...cred, options }); + } - return (instancePromise); + async getCallerIdentity(): Promise { + return await this.sts.getCallerIdentity().promise(); } }