Skip to content
Merged
610 changes: 610 additions & 0 deletions packages/eas-cli/src/commands/go.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/eas-cli/src/credentials/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export class CredentialsContext {
public readonly appStore = new AppStoreApi();
public readonly ios = IosGraphqlClient;
public readonly nonInteractive: boolean;
public readonly autoAcceptCredentialReuse: boolean;
public readonly freezeCredentials: boolean = false;
public readonly projectDir: string;
public readonly user: Actor;
Expand All @@ -50,6 +51,7 @@ export class CredentialsContext {
analytics: Analytics;
vcsClient: Client;
freezeCredentials?: boolean;
autoAcceptCredentialReuse?: boolean;
env?: Env;
}
) {
Expand All @@ -60,6 +62,7 @@ export class CredentialsContext {
this.analytics = options.analytics;
this.vcsClient = options.vcsClient;
this.nonInteractive = options.nonInteractive ?? false;
this.autoAcceptCredentialReuse = options.autoAcceptCredentialReuse ?? false;
this.projectInfo = options.projectInfo;
this.freezeCredentials = options.freezeCredentials ?? false;
this.usesBroadcastPushNotifications =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ export async function provideOrGenerateAscApiKeyAsync(
throw new Error(`A new App Store Connect API Key cannot be created in non-interactive mode.`);
}

// When auto-accepting credentials, always auto-generate without asking for user input
if (ctx.autoAcceptCredentialReuse) {
return await generateAscApiKeyAsync(ctx, purpose);
}

const userProvided = await promptForAscApiKeyAsync(ctx);
if (!userProvided) {
return await generateAscApiKeyAsync(ctx, purpose);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { pushKeySchema } from '../credentials';
import { isPushKeyValidAndTrackedAsync } from '../validators/validatePushKey';

export async function provideOrGeneratePushKeyAsync(ctx: CredentialsContext): Promise<PushKey> {
if (!ctx.nonInteractive) {
if (!ctx.nonInteractive && !ctx.autoAcceptCredentialReuse) {
const userProvided = await promptForPushKeyAsync(ctx);
if (userProvided) {
if (!ctx.appStore.authCtx) {
Expand Down
14 changes: 11 additions & 3 deletions packages/eas-cli/src/credentials/ios/actions/SetUpAscApiKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ export class SetUpAscApiKey {
return await new AssignAscApiKey(this.app).runAsync(ctx, maybeAutoselectedKey, this.purpose);
}

// When auto-accepting credentials and no valid key was found, generate a new one without prompting
if (ctx.autoAcceptCredentialReuse) {
const ascApiKey = await new CreateAscApiKey(this.app.account).runAsync(ctx, this.purpose);
return await new AssignAscApiKey(this.app).runAsync(ctx, ascApiKey, this.purpose);
}

const availableChoices =
keysForAccount.length === 0
? this.choices.filter(choice => choice.value !== SetupAscApiKeyChoice.USE_EXISTING)
Expand All @@ -90,9 +96,11 @@ export class SetUpAscApiKey {
return null;
}
const [autoselectedKey] = sortAscApiKeysByUpdatedAtDesc(validKeys);
const useAutoselected = await confirmAsync({
message: `Reuse this App Store Connect API Key?\n${formatAscApiKey(autoselectedKey)}`,
});
const useAutoselected =
ctx.autoAcceptCredentialReuse ||
(await confirmAsync({
message: `Reuse this App Store Connect API Key?\n${formatAscApiKey(autoselectedKey)}`,
}));

if (useAutoselected) {
Log.log(`Using App Store Connect API Key with ID ${autoselectedKey.keyIdentifier}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,13 @@ export class SetUpDistributionCertificate {
const validDistCerts = await this.getValidDistCertsAsync(ctx);
const autoselectedDistCert = validDistCerts[0];

const useAutoselected = await confirmAsync({
message: `Reuse this distribution certificate?\n${formatDistributionCertificate(
autoselectedDistCert
)}`,
});
const useAutoselected =
ctx.autoAcceptCredentialReuse ||
(await confirmAsync({
message: `Reuse this distribution certificate?\n${formatDistributionCertificate(
autoselectedDistCert
)}`,
}));

if (useAutoselected) {
Log.log(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ export class SetUpProvisioningProfile {
}

const isNonInteractiveOrUserDidConfirmAsync = async (): Promise<boolean> => {
if (ctx.nonInteractive) {
if (ctx.nonInteractive || ctx.autoAcceptCredentialReuse) {
return true;
}
return await confirmAsync({
Expand Down
19 changes: 13 additions & 6 deletions packages/eas-cli/src/credentials/ios/actions/SetUpPushKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,14 @@ export class SetUpPushKey {
if (validPushKeys.length > 0) {
const autoselectedPushKey = validPushKeys[0];

const useAutoselected = await confirmAsync({
message: `Reuse this Push Key?\n${formatPushKey(
autoselectedPushKey,
validPushKeys.map(pushKey => pushKey.keyIdentifier)
)}`,
});
const useAutoselected =
ctx.autoAcceptCredentialReuse ||
(await confirmAsync({
message: `Reuse this Push Key?\n${formatPushKey(
autoselectedPushKey,
validPushKeys.map(pushKey => pushKey.keyIdentifier)
)}`,
}));

if (useAutoselected) {
Log.log(`Using push key with ID ${autoselectedPushKey.keyIdentifier}`);
Expand All @@ -77,6 +79,11 @@ export class SetUpPushKey {
}
}

// When auto-accepting and no valid push key was found, generate a new one without prompting
if (ctx.autoAcceptCredentialReuse) {
return await new CreatePushKey(this.app.account).runAsync(ctx);
}

const { action } = await promptAsync({
type: 'select',
name: 'action',
Expand Down
35 changes: 35 additions & 0 deletions packages/eas-cli/src/graphql/mutations/WorkflowRunMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
CreateWorkflowRunFromGitRefMutationVariables,
CreateWorkflowRunMutation,
CreateWorkflowRunMutationVariables,
WorkflowProjectSourceInput,
WorkflowRevisionInput,
WorkflowRunInput,
} from '../generated';
Expand Down Expand Up @@ -103,6 +104,40 @@ export namespace WorkflowRunMutation {
return { id: data.workflowRun.createWorkflowRunFromGitRef.id };
}

export async function createExpoGoRepackWorkflowRunAsync(
graphqlClient: ExpoGraphqlClient,
{
appId,
projectSource,
}: {
appId: string;
projectSource: WorkflowProjectSourceInput;
}
): Promise<{ id: string }> {
const data = await withErrorHandlingAsync(
graphqlClient
.mutation<
{ workflowRun: { createExpoGoRepackWorkflowRun: { id: string } } },
{ appId: string; projectSource: WorkflowProjectSourceInput }
>(
/* eslint-disable graphql/template-strings */
gql`
mutation CreateExpoGoRepackWorkflowRun($appId: ID!, $projectSource: WorkflowProjectSourceInput!) {
workflowRun {
createExpoGoRepackWorkflowRun(appId: $appId, projectSource: $projectSource) {
id
}
}
}
`,
/* eslint-enable graphql/template-strings */
{ appId, projectSource }
)
.toPromise()
);
return { id: data.workflowRun.createExpoGoRepackWorkflowRun.id };
}

export async function cancelWorkflowRunAsync(
graphqlClient: ExpoGraphqlClient,
{
Expand Down
9 changes: 9 additions & 0 deletions packages/eas-cli/src/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ export default class Log {
}
}

/**
* Signal that the cursor is already at the start of a fresh line (e.g. after
* a spinner clears itself), so that the next `addNewLineIfNone()` call knows
* it doesn't need to emit an extra blank line.
*/
public static markFreshLine(): void {
Log.isLastLineNewLine = true;
}

public static error(...args: any[]): void {
Log.consoleLog(...Log.withTextColor(args, chalk.red));
}
Expand Down