diff --git a/.circleci/config.base.yml b/.circleci/config.base.yml index baf0f53df42..f8bd05a7a24 100644 --- a/.circleci/config.base.yml +++ b/.circleci/config.base.yml @@ -654,6 +654,36 @@ jobs: path: ~/repo/packages/amplify-migration-tests/amplify-migration-reports working_directory: ~/repo + amplify_general_config_tests: + parameters: + os: + type: executor + default: l_large + executor: << parameters.os >> + environment: + AMPLIFY_PATH: /home/circleci/.npm-global/lib/node_modules/@aws-amplify/cli/bin/amplify + steps: + - restore_cache: + key: amplify-cli-repo-{{ .Branch }}-{{ .Revision }} + - restore_cache: + key: amplify-cli-yarn-deps-{{ .Branch }}-{{ checksum "yarn.lock" }} + - restore_cache: + key: amplify-pkg-binaries-{{ .Branch }}-{{ .Revision }} + - run: + name: Run tests using general profile + command: | + source .circleci/local_publish_helpers.sh + changeNpmGlobalPath + cd packages/amplify-e2e-tests + retry yarn run general-config-e2e --no-cache --maxWorkers=3 --forceExit $TEST_SUITE + no_output_timeout: 90m + - run: *scan_e2e_test_artifacts + - store_test_results: + path: ~/repo/packages/amplify-e2e-tests/ + - store_artifacts: + path: ~/repo/packages/amplify-e2e-tests/amplify-e2e-reports + working_directory: ~/repo + amplify_console_integration_tests: parameters: os: @@ -1156,6 +1186,20 @@ workflows: - /run-e2e\/.*/ requires: - upload_pkg_binaries + - amplify_general_config_tests: + context: + - e2e-auth-credentials + - cleanup-resources + - e2e-test-context + filters: + branches: + only: + - dev + - /run-e2e-with-rc\/.*/ + - /tagged-release\/.*/ + - /run-e2e\/.*/ + requires: + - upload_pkg_binaries - amplify_console_integration_tests: context: - e2e-auth-credentials diff --git a/packages/amplify-e2e-core/src/init/non-interactive-init.ts b/packages/amplify-e2e-core/src/init/non-interactive-init.ts index e55378bf7d0..3b7356121d8 100644 --- a/packages/amplify-e2e-core/src/init/non-interactive-init.ts +++ b/packages/amplify-e2e-core/src/init/non-interactive-init.ts @@ -9,8 +9,8 @@ import { CategoriesConfig, AwsProviderConfig } from './headless-types'; export const nonInteractiveInitAttach = async ( projRoot: string, amplifyInitConfig: AmplifyInitConfig, + awsProviderConfig: AwsProviderConfig | AwsProviderGeneralConfig, categoriesConfig?: CategoriesConfig, - awsProviderConfig = getAwsProviderConfig(), ): Promise => { const args = [ 'init', @@ -67,10 +67,23 @@ export const getAmplifyInitConfig = (projectName: string, envName: string): Ampl /** * Returns a default AwsProviderConfig */ -export const getAwsProviderConfig = (): AwsProviderConfig => ({ - configLevel: 'project', - useProfile: true, - profileName: TEST_PROFILE_NAME, +export const getAwsProviderConfig = (profileType?: string): AwsProviderConfig | AwsProviderGeneralConfig => { + if (profileType === 'general') { + return getAwsProviderGeneralConfig(); + } else { + return { + configLevel: 'project', + useProfile: true, + profileName: TEST_PROFILE_NAME, + }; + } +}; + +/** + * Returns a general AwsProviderConfig + */ +export const getAwsProviderGeneralConfig = (): AwsProviderGeneralConfig => ({ + configLevel: 'general', }); /** @@ -82,3 +95,7 @@ export type AmplifyInitConfig = { defaultEditor: string; frontend?: string; }; + +export type AwsProviderGeneralConfig = { + configLevel: string; +}; diff --git a/packages/amplify-e2e-tests/package.json b/packages/amplify-e2e-tests/package.json index 4805d2b172e..92b9cc77a6d 100644 --- a/packages/amplify-e2e-tests/package.json +++ b/packages/amplify-e2e-tests/package.json @@ -18,6 +18,7 @@ "private": true, "scripts": { "e2e": "npm run setup-profile && jest --verbose", + "general-config-e2e": "jest src/__tests__/general-config/general-config-headless-init.test.ts --verbose", "build-tests": "tsc --build tsconfig.tests.json", "setup-profile": "ts-node ./src/configure_tests.ts", "clean-e2e-resources": "ts-node ./src/cleanup-e2e-resources.ts" diff --git a/packages/amplify-e2e-tests/src/__tests__/general-config/general-config-headless-init.test.ts b/packages/amplify-e2e-tests/src/__tests__/general-config/general-config-headless-init.test.ts new file mode 100644 index 00000000000..57d45b081f2 --- /dev/null +++ b/packages/amplify-e2e-tests/src/__tests__/general-config/general-config-headless-init.test.ts @@ -0,0 +1,33 @@ +/** + * Tests for headless init/pull workflows on git-cloned projects + * These tests exercise workflows that hosting executes during backend builds + */ + +import { + createNewProjectDir, + deleteProject, + deleteProjectDir, + getAmplifyInitConfig, + getAwsProviderConfig, + nonInteractiveInitAttach, +} from '@aws-amplify/amplify-e2e-core'; +import {} from '@aws-amplify/amplify-e2e-core'; + +describe('attach amplify to git-cloned project', () => { + const envName = 'test'; + const projectName = 'initGeneral'; + let projRoot: string; + beforeAll(async () => { + projRoot = await createNewProjectDir('clone-test'); + }); + + afterAll(async () => { + await deleteProject(projRoot); + deleteProjectDir(projRoot); + }); + + test('headless init works with general profile', async () => { + // execute headless init + await nonInteractiveInitAttach(projRoot, getAmplifyInitConfig(projectName, envName), getAwsProviderConfig('general')); + }); +}); diff --git a/packages/amplify-e2e-tests/src/__tests__/git-clone-attach.test.ts b/packages/amplify-e2e-tests/src/__tests__/git-clone-attach.test.ts index 363c3a17856..f19cd72ce96 100644 --- a/packages/amplify-e2e-tests/src/__tests__/git-clone-attach.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/git-clone-attach.test.ts @@ -13,6 +13,7 @@ import { deleteProjectDir, getAmplifyInitConfig, getAmplifyPullConfig, + getAwsProviderConfig, getProjectConfig, getSocialProviders, getTeamProviderInfo, @@ -76,7 +77,7 @@ describe('attach amplify to git-cloned project', () => { region: importBucketRegion, }, }; - await nonInteractiveInitAttach(projRoot, getAmplifyInitConfig(projectName, envName), categoriesConfig); + await nonInteractiveInitAttach(projRoot, getAmplifyInitConfig(projectName, envName), getAwsProviderConfig(), categoriesConfig); await buildOverrides(projRoot); // expect no file changes diff --git a/packages/amplify-provider-awscloudformation/src/__tests__/amplify-service-manager.test.ts b/packages/amplify-provider-awscloudformation/src/__tests__/amplify-service-manager.test.ts index 52bc1f0dc84..56bc1bce17a 100644 --- a/packages/amplify-provider-awscloudformation/src/__tests__/amplify-service-manager.test.ts +++ b/packages/amplify-provider-awscloudformation/src/__tests__/amplify-service-manager.test.ts @@ -37,4 +37,32 @@ describe('init', () => { `[ProjectInitError: You have reached the Amplify App limit for this account and region]`, ); }); + + it('throws Configutation error if config level is general and soorcing wrong credentials', async () => { + const amplifyClientGeneralConfigStub = { + createApp: jest.fn().mockReturnValue({ + promise: jest.fn().mockRejectedValue({ + code: 'ConfigError', + message: 'Missing Region in Config', + }), + }), + } as unknown as Amplify; + getConfiguredAmplifyClientMock.mockClear(); + getConfiguredAmplifyClientMock.mockResolvedValue(amplifyClientGeneralConfigStub); + + const amplifyServiceParamsStub = { + context: { + exeInfo: { + awsConfigInfo: { + configLevel: 'general', + }, + }, + }, + awsConfigInfo: {}, + projectName: 'test-project', + envName: 'test', + stackName: 'test-stack-name', + }; + await expect(init(amplifyServiceParamsStub)).rejects.toMatchInlineSnapshot(`[ConfigurationError: Missing Region in Config]`); + }); }); diff --git a/packages/amplify-provider-awscloudformation/src/amplify-service-manager.ts b/packages/amplify-provider-awscloudformation/src/amplify-service-manager.ts index 7ab3c18f7b6..64d8909f0d2 100644 --- a/packages/amplify-provider-awscloudformation/src/amplify-service-manager.ts +++ b/packages/amplify-provider-awscloudformation/src/amplify-service-manager.ts @@ -142,6 +142,14 @@ export async function init(amplifyServiceParams) { e, ); } + if (context?.exeInfo?.awsConfigInfo?.configLevel === 'general' && e.code === 'ConfigError') { + throw new AmplifyError('ConfigurationError', { + code: e.code, + message: e.message, + resolution: 'https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html', + }); + } + // default fault throw new AmplifyFault( 'ProjectInitFault', { diff --git a/packages/amplify-provider-awscloudformation/src/configuration-manager.ts b/packages/amplify-provider-awscloudformation/src/configuration-manager.ts index fb95520eda1..699892837a4 100644 --- a/packages/amplify-provider-awscloudformation/src/configuration-manager.ts +++ b/packages/amplify-provider-awscloudformation/src/configuration-manager.ts @@ -859,7 +859,7 @@ async function determineAuthFlow(context: $TSContext, projectConfig?: ProjectCon useProfile = useProfile ?? projectConfig?.config?.useProfile; profileName = profileName ?? projectConfig?.config?.profileName; - const generalCreds = projectConfig?.configLevel === 'general'; + const generalCreds = projectConfig?.configLevel === 'general' || cfnParams?.configLevel === 'general'; if (generalCreds) { return { type: 'general' };