Skip to content

Commit

Permalink
feat: inject project info into overrides (#12064)
Browse files Browse the repository at this point in the history
* feat: inject project info into overrides

* chore: format

* chore: rename

* chore: make project info readonly

* chore: api

* chore: some pr feedback

* chore: better tests

* chore: fix test

* chore: fix typo
  • Loading branch information
sobolk authored Feb 22, 2023
1 parent d80419d commit 9ceaefa
Show file tree
Hide file tree
Showing 24 changed files with 133 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AmplifyAuthCognitoStackTemplate } from '@aws-amplify/cli-extensibility-helper';
import { AmplifyAuthCognitoStackTemplate, AmplifyProjectInfo } from '@aws-amplify/cli-extensibility-helper';

export function override(resources: AmplifyAuthCognitoStackTemplate, amplifyProjectInfo: AmplifyProjectInfo) {

export function override(resources: AmplifyAuthCognitoStackTemplate) {

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AmplifyUserPoolGroupStackTemplate } from '@aws-amplify/cli-extensibility-helper';
import { AmplifyProjectInfo, AmplifyUserPoolGroupStackTemplate } from '@aws-amplify/cli-extensibility-helper';

export function override(resources: AmplifyUserPoolGroupStackTemplate, amplifyProjectInfo: AmplifyProjectInfo) {

export function override(resources: AmplifyUserPoolGroupStackTemplate) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { generateNestedAuthTriggerTemplate } from '../utils/generate-auth-trigge
import { createUserPoolGroups, updateUserPoolGroups } from '../utils/synthesize-resources';
import { AmplifyAuthCognitoStack } from './auth-cognito-stack-builder';
import { AuthStackSynthesizer } from './stack-synthesizer';
import { getProjectInfo } from '@aws-amplify/cli-extensibility-helper';

/**
* Class to handle Auth cdk generation / override functionality
Expand Down Expand Up @@ -123,10 +124,11 @@ export class AmplifyAuthTransform extends AmplifyCategoryTransform {
external: true,
},
});
const projectInfo = getProjectInfo();
try {
await sandboxNode
.run(overrideCode, path.join(overrideDir, 'build', 'override.js'))
.override(this._authTemplateObj as AmplifyAuthCognitoStack & AmplifyStackTemplate);
.override(this._authTemplateObj as AmplifyAuthCognitoStack & AmplifyStackTemplate, projectInfo);
} catch (err) {
throw new AmplifyError(
'InvalidOverrideError',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { AuthInputState } from '../auth-inputs-manager/auth-input-state';
import { CognitoCLIInputs } from '../service-walkthrough-types/awsCognito-user-input-types';
import { AmplifyUserPoolGroupStack, AmplifyUserPoolGroupStackOutputs } from './index';
import { AuthStackSynthesizer } from './stack-synthesizer';
import { getProjectInfo } from '@aws-amplify/cli-extensibility-helper';

/**
* UserPool groups metadata
Expand Down Expand Up @@ -194,8 +195,11 @@ export class AmplifyUserPoolGroupTransform extends AmplifyCategoryTransform {
timeout: 5000,
sandbox: {},
});
const projectInfo = getProjectInfo();
try {
await sandboxNode.run(overrideCode).override(this._userPoolGroupTemplateObj as AmplifyUserPoolGroupStack & AmplifyStackTemplate);
await sandboxNode
.run(overrideCode)
.override(this._userPoolGroupTemplateObj as AmplifyUserPoolGroupStack & AmplifyStackTemplate, projectInfo);
} catch (err: $TSAny) {
throw new AmplifyError(
'InvalidOverrideError',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AmplifyDDBResourceTemplate } from '@aws-amplify/cli-extensibility-helper';
import { AmplifyDDBResourceTemplate, AmplifyProjectInfo } from '@aws-amplify/cli-extensibility-helper';

export function override(resources: AmplifyDDBResourceTemplate, amplifyProjectInfo: AmplifyProjectInfo) {

export function override(resources: AmplifyDDBResourceTemplate) {

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AmplifyS3ResourceTemplate } from '@aws-amplify/cli-extensibility-helper';
import { AmplifyProjectInfo, AmplifyS3ResourceTemplate } from '@aws-amplify/cli-extensibility-helper';

export function override(resources: AmplifyS3ResourceTemplate, amplifyProjectInfo: AmplifyProjectInfo) {

export function override(resources: AmplifyS3ResourceTemplate) {

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AmplifyDDBResourceTemplate } from '@aws-amplify/cli-extensibility-helper';
import { AmplifyDDBResourceTemplate, getProjectInfo } from '@aws-amplify/cli-extensibility-helper';
import { $TSAny, $TSContext, AmplifyError, buildOverrideDir, JSONUtilities, pathManager } from 'amplify-cli-core';
import { formatter } from 'amplify-prompts';
import * as cdk from 'aws-cdk-lib';
Expand Down Expand Up @@ -214,8 +214,11 @@ export class DDBStackTransform {
external: true,
},
});
const projectInfo = getProjectInfo();
try {
await sandboxNode.run(overrideCode, overrideJSFilePath).override(this._resourceTemplateObj as AmplifyDDBResourceTemplate);
await sandboxNode
.run(overrideCode, overrideJSFilePath)
.override(this._resourceTemplateObj as AmplifyDDBResourceTemplate, projectInfo);
} catch (err) {
throw new AmplifyError(
'InvalidOverrideError',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as cdk from 'aws-cdk-lib';
import { AmplifyS3ResourceTemplate } from '@aws-amplify/cli-extensibility-helper';
import { AmplifyS3ResourceTemplate, getProjectInfo } from '@aws-amplify/cli-extensibility-helper';
import {
$TSAny,
$TSContext,
Expand Down Expand Up @@ -223,7 +223,10 @@ export class AmplifyS3ResourceStackTransform {
},
});
try {
await sandboxNode.run(overrideCode, overrideJSFilePath).override(this.resourceTemplateObj as AmplifyS3ResourceTemplate);
const projectInfo = getProjectInfo();
await sandboxNode
.run(overrideCode, overrideJSFilePath)
.override(this.resourceTemplateObj as AmplifyS3ResourceTemplate, projectInfo);
} catch (err: $TSAny) {
throw new AmplifyError(
'InvalidOverrideError',
Expand Down
4 changes: 2 additions & 2 deletions packages/amplify-cli-extensibility-helper/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,10 @@ export interface AmplifyDDBResourceTemplate extends AmplifyCDKL1 {
}

// @public (undocumented)
export type AmplifyProjectInfo = {
export type AmplifyProjectInfo = Readonly<{
envName: string;
projectName: string;
};
}>;

export { AmplifyResourceProps }

Expand Down
4 changes: 2 additions & 2 deletions packages/amplify-cli-extensibility-helper/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* PUBLIC API: Amplify project type
*/
export type AmplifyProjectInfo = {
export type AmplifyProjectInfo = Readonly<{
envName: string;
projectName: string;
};
}>;
1 change: 1 addition & 0 deletions packages/amplify-e2e-core/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export * from './appsync';
export * from './envVars';
export * from './getAppId';
export * from './headless';
export * from './overrides';
export * from './nexpect';
export * from './pinpoint';
export * from './projectMeta';
Expand Down
7 changes: 7 additions & 0 deletions packages/amplify-e2e-core/src/utils/overrides.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as fs from 'fs-extra';

export const replaceOverrideFileWithProjectInfo = (srcPath: string, destPath: string, envName: string, projectName: string) => {
const content = fs.readFileSync(srcPath).toString();
const contentWithProjectInfo = content.replace('##EXPECTED_ENV_NAME', envName).replace('##EXPECTED_PROJECT_NAME', projectName);
fs.writeFileSync(destPath, contentWithProjectInfo);
};
17 changes: 15 additions & 2 deletions packages/amplify-e2e-tests/overrides/override-auth.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
export function override(props: any): any {
import { AmplifyProjectInfo, AmplifyAuthCognitoStackTemplate } from '@aws-amplify/cli-extensibility-helper';

export function override(props: AmplifyAuthCognitoStackTemplate, amplifyProjectInfo: AmplifyProjectInfo): void {
props.userPool.deviceConfiguration = {
challengeRequiredOnNewDevice: true,
};
props.userPool.userAttributeUpdateSettings = {
attributesRequireVerificationBeforeUpdate: ['email'],
};
return props;

if (!amplifyProjectInfo || !amplifyProjectInfo.envName || !amplifyProjectInfo.projectName) {
throw new Error(`Project info is missing in override: ${JSON.stringify(amplifyProjectInfo)}`);
}

if (amplifyProjectInfo.envName != '##EXPECTED_ENV_NAME') {
throw new Error(`Unexpected envName: ${amplifyProjectInfo.envName}`);
}

if (amplifyProjectInfo.projectName != '##EXPECTED_PROJECT_NAME') {
throw new Error(`Unexpected envName: ${amplifyProjectInfo.envName}`);
}
}
17 changes: 15 additions & 2 deletions packages/amplify-e2e-tests/overrides/override-root.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import { AmplifyProjectInfo, AmplifyRootStackTemplate } from '@aws-amplify/cli-extensibility-helper';

function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
export function override(props: any): void {
export function override(props: AmplifyRootStackTemplate, amplifyProjectInfo: AmplifyProjectInfo): void {
props.authRole.roleName = `mockRole-${getRandomInt(10000)}`;
return props;

if (!amplifyProjectInfo || !amplifyProjectInfo.envName || !amplifyProjectInfo.projectName) {
throw new Error(`Project info is missing in override: ${JSON.stringify(amplifyProjectInfo)}`);
}

if (amplifyProjectInfo.envName != '##EXPECTED_ENV_NAME') {
throw new Error(`Unexpected envName: ${amplifyProjectInfo.envName}`);
}

if (amplifyProjectInfo.projectName != '##EXPECTED_PROJECT_NAME') {
throw new Error(`Unexpected envName: ${amplifyProjectInfo.envName}`);
}
}
16 changes: 15 additions & 1 deletion packages/amplify-e2e-tests/overrides/override-storage-ddb.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
export function override(props: any) {
import { AmplifyDDBResourceTemplate, AmplifyProjectInfo } from '@aws-amplify/cli-extensibility-helper';

export function override(props: AmplifyDDBResourceTemplate, amplifyProjectInfo: AmplifyProjectInfo): void {
props.dynamoDBTable.streamSpecification = {
streamViewType: 'NEW_AND_OLD_IMAGES',
};

if (!amplifyProjectInfo || !amplifyProjectInfo.envName || !amplifyProjectInfo.projectName) {
throw new Error(`Project info is missing in override: ${JSON.stringify(amplifyProjectInfo)}`);
}

if (amplifyProjectInfo.envName != '##EXPECTED_ENV_NAME') {
throw new Error(`Unexpected envName: ${amplifyProjectInfo.envName}`);
}

if (amplifyProjectInfo.projectName != '##EXPECTED_PROJECT_NAME') {
throw new Error(`Unexpected envName: ${amplifyProjectInfo.envName}`);
}
}
16 changes: 15 additions & 1 deletion packages/amplify-e2e-tests/overrides/override-storage-s3.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
export function override(props: any) {
import { AmplifyProjectInfo, AmplifyS3ResourceTemplate } from '@aws-amplify/cli-extensibility-helper';

export function override(props: AmplifyS3ResourceTemplate, amplifyProjectInfo: AmplifyProjectInfo) {
//Enable versioning on the bucket
props.s3Bucket.versioningConfiguration = {
status: 'Enabled',
};

if (!amplifyProjectInfo || !amplifyProjectInfo.envName || !amplifyProjectInfo.projectName) {
throw new Error(`Project info is missing in override: ${JSON.stringify(amplifyProjectInfo)}`);
}

if (amplifyProjectInfo.envName != '##EXPECTED_ENV_NAME') {
throw new Error(`Unexpected envName: ${amplifyProjectInfo.envName}`);
}

if (amplifyProjectInfo.projectName != '##EXPECTED_PROJECT_NAME') {
throw new Error(`Unexpected envName: ${amplifyProjectInfo.envName}`);
}
}
3 changes: 2 additions & 1 deletion packages/amplify-e2e-tests/src/__tests__/auth_6.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
getProjectMeta,
getUserPool,
initJSProjectWithProfile,
replaceOverrideFileWithProjectInfo,
runAmplifyAuthConsole,
} from '@aws-amplify/amplify-e2e-core';
import * as path from 'path';
Expand Down Expand Up @@ -101,7 +102,7 @@ describe('zero config auth', () => {

// test happy path
const srcOverrideFilePath = path.join(__dirname, '..', '..', 'overrides', 'override-auth.ts');
fs.copyFileSync(srcOverrideFilePath, destOverrideFilePath);
replaceOverrideFileWithProjectInfo(srcOverrideFilePath, destOverrideFilePath, 'integtest', PROJECT_NAME);
await amplifyPushOverride(projRoot);

// check overwritten config
Expand Down
7 changes: 5 additions & 2 deletions packages/amplify-e2e-tests/src/__tests__/init_e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
createNewProjectDir,
deleteProjectDir,
getProjectMeta,
replaceOverrideFileWithProjectInfo,
} from '@aws-amplify/amplify-e2e-core';

import { addEnvironment } from '../environment/env';
Expand All @@ -27,7 +28,8 @@ describe('amplify init e', () => {
});

it('should init the project and override root and push', async () => {
await initJSProjectWithProfile(projRoot, {});
const projectName = 'initTest';
await initJSProjectWithProfile(projRoot, { name: projectName });
const meta = getProjectMeta(projRoot).providers.awscloudformation;
expect(meta.Region).toBeDefined();
const { AuthRoleName, UnauthRoleName, UnauthRoleArn, AuthRoleArn, DeploymentBucketName } = meta;
Expand All @@ -54,12 +56,13 @@ describe('amplify init e', () => {

// test happy path
const srcOverrideFilePath = path.join(__dirname, '..', '..', 'overrides', 'override-root.ts');
fs.copyFileSync(srcOverrideFilePath, destOverrideFilePath);
replaceOverrideFileWithProjectInfo(srcOverrideFilePath, destOverrideFilePath, 'integtest', projectName);
await amplifyPushOverride(projRoot);
const newEnvMeta = getProjectMeta(projRoot).providers.awscloudformation;
expect(newEnvMeta.AuthRoleName).toContain('mockRole');

// create a new env, and the override should remain in place
replaceOverrideFileWithProjectInfo(srcOverrideFilePath, destOverrideFilePath, 'envb', projectName);
await addEnvironment(projRoot, { envName: 'envb' });
const newestEnvMeta = getProjectMeta(projRoot).providers.awscloudformation;
expect(newestEnvMeta.AuthRoleName).toContain('mockRole');
Expand Down
11 changes: 7 additions & 4 deletions packages/amplify-e2e-tests/src/__tests__/storage-5.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
initJSProjectWithProfile,
overrideDDB,
overrideS3,
replaceOverrideFileWithProjectInfo,
updateDDBWithTrigger,
updateSimpleDDBwithGSI,
} from '@aws-amplify/amplify-e2e-core';
Expand Down Expand Up @@ -44,7 +45,8 @@ describe('s3 override tests', () => {
});

it('override S3 Removal property', async () => {
await initJSProjectWithProfile(projRoot, {});
const projectName = 's3OverrideTest';
await initJSProjectWithProfile(projRoot, { name: projectName });
await addAuthWithDefault(projRoot, {});
await addS3WithGuestAccess(projRoot, {});
await overrideS3(projRoot);
Expand All @@ -68,7 +70,7 @@ describe('s3 override tests', () => {
// test happy path
const srcOverrideFilePath = path.join(__dirname, '..', '..', 'overrides', 'override-storage-s3.ts');
const cfnFilePath = path.join(projRoot, 'amplify', 'backend', 'storage', resourceName, 'build', 'cloudformation-template.json');
fs.copyFileSync(srcOverrideFilePath, destOverrideFilePath);
replaceOverrideFileWithProjectInfo(srcOverrideFilePath, destOverrideFilePath, 'integtest', projectName);
await buildOverrideStorage(projRoot);
let s3CFNFileJSON = JSONUtilities.readJson<$TSObject>(cfnFilePath);
// check if overrides are applied to the cfn file
Expand Down Expand Up @@ -173,7 +175,8 @@ describe('ddb override tests', () => {

it('override DDB StreamSpecification property', async () => {
const resourceName = `dynamo${uuid.v4().split('-')[0]}`;
await initJSProjectWithProfile(projRoot, {});
const projectName = 'ddbOverrideTest';
await initJSProjectWithProfile(projRoot, { name: projectName });
await addSimpleDDB(projRoot, { name: resourceName });
await overrideDDB(projRoot);

Expand Down Expand Up @@ -204,7 +207,7 @@ describe('ddb override tests', () => {
`${resourceName}-cloudformation-template.json`,
);

fs.copyFileSync(srcOverrideFilePath, destOverrideFilePath);
replaceOverrideFileWithProjectInfo(srcOverrideFilePath, destOverrideFilePath, 'integtest', projectName);
await buildOverrideStorage(projRoot);
let ddbCFNFileJSON = JSONUtilities.readJson<$TSObject>(cfnFilePath);
// check if overrides are applied to the cfn file
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as fs from 'fs-extra';
import * as path from 'path';
import {
deleteProject,
Expand All @@ -7,6 +6,7 @@ import {
deleteProjectDir,
getProjectMeta,
amplifyPushOverride,
replaceOverrideFileWithProjectInfo,
} from '@aws-amplify/amplify-e2e-core';
import { JSONUtilities } from 'amplify-cli-core';
import { versionCheck, allowedVersionsToMigrateFrom, initJSProjectWithProfileV4_52_0 } from '../../../migration-helpers';
Expand All @@ -30,7 +30,8 @@ describe('amplify init', () => {
});

it('should init the project and override root and push', async () => {
await initJSProjectWithProfileV4_52_0(projRoot, {});
const projectName = 'initMigrationTest';
await initJSProjectWithProfileV4_52_0(projRoot, { name: projectName });
const meta = getProjectMeta(projRoot).providers.awscloudformation;
expect(meta.Region).toBeDefined();
// turn ON feature flag
Expand All @@ -42,7 +43,7 @@ describe('amplify init', () => {
await amplifyOverrideRoot(projRoot, { testingWithLatestCodebase: true });
const srcOverrideFilePath = path.join(__dirname, '..', '..', '..', '..', '..', 'amplify-e2e-tests', 'overrides', 'override-root.ts');
const destOverrideFilePath = path.join(projRoot, 'amplify', 'backend', 'awscloudformation', 'override.ts');
fs.copyFileSync(srcOverrideFilePath, destOverrideFilePath);
replaceOverrideFileWithProjectInfo(srcOverrideFilePath, destOverrideFilePath, 'integtest', projectName);
await amplifyPushOverride(projRoot, true);
const newEnvMeta = getProjectMeta(projRoot).providers.awscloudformation;
expect(newEnvMeta.AuthRoleName).toContain('mockRole');
Expand Down
Loading

0 comments on commit 9ceaefa

Please sign in to comment.