From e0d2a5ee856f9855c75fb84b801f2e12164d9f05 Mon Sep 17 00:00:00 2001 From: Quinlan Jung Date: Mon, 14 Jun 2021 18:41:39 -0700 Subject: [PATCH 1/3] [eas-cli] action to upload/download credentials.json to www --- .../android/actions/UpdateCredentialsJson.ts | 15 +- ...etupBuildCredentialsFromCredentialsJson.ts | 88 +++++++++++ .../actions/new/UpdateCredentialsJson.ts | 17 ++ ...uildCredentialsFromCredentialsJson-test.ts | 149 ++++++++++++++++++ .../credentialsJson/__tests__/update-test.ts | 58 +++---- .../src/credentials/credentialsJson/update.ts | 29 +--- .../credentials/manager/ManageAndroidBeta.ts | 23 +++ 7 files changed, 322 insertions(+), 57 deletions(-) create mode 100644 packages/eas-cli/src/credentials/android/actions/new/SetupBuildCredentialsFromCredentialsJson.ts create mode 100644 packages/eas-cli/src/credentials/android/actions/new/UpdateCredentialsJson.ts create mode 100644 packages/eas-cli/src/credentials/android/actions/new/__tests__/SetupBuildCredentialsFromCredentialsJson-test.ts diff --git a/packages/eas-cli/src/credentials/android/actions/UpdateCredentialsJson.ts b/packages/eas-cli/src/credentials/android/actions/UpdateCredentialsJson.ts index 2a0f148a92..3a4b1c4b12 100644 --- a/packages/eas-cli/src/credentials/android/actions/UpdateCredentialsJson.ts +++ b/packages/eas-cli/src/credentials/android/actions/UpdateCredentialsJson.ts @@ -2,13 +2,26 @@ import Log from '../../../log'; import { Action, CredentialsManager } from '../../CredentialsManager'; import { Context } from '../../context'; import { updateAndroidCredentialsAsync } from '../../credentialsJson/update'; +import { AndroidAppCredentialsQuery } from '../api/graphql/queries/AndroidAppCredentialsQuery'; export class UpdateCredentialsJson implements Action { constructor(private projectFullName: string) {} async runAsync(manager: CredentialsManager, ctx: Context): Promise { + const legacyAppCredentials = await AndroidAppCredentialsQuery.withCommonFieldsByApplicationIdentifierAsync( + this.projectFullName, + { + legacyOnly: true, + } + ); + const legacyBuildCredentials = legacyAppCredentials?.androidAppBuildCredentialsList[0] ?? null; + if (!legacyBuildCredentials) { + Log.log('You dont have any Expo Classic Android credentials configured at this time'); + return; + } Log.log('Updating Android credentials in credentials.json'); - await updateAndroidCredentialsAsync(ctx); + + await updateAndroidCredentialsAsync(ctx, legacyBuildCredentials); Log.succeed( 'Android part of your local credentials.json is synced with values stored on EAS servers.' ); diff --git a/packages/eas-cli/src/credentials/android/actions/new/SetupBuildCredentialsFromCredentialsJson.ts b/packages/eas-cli/src/credentials/android/actions/new/SetupBuildCredentialsFromCredentialsJson.ts new file mode 100644 index 0000000000..ea204a348a --- /dev/null +++ b/packages/eas-cli/src/credentials/android/actions/new/SetupBuildCredentialsFromCredentialsJson.ts @@ -0,0 +1,88 @@ +import { + AndroidAppBuildCredentialsFragment, + AndroidKeystoreType, +} from '../../../../graphql/generated'; +import Log from '../../../../log'; +import { confirmAsync } from '../../../../prompts'; +import { Context } from '../../../context'; +import { readAndroidCredentialsAsync } from '../../../credentialsJson/read'; +import { + SelectAndroidBuildCredentials, + SelectAndroidBuildCredentialsResultType, +} from '../../../manager/SelectAndroidBuildCredentials'; +import { AppLookupParams } from '../../api/GraphqlClient'; +import { getKeystoreWithType } from '../../utils/keystoreNew'; +import { BackupKeystore } from './DownloadKeystore'; + +export class SetupBuildCredentialsFromCredentialsJson { + constructor(private app: AppLookupParams) {} + + async runAsync(ctx: Context): Promise { + if (ctx.nonInteractive) { + throw new Error( + 'Setting up build credentials from credentials.json is only available in interactive mode' + ); + } + + let localCredentials; + try { + localCredentials = await readAndroidCredentialsAsync(ctx.projectDir); + } catch (error) { + Log.error( + 'Reading credentials from credentials.json failed. Make sure this file is correct and all credentials are present there.' + ); + throw error; + } + + const selectBuildCredentialsResult = await new SelectAndroidBuildCredentials(this.app).runAsync( + ctx + ); + if ( + selectBuildCredentialsResult.resultType === + SelectAndroidBuildCredentialsResultType.EXISTING_CREDENTIALS && + selectBuildCredentialsResult.result.androidKeystore + ) { + const buildCredentials = selectBuildCredentialsResult.result; + const confirmOverwrite = await confirmAsync({ + message: `The build configuration ${buildCredentials.name} already has a keystore configured. Overwrite?`, + }); + if (!confirmOverwrite) { + return null; + } + await new BackupKeystore(this.app).runAsync(ctx, buildCredentials); + } + + const providedKeystoreWithType = getKeystoreWithType(localCredentials.keystore); + if (providedKeystoreWithType.type === AndroidKeystoreType.Unknown) { + const confirmKeystoreIsSketchy = await confirmAsync({ + message: `The keystore you provided could not be parsed and may be corrupt. Proceed anyways?`, + }); + if (!confirmKeystoreIsSketchy) { + return null; + } + } + const keystoreFragment = await ctx.newAndroid.createKeystoreAsync( + this.app.account, + providedKeystoreWithType + ); + let buildCredentials: AndroidAppBuildCredentialsFragment; + if ( + selectBuildCredentialsResult.resultType === + SelectAndroidBuildCredentialsResultType.CREATE_REQUEST + ) { + buildCredentials = await ctx.newAndroid.createAndroidAppBuildCredentialsAsync(this.app, { + ...selectBuildCredentialsResult.result, + androidKeystoreId: keystoreFragment.id, + }); + } else { + buildCredentials = await ctx.newAndroid.updateAndroidAppBuildCredentialsAsync( + selectBuildCredentialsResult.result, + { + androidKeystoreId: keystoreFragment.id, + } + ); + } + Log.succeed('Keystore updated'); + return buildCredentials; + } +} diff --git a/packages/eas-cli/src/credentials/android/actions/new/UpdateCredentialsJson.ts b/packages/eas-cli/src/credentials/android/actions/new/UpdateCredentialsJson.ts new file mode 100644 index 0000000000..293b03b3ae --- /dev/null +++ b/packages/eas-cli/src/credentials/android/actions/new/UpdateCredentialsJson.ts @@ -0,0 +1,17 @@ +import { AndroidAppBuildCredentialsFragment } from '../../../../graphql/generated'; +import Log from '../../../../log'; +import { Context } from '../../../context'; +import { updateAndroidCredentialsAsync } from '../../../credentialsJson/update'; + +export class UpdateCredentialsJson { + async runAsync( + ctx: Context, + buildCredentials: AndroidAppBuildCredentialsFragment + ): Promise { + Log.log('Updating Android credentials in credentials.json'); + await updateAndroidCredentialsAsync(ctx, buildCredentials); + Log.succeed( + 'Android part of your local credentials.json is synced with values stored on EAS servers.' + ); + } +} diff --git a/packages/eas-cli/src/credentials/android/actions/new/__tests__/SetupBuildCredentialsFromCredentialsJson-test.ts b/packages/eas-cli/src/credentials/android/actions/new/__tests__/SetupBuildCredentialsFromCredentialsJson-test.ts new file mode 100644 index 0000000000..7b6c8c1b6d --- /dev/null +++ b/packages/eas-cli/src/credentials/android/actions/new/__tests__/SetupBuildCredentialsFromCredentialsJson-test.ts @@ -0,0 +1,149 @@ +import { vol } from 'memfs'; + +import { AndroidKeystoreType } from '../../../../../graphql/generated'; +import { confirmAsync } from '../../../../../prompts'; +import { + getNewAndroidApiMockWithoutCredentials, + testAndroidBuildCredentialsFragment, + testJksAndroidKeystoreFragment, +} from '../../../../__tests__/fixtures-android-new'; +import { createCtxMock } from '../../../../__tests__/fixtures-context'; +import { + SelectAndroidBuildCredentials, + SelectAndroidBuildCredentialsResultType, +} from '../../../../manager/SelectAndroidBuildCredentials'; +import { getAppLookupParamsFromContext } from '../../BuildCredentialsUtils'; +import { SetupBuildCredentialsFromCredentialsJson } from '../SetupBuildCredentialsFromCredentialsJson'; + +jest.mock('fs'); + +jest.mock('../../../../../prompts'); +(confirmAsync as jest.Mock).mockImplementation(() => true); +jest.mock('../../../../manager/SelectAndroidBuildCredentials'); + +const originalConsoleLog = console.log; +const originalConsoleWarn = console.warn; +beforeAll(() => { + console.log = jest.fn(); + console.warn = jest.fn(); +}); +afterAll(() => { + console.log = originalConsoleLog; + console.warn = originalConsoleWarn; +}); +beforeEach(() => { + vol.reset(); +}); + +describe(SetupBuildCredentialsFromCredentialsJson, () => { + it('sets up a new build configuration from credentials.json upon user request', async () => { + (SelectAndroidBuildCredentials as any).mockImplementation(() => { + return { + runAsync: () => { + return { + resultType: SelectAndroidBuildCredentialsResultType.CREATE_REQUEST, + result: { isDefault: true, name: 'test configuration' }, + }; + }, + }; + }); + const ctx = createCtxMock({ + nonInteractive: false, + newAndroid: { + ...getNewAndroidApiMockWithoutCredentials(), + createKeystoreAsync: jest.fn(() => testJksAndroidKeystoreFragment), + }, + }); + vol.fromJSON({ + './credentials.json': JSON.stringify({ + android: { + keystore: { + keystorePath: 'keystore.jks', + keystorePassword: testJksAndroidKeystoreFragment.keystorePassword, + keyAlias: testJksAndroidKeystoreFragment.keyAlias, + keyPassword: testJksAndroidKeystoreFragment.keyPassword, + }, + }, + }), + 'keystore.jks': 'some-binary-content', + }); + const appLookupParams = getAppLookupParamsFromContext(ctx); + const setupBuildCredentialsAction = new SetupBuildCredentialsFromCredentialsJson( + appLookupParams + ); + await setupBuildCredentialsAction.runAsync(ctx); + + // expect keystore to be created with credentials.json content + expect(ctx.newAndroid.createKeystoreAsync as any).toHaveBeenCalledTimes(1); + expect(ctx.newAndroid.createKeystoreAsync as any).toBeCalledWith(appLookupParams.account, { + keystorePassword: testJksAndroidKeystoreFragment.keystorePassword, + keyAlias: testJksAndroidKeystoreFragment.keyAlias, + keyPassword: testJksAndroidKeystoreFragment.keyPassword, + keystore: Buffer.from('some-binary-content').toString('base64'), + type: AndroidKeystoreType.Unknown, + }); + + // expect new build credentials to be created + expect(ctx.newAndroid.createAndroidAppBuildCredentialsAsync as any).toHaveBeenCalledTimes(1); + }); + it('uses an existing build configuration upon user request', async () => { + (SelectAndroidBuildCredentials as any).mockImplementation(() => { + return { + runAsync: () => { + return { + resultType: SelectAndroidBuildCredentialsResultType.EXISTING_CREDENTIALS, + result: testAndroidBuildCredentialsFragment, + }; + }, + }; + }); + const ctx = createCtxMock({ + nonInteractive: false, + newAndroid: { + ...getNewAndroidApiMockWithoutCredentials(), + createKeystoreAsync: jest.fn(() => testJksAndroidKeystoreFragment), + }, + }); + vol.fromJSON({ + './credentials.json': JSON.stringify({ + android: { + keystore: { + keystorePath: 'keystore.jks', + keystorePassword: testJksAndroidKeystoreFragment.keystorePassword, + keyAlias: testJksAndroidKeystoreFragment.keyAlias, + keyPassword: testJksAndroidKeystoreFragment.keyPassword, + }, + }, + }), + 'keystore.jks': 'some-binary-content', + }); + const appLookupParams = getAppLookupParamsFromContext(ctx); + const setupBuildCredentialsAction = new SetupBuildCredentialsFromCredentialsJson( + appLookupParams + ); + await setupBuildCredentialsAction.runAsync(ctx); + + // expect keystore to be created with credentials.json content + expect(ctx.newAndroid.createKeystoreAsync as any).toHaveBeenCalledTimes(1); + expect(ctx.newAndroid.createKeystoreAsync as any).toBeCalledWith(appLookupParams.account, { + keystorePassword: testJksAndroidKeystoreFragment.keystorePassword, + keyAlias: testJksAndroidKeystoreFragment.keyAlias, + keyPassword: testJksAndroidKeystoreFragment.keyPassword, + keystore: Buffer.from('some-binary-content').toString('base64'), + type: AndroidKeystoreType.Unknown, + }); + + // expect existing build credentials to be updated + expect(ctx.newAndroid.updateAndroidAppBuildCredentialsAsync as any).toHaveBeenCalledTimes(1); + }); + it('errors in Non-Interactive Mode', async () => { + const ctx = createCtxMock({ + nonInteractive: true, + }); + const appLookupParams = getAppLookupParamsFromContext(ctx); + const setupBuildCredentialsAction = new SetupBuildCredentialsFromCredentialsJson( + appLookupParams + ); + await expect(setupBuildCredentialsAction.runAsync(ctx)).rejects.toThrowError(); + }); +}); diff --git a/packages/eas-cli/src/credentials/credentialsJson/__tests__/update-test.ts b/packages/eas-cli/src/credentials/credentialsJson/__tests__/update-test.ts index c4e8f757fd..c4e9e0a836 100644 --- a/packages/eas-cli/src/credentials/credentialsJson/__tests__/update-test.ts +++ b/packages/eas-cli/src/credentials/credentialsJson/__tests__/update-test.ts @@ -5,6 +5,7 @@ import prompts from 'prompts'; import { asMock } from '../../../__tests__/utils'; import { IosDistributionType } from '../../../graphql/generated'; import { testKeystore } from '../../__tests__/fixtures-android'; +import { testLegacyAndroidBuildCredentialsFragment } from '../../__tests__/fixtures-android-new'; import { createCtxMock } from '../../__tests__/fixtures-context'; import { getNewIosApiMockWithoutCredentials, @@ -45,11 +46,7 @@ beforeEach(() => { describe('update credentials.json', () => { describe(updateAndroidCredentialsAsync, () => { it('should update keystore in credentials.json if www returns valid credentials', async () => { - const ctx = createCtxMock({ - android: { - fetchKeystoreAsync: jest.fn(() => testKeystore), - }, - }); + const ctx = createCtxMock(); vol.fromJSON({ './credentials.json': JSON.stringify({ android: { @@ -63,7 +60,7 @@ describe('update credentials.json', () => { }), 'keystore.jks': 'somebinarydata', }); - await updateAndroidCredentialsAsync(ctx); + await updateAndroidCredentialsAsync(ctx, testLegacyAndroidBuildCredentialsFragment); const keystore = await fs.readFile('./keystore.jks', 'base64'); const credJson = await fs.readJson('./credentials.json'); expect(keystore).toEqual(testKeystore.keystore); @@ -71,20 +68,17 @@ describe('update credentials.json', () => { android: { keystore: { keystorePath: 'keystore.jks', - keystorePassword: testKeystore.keystorePassword, - keyAlias: testKeystore.keyAlias, - keyPassword: testKeystore.keyPassword, + keystorePassword: + testLegacyAndroidBuildCredentialsFragment.androidKeystore?.keystorePassword, + keyAlias: testLegacyAndroidBuildCredentialsFragment.androidKeystore?.keyAlias, + keyPassword: testLegacyAndroidBuildCredentialsFragment.androidKeystore?.keyPassword, }, }, }); }); it('should create credentials.json and keystore if credentials.json does not exist', async () => { - const ctx = createCtxMock({ - android: { - fetchKeystoreAsync: jest.fn(() => testKeystore), - }, - }); - await updateAndroidCredentialsAsync(ctx); + const ctx = createCtxMock(); + await updateAndroidCredentialsAsync(ctx, testLegacyAndroidBuildCredentialsFragment); const keystore = await fs.readFile('./credentials/android/keystore.jks', 'base64'); const credJson = await fs.readJson('./credentials.json'); expect(keystore).toEqual(testKeystore.keystore); @@ -92,9 +86,10 @@ describe('update credentials.json', () => { android: { keystore: { keystorePath: 'credentials/android/keystore.jks', - keystorePassword: testKeystore.keystorePassword, - keyAlias: testKeystore.keyAlias, - keyPassword: testKeystore.keyPassword, + keystorePassword: + testLegacyAndroidBuildCredentialsFragment.androidKeystore?.keystorePassword, + keyAlias: testLegacyAndroidBuildCredentialsFragment.androidKeystore?.keyAlias, + keyPassword: testLegacyAndroidBuildCredentialsFragment.androidKeystore?.keyPassword, }, }, }); @@ -116,7 +111,9 @@ describe('update credentials.json', () => { 'keystore.jks': 'somebinarydata', }); try { - await updateAndroidCredentialsAsync(ctx); + const buildCredentialsNoKeystore = { ...testLegacyAndroidBuildCredentialsFragment }; + delete buildCredentialsNoKeystore.androidKeystore; + await updateAndroidCredentialsAsync(ctx, buildCredentialsNoKeystore); throw new Error('updateAndroidCredentialsAsync should throw an error'); } catch (e) { expect(e.message).toMatch( @@ -129,15 +126,11 @@ describe('update credentials.json', () => { expect(newCredJson).toEqual(credJson); }); it('should update keystore and credentials.json if android part of credentials.json is not valid', async () => { - const ctx = createCtxMock({ - android: { - fetchKeystoreAsync: jest.fn(() => testKeystore), - }, - }); + const ctx = createCtxMock(); vol.fromJSON({ './credentials.json': JSON.stringify({ android: { test: '123' } }), }); - await updateAndroidCredentialsAsync(ctx); + await updateAndroidCredentialsAsync(ctx, testLegacyAndroidBuildCredentialsFragment); const keystore = await fs.readFile('./credentials/android/keystore.jks', 'base64'); const credJson = await fs.readJson('./credentials.json'); expect(keystore).toEqual(testKeystore.keystore); @@ -145,19 +138,16 @@ describe('update credentials.json', () => { android: { keystore: { keystorePath: 'credentials/android/keystore.jks', - keystorePassword: testKeystore.keystorePassword, - keyAlias: testKeystore.keyAlias, - keyPassword: testKeystore.keyPassword, + keystorePassword: + testLegacyAndroidBuildCredentialsFragment.androidKeystore?.keystorePassword, + keyAlias: testLegacyAndroidBuildCredentialsFragment.androidKeystore?.keyAlias, + keyPassword: testLegacyAndroidBuildCredentialsFragment.androidKeystore?.keyPassword, }, }, }); }); it('should update keystore and credentials.json if ios part of credentials.json is not valid', async () => { - const ctx = createCtxMock({ - android: { - fetchKeystoreAsync: jest.fn(() => testKeystore), - }, - }); + const ctx = createCtxMock(); const credJson = { android: { keystore: { @@ -175,7 +165,7 @@ describe('update credentials.json', () => { './credentials.json': JSON.stringify(credJson), 'keystore.jks': 'somebinarydata', }); - await updateAndroidCredentialsAsync(ctx); + await updateAndroidCredentialsAsync(ctx, testLegacyAndroidBuildCredentialsFragment); const keystore = await fs.readFile('./keystore.jks', 'base64'); const newCredJson = await fs.readJson('./credentials.json'); expect(keystore).toEqual(testKeystore.keystore); diff --git a/packages/eas-cli/src/credentials/credentialsJson/update.ts b/packages/eas-cli/src/credentials/credentialsJson/update.ts index 9f94580fdc..80ab1294fd 100644 --- a/packages/eas-cli/src/credentials/credentialsJson/update.ts +++ b/packages/eas-cli/src/credentials/credentialsJson/update.ts @@ -3,11 +3,9 @@ import zipObject from 'lodash/zipObject'; import nullthrows from 'nullthrows'; import path from 'path'; -import { IosDistributionType } from '../../graphql/generated'; +import { AndroidAppBuildCredentialsFragment, IosDistributionType } from '../../graphql/generated'; import Log from '../../log'; import { findApplicationTarget, findTargetByName } from '../../project/ios/target'; -import { getProjectAccountName } from '../../project/projectUtils'; -import { confirmAsync } from '../../prompts'; import { gitStatusAsync } from '../../utils/git'; import { Context } from '../context'; import { App, Target, TargetCredentials } from '../ios/types'; @@ -23,31 +21,18 @@ import { getCredentialsJsonPath } from './utils'; * Update Android credentials.json with values from www, content of credentials.json * is not validated */ -export async function updateAndroidCredentialsAsync(ctx: Context): Promise { +export async function updateAndroidCredentialsAsync( + ctx: Context, + buildCredentials: AndroidAppBuildCredentialsFragment +): Promise { const rawCredentialsJson: any = (await readRawAsync(ctx.projectDir, { throwIfMissing: false })) ?? {}; - const accountName = getProjectAccountName(ctx.exp, ctx.user); - const experienceName = `@${accountName}/${ctx.exp.slug}`; - const keystore = await ctx.android.fetchKeystoreAsync(experienceName); + const keystore = buildCredentials.androidKeystore; if (!keystore) { throw new Error('There are no credentials configured for this project on EAS servers'); } - const isKeystoreComplete = - keystore.keystore && keystore.keystorePassword && keystore.keyPassword && keystore.keyAlias; - - if (!isKeystoreComplete) { - const confirm = await confirmAsync({ - message: - 'Credentials on EAS servers might be invalid or incomplete. Are you sure you want to continue?', - }); - if (!confirm) { - Log.warn('Aborting...'); - return; - } - } - const keystorePath = rawCredentialsJson?.android?.keystore?.keystorePath ?? 'credentials/android/keystore.jks'; Log.log(`Writing Keystore to ${keystorePath}`); @@ -59,7 +44,7 @@ export async function updateAndroidCredentialsAsync(ctx: Context): Promise keystorePath, keystorePassword: keystore.keystorePassword, keyAlias: keystore.keyAlias, - keyPassword: keystore.keyPassword, + keyPassword: keystore.keyPassword ?? undefined, }, }; rawCredentialsJson.android = androidCredentials; diff --git a/packages/eas-cli/src/credentials/manager/ManageAndroidBeta.ts b/packages/eas-cli/src/credentials/manager/ManageAndroidBeta.ts index 36758c74da..17b87aff48 100644 --- a/packages/eas-cli/src/credentials/manager/ManageAndroidBeta.ts +++ b/packages/eas-cli/src/credentials/manager/ManageAndroidBeta.ts @@ -15,6 +15,8 @@ import { CreateKeystore } from '../android/actions/new/CreateKeystore'; import { DownloadKeystore } from '../android/actions/new/DownloadKeystore'; import { RemoveFcm } from '../android/actions/new/RemoveFcm'; import { RemoveKeystore } from '../android/actions/new/RemoveKeystore'; +import { SetupBuildCredentialsFromCredentialsJson } from '../android/actions/new/SetupBuildCredentialsFromCredentialsJson'; +import { UpdateCredentialsJson } from '../android/actions/new/UpdateCredentialsJson'; import { displayAndroidAppCredentials, displayEmptyAndroidCredentials, @@ -33,6 +35,8 @@ enum ActionType { RemoveKeystore, CreateFcm, RemoveFcm, + UpdateCredentialsJson, + SetupBuildCredentialsFromCredentialsJson, } enum Scope { @@ -102,6 +106,14 @@ export class ManageAndroid implements Action { value: ActionType.RemoveFcm, title: 'Delete your FCM Api Key', }, + { + value: ActionType.UpdateCredentialsJson, + title: 'Update credentials.json with values from EAS servers', + }, + { + value: ActionType.SetupBuildCredentialsFromCredentialsJson, + title: 'Update credentials on EAS servers with values from credentials.json', + }, ]; const { action: chosenAction } = await promptAsync({ type: 'select', @@ -154,6 +166,17 @@ export class ManageAndroid implements Action { } else if (chosenAction === ActionType.RemoveFcm) { const appLookupParams = getAppLookupParamsFromContext(ctx); await new RemoveFcm(appLookupParams).runAsync(ctx); + } else if (chosenAction === ActionType.UpdateCredentialsJson) { + const appLookupParams = getAppLookupParamsFromContext(ctx); + const buildCredentials = await new SelectExistingAndroidBuildCredentials( + appLookupParams + ).runAsync(ctx); + if (buildCredentials) { + await new UpdateCredentialsJson().runAsync(ctx, buildCredentials); + } + } else if (chosenAction === ActionType.SetupBuildCredentialsFromCredentialsJson) { + const appLookupParams = getAppLookupParamsFromContext(ctx); + await new SetupBuildCredentialsFromCredentialsJson(appLookupParams).runAsync(ctx); } } catch (err) { Log.error(err); From 8eff9446a49b65c349a6543e30c5d4117b42f448 Mon Sep 17 00:00:00 2001 From: Quinlan Jung Date: Tue, 15 Jun 2021 11:13:59 -0700 Subject: [PATCH 2/3] Update packages/eas-cli/src/credentials/android/actions/new/SetupBuildCredentialsFromCredentialsJson.ts Co-authored-by: Dominik Sokal --- .../actions/new/SetupBuildCredentialsFromCredentialsJson.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eas-cli/src/credentials/android/actions/new/SetupBuildCredentialsFromCredentialsJson.ts b/packages/eas-cli/src/credentials/android/actions/new/SetupBuildCredentialsFromCredentialsJson.ts index ea204a348a..9fee90b1cc 100644 --- a/packages/eas-cli/src/credentials/android/actions/new/SetupBuildCredentialsFromCredentialsJson.ts +++ b/packages/eas-cli/src/credentials/android/actions/new/SetupBuildCredentialsFromCredentialsJson.ts @@ -55,7 +55,7 @@ export class SetupBuildCredentialsFromCredentialsJson { const providedKeystoreWithType = getKeystoreWithType(localCredentials.keystore); if (providedKeystoreWithType.type === AndroidKeystoreType.Unknown) { const confirmKeystoreIsSketchy = await confirmAsync({ - message: `The keystore you provided could not be parsed and may be corrupt. Proceed anyways?`, + message: `The keystore you provided could not be parsed and may be corrupt. Proceed anyway?`, }); if (!confirmKeystoreIsSketchy) { return null; From 25c3eae7d438ccf96993a1b920de1ba0378fff34 Mon Sep 17 00:00:00 2001 From: Quinlan Jung Date: Tue, 15 Jun 2021 11:14:05 -0700 Subject: [PATCH 3/3] Update packages/eas-cli/src/credentials/android/actions/UpdateCredentialsJson.ts Co-authored-by: Dominik Sokal --- .../src/credentials/android/actions/UpdateCredentialsJson.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eas-cli/src/credentials/android/actions/UpdateCredentialsJson.ts b/packages/eas-cli/src/credentials/android/actions/UpdateCredentialsJson.ts index 3a4b1c4b12..84ac131fa0 100644 --- a/packages/eas-cli/src/credentials/android/actions/UpdateCredentialsJson.ts +++ b/packages/eas-cli/src/credentials/android/actions/UpdateCredentialsJson.ts @@ -16,7 +16,7 @@ export class UpdateCredentialsJson implements Action { ); const legacyBuildCredentials = legacyAppCredentials?.androidAppBuildCredentialsList[0] ?? null; if (!legacyBuildCredentials) { - Log.log('You dont have any Expo Classic Android credentials configured at this time'); + Log.log(`You don't have any Expo Classic Android credentials configured at this time`); return; } Log.log('Updating Android credentials in credentials.json');