From 33ea24daaa13a20b6f61e8ba1dc052d608821225 Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Tue, 25 Oct 2022 16:16:13 +0200 Subject: [PATCH] refactor(update): move ensure methods outside the update command --- packages/eas-cli/src/branch/queries.ts | 72 ++++++++++++++++- packages/eas-cli/src/channel/queries.ts | 65 +++++++++++++++ .../eas-cli/src/commands/branch/create.ts | 1 + .../eas-cli/src/commands/channel/create.ts | 1 + packages/eas-cli/src/commands/update/index.ts | 81 +++---------------- 5 files changed, 147 insertions(+), 73 deletions(-) diff --git a/packages/eas-cli/src/branch/queries.ts b/packages/eas-cli/src/branch/queries.ts index c7a74c21b6..34c35b7d6e 100644 --- a/packages/eas-cli/src/branch/queries.ts +++ b/packages/eas-cli/src/branch/queries.ts @@ -1,8 +1,15 @@ import chalk from 'chalk'; +import gql from 'graphql-tag'; import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient'; import { PaginatedQueryOptions } from '../commandUtils/pagination'; -import { UpdateBranchFragment } from '../graphql/generated'; +import { withErrorHandlingAsync } from '../graphql/client'; +import { + CreateUpdateBranchForAppMutation, + CreateUpdateBranchForAppMutationVariables, + UpdateBranch, + UpdateBranchFragment, +} from '../graphql/generated'; import { BranchQuery } from '../graphql/queries/BranchQuery'; import Log from '../log'; import { formatBranch, getBranchDescription } from '../update/utils'; @@ -11,6 +18,7 @@ import { paginatedQueryWithConfirmPromptAsync, paginatedQueryWithSelectPromptAsync, } from '../utils/queries'; +import { BranchNotFoundError } from './utils'; export const BRANCHES_LIMIT = 50; @@ -111,3 +119,65 @@ function renderPageOfBranches( ); } } + +export async function createUpdateBranchOnAppAsync( + graphqlClient: ExpoGraphqlClient, + { appId, name }: CreateUpdateBranchForAppMutationVariables +): Promise> { + const result = await withErrorHandlingAsync( + graphqlClient + .mutation( + gql` + mutation createUpdateBranchForApp($appId: ID!, $name: String!) { + updateBranch { + createUpdateBranchForApp(appId: $appId, name: $name) { + id + name + } + } + } + `, + { + appId, + name, + } + ) + .toPromise() + ); + const newBranch = result.updateBranch.createUpdateBranchForApp; + if (!newBranch) { + throw new Error(`Could not create branch ${name}.`); + } + return newBranch; +} + +export async function ensureBranchExistsAsync( + graphqlClient: ExpoGraphqlClient, + { + appId, + branchName, + }: { + appId: string; + branchName: string; + } +): Promise<{ branchId: string }> { + try { + const updateBranch = await BranchQuery.getBranchByNameAsync(graphqlClient, { + appId, + name: branchName, + }); + + const { id } = updateBranch; + return { branchId: id }; + } catch (error) { + if (error instanceof BranchNotFoundError) { + const newUpdateBranch = await createUpdateBranchOnAppAsync(graphqlClient, { + appId, + name: branchName, + }); + return { branchId: newUpdateBranch.id }; + } else { + throw error; + } + } +} diff --git a/packages/eas-cli/src/channel/queries.ts b/packages/eas-cli/src/channel/queries.ts index a1b116e5f6..515039836f 100644 --- a/packages/eas-cli/src/channel/queries.ts +++ b/packages/eas-cli/src/channel/queries.ts @@ -1,8 +1,12 @@ import chalk from 'chalk'; +import gql from 'graphql-tag'; import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient'; import { PaginatedQueryOptions } from '../commandUtils/pagination'; +import { withErrorHandlingAsync } from '../graphql/client'; import { + CreateUpdateChannelOnAppMutation, + CreateUpdateChannelOnAppMutationVariables, ViewBranchesOnUpdateChannelQueryVariables, ViewUpdateChannelsOnAppQueryVariables, } from '../graphql/generated'; @@ -197,3 +201,64 @@ function renderChannelHeaderContent({ Log.addNewLineIfNone(); Log.log(chalk`{bold Branches pointed at this channel and their most recent update group:}`); } + +export async function createChannelAsync( + graphqlClient: ExpoGraphqlClient, + { + appId, + branchId, + channelName, + }: { + appId: string; + branchId: string; + channelName: string; + } +): Promise { + // Point the new channel at a branch with its same name. + const branchMapping = JSON.stringify({ + data: [{ branchId, branchMappingLogic: 'true' }], + version: 0, + }); + return await withErrorHandlingAsync( + graphqlClient + .mutation( + gql` + mutation CreateUpdateChannelOnApp($appId: ID!, $name: String!, $branchMapping: String!) { + updateChannel { + createUpdateChannelForApp(appId: $appId, name: $name, branchMapping: $branchMapping) { + id + name + branchMapping + } + } + } + `, + { + appId, + name: channelName, + branchMapping, + } + ) + .toPromise() + ); +} + +export async function ensureChannelExistsAsync( + graphqlClient: ExpoGraphqlClient, + { appId, branchId, channelName }: { appId: string; branchId: string; channelName: string } +): Promise { + try { + await createChannelAsync(graphqlClient, { + appId, + channelName, + branchId, + }); + } catch (e: any) { + const isIgnorableError = + e.graphQLErrors?.length === 1 && + e.graphQLErrors[0].extensions.errorCode === 'CHANNEL_ALREADY_EXISTS'; + if (!isIgnorableError) { + throw e; + } + } +} diff --git a/packages/eas-cli/src/commands/branch/create.ts b/packages/eas-cli/src/commands/branch/create.ts index 046bad9d26..3739432c0d 100644 --- a/packages/eas-cli/src/commands/branch/create.ts +++ b/packages/eas-cli/src/commands/branch/create.ts @@ -16,6 +16,7 @@ import { getDisplayNameForProjectIdAsync } from '../../project/projectUtils'; import { promptAsync } from '../../prompts'; import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json'; +// NOTE(cedric): copied to src/branch/queries.ts to reuse in multiple commands export async function createUpdateBranchOnAppAsync( graphqlClient: ExpoGraphqlClient, { appId, name }: CreateUpdateBranchForAppMutationVariables diff --git a/packages/eas-cli/src/commands/channel/create.ts b/packages/eas-cli/src/commands/channel/create.ts index 9a64daaa24..ce21d36ef6 100644 --- a/packages/eas-cli/src/commands/channel/create.ts +++ b/packages/eas-cli/src/commands/channel/create.ts @@ -18,6 +18,7 @@ import formatFields from '../../utils/formatFields'; import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json'; import { createUpdateBranchOnAppAsync } from '../branch/create'; +// NOTE(cedric): copied to src/channel/queries.ts to reuse in multiple commands export async function createUpdateChannelOnAppAsync( graphqlClient: ExpoGraphqlClient, { diff --git a/packages/eas-cli/src/commands/update/index.ts b/packages/eas-cli/src/commands/update/index.ts index 88970c087c..421fa577fc 100644 --- a/packages/eas-cli/src/commands/update/index.ts +++ b/packages/eas-cli/src/commands/update/index.ts @@ -7,9 +7,10 @@ import chalk from 'chalk'; import nullthrows from 'nullthrows'; import { getEASUpdateURL } from '../../api'; -import { selectBranchOnAppAsync } from '../../branch/queries'; -import { BranchNotFoundError, getDefaultBranchNameAsync } from '../../branch/utils'; +import { ensureBranchExistsAsync, selectBranchOnAppAsync } from '../../branch/queries'; +import { getDefaultBranchNameAsync } from '../../branch/utils'; import { getUpdateGroupUrl } from '../../build/utils/url'; +import { ensureChannelExistsAsync } from '../../channel/queries'; import EasCommand from '../../commandUtils/EasCommand'; import { DynamicConfigContextFn } from '../../commandUtils/context/DynamicProjectConfigContextField'; import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient'; @@ -22,10 +23,8 @@ import { Update, UpdateInfoGroup, UpdatePublishMutation, - ViewBranchQueryVariables, } from '../../graphql/generated'; import { PublishMutation } from '../../graphql/mutations/PublishMutation'; -import { BranchQuery } from '../../graphql/queries/BranchQuery'; import { UpdateQuery } from '../../graphql/queries/UpdateQuery'; import Log, { learnMore, link } from '../../log'; import { ora } from '../../ora'; @@ -57,8 +56,6 @@ import formatFields from '../../utils/formatFields'; import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json'; import { maybeWarnAboutEasOutagesAsync } from '../../utils/statuspageService'; import { getVcsClient } from '../../vcs'; -import { createUpdateBranchOnAppAsync } from '../branch/create'; -import { createUpdateChannelOnAppAsync } from '../channel/create'; import { configureAppJSONForEASUpdateAsync, configureNativeFilesForEASUpdateAsync, @@ -95,71 +92,6 @@ type UpdateFlags = { nonInteractive: boolean; }; -async function ensureChannelExistsAsync( - graphqlClient: ExpoGraphqlClient, - { - appId, - branchId, - channelName, - }: { - appId: string; - branchId: string; - channelName: string; - } -): Promise { - try { - await createUpdateChannelOnAppAsync(graphqlClient, { - appId, - channelName, - branchId, - }); - Log.withTick( - `Created a channel: ${chalk.bold(channelName)} pointed at branch: ${chalk.bold(channelName)}.` - ); - } catch (e: any) { - const isIgnorableError = - e.graphQLErrors?.length === 1 && - e.graphQLErrors[0].extensions.errorCode === 'CHANNEL_ALREADY_EXISTS'; - if (!isIgnorableError) { - throw e; - } - } -} - -export async function ensureBranchExistsAsync( - graphqlClient: ExpoGraphqlClient, - { appId, name: branchName }: ViewBranchQueryVariables -): Promise<{ - branchId: string; -}> { - try { - const updateBranch = await BranchQuery.getBranchByNameAsync(graphqlClient, { - appId, - name: branchName, - }); - - const { id } = updateBranch; - await ensureChannelExistsAsync(graphqlClient, { appId, branchId: id, channelName: branchName }); - return { branchId: id }; - } catch (error) { - if (error instanceof BranchNotFoundError) { - const newUpdateBranch = await createUpdateBranchOnAppAsync(graphqlClient, { - appId, - name: branchName, - }); - Log.withTick(`Created branch: ${chalk.bold(branchName)}`); - await ensureChannelExistsAsync(graphqlClient, { - appId, - branchId: newUpdateBranch.id, - channelName: branchName, - }); - return { branchId: newUpdateBranch.id }; - } else { - throw error; - } - } -} - export default class UpdatePublish extends EasCommand { static override description = 'publish an update group'; @@ -484,7 +416,12 @@ export default class UpdatePublish extends EasCommand { const { branchId } = await ensureBranchExistsAsync(graphqlClient, { appId: projectId, - name: branchName, + branchName, + }); + await ensureChannelExistsAsync(graphqlClient, { + appId: projectId, + branchId, + channelName: branchName, }); // Sort the updates into different groups based on their platform specific runtime versions