Skip to content

Commit

Permalink
Merge pull request #4645 from Shopify/use-app-context-in-app-deploy
Browse files Browse the repository at this point in the history
Use app context in `app deploy`
  • Loading branch information
isaacroldan authored Oct 15, 2024
2 parents 8574078 + 738bb66 commit fac882b
Show file tree
Hide file tree
Showing 12 changed files with 132 additions and 554 deletions.
25 changes: 15 additions & 10 deletions packages/app/src/cli/commands/app/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import {appFlags} from '../../flags.js'
import {deploy} from '../../services/deploy.js'
import {AppInterface} from '../../models/app/app.js'
import {loadApp} from '../../models/app/loader.js'
import {getAppConfigurationState} from '../../models/app/loader.js'
import {validateVersion} from '../../validations/version-name.js'
import {showApiKeyDeprecationWarning} from '../../prompts/deprecation-warnings.js'
import {validateMessage} from '../../validations/message.js'
import metadata from '../../metadata.js'
import {loadLocalExtensionsSpecifications} from '../../models/extensions/load-specifications.js'
import AppCommand, {AppCommandOutput} from '../../utilities/app-command.js'
import {linkedAppContext} from '../../services/app-context.js'
import {Flags} from '@oclif/core'
import {globalFlags} from '@shopify/cli-kit/node/cli'
import {addPublicMetadata} from '@shopify/cli-kit/node/metadata'
Expand Down Expand Up @@ -100,19 +99,25 @@ export default class Deploy extends AppCommand {
cmd_app_reset_used: flags.reset,
}))

const app: AppInterface = await loadApp({
const requiredNonTTYFlags = ['force']
const configurationState = await getAppConfigurationState(flags.path, flags.config)
if (configurationState.state === 'template-only' && !apiKey) {
requiredNonTTYFlags.push('client-id')
}
this.failMissingNonTTYFlags(flags, requiredNonTTYFlags)

const {app, remoteApp, developerPlatformClient, organization} = await linkedAppContext({
directory: flags.path,
clientId: apiKey,
forceRelink: flags.reset,
userProvidedConfigName: flags.config,
specifications: await loadLocalExtensionsSpecifications(),
})

const requiredNonTTYFlags = ['force']
if (!apiKey && !app.configuration.client_id) requiredNonTTYFlags.push('client-id')
this.failMissingNonTTYFlags(flags, requiredNonTTYFlags)

const result = await deploy({
app,
apiKey,
remoteApp,
organization,
developerPlatformClient,
reset: flags.reset,
force: flags.force,
noRelease: flags['no-release'],
Expand Down
3 changes: 2 additions & 1 deletion packages/app/src/cli/commands/app/versions/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default class VersionsList extends AppCommand {
}
const apiKey = flags['client-id'] || flags['api-key']

const {app, remoteApp, developerPlatformClient} = await linkedAppContext({
const {app, remoteApp, developerPlatformClient, organization} = await linkedAppContext({
directory: flags.path,
clientId: apiKey,
forceRelink: false,
Expand All @@ -58,6 +58,7 @@ export default class VersionsList extends AppCommand {
await versionList({
app,
remoteApp,
organization,
developerPlatformClient,
json: flags.json,
})
Expand Down
8 changes: 4 additions & 4 deletions packages/app/src/cli/models/app/app.test-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,14 @@ export function testAppWithLegacyConfig({
return testApp({...app, configuration}) as AppInterface<LegacyAppConfiguration>
}

export function testAppWithConfig(options?: TestAppWithConfigOptions): AppInterface<CurrentAppConfiguration> {
const app = testApp(options?.app, 'current')
export function testAppWithConfig(options?: TestAppWithConfigOptions): AppLinkedInterface {
const app = testAppLinked(options?.app)
app.configuration = {
...DEFAULT_CONFIG,
...options?.config,
} as CurrentAppConfiguration

return app as AppInterface<CurrentAppConfiguration>
return app
}

export function getWebhookConfig(webhookConfigOverrides?: WebhooksConfig): CurrentAppConfiguration {
Expand All @@ -166,7 +166,7 @@ export function getWebhookConfig(webhookConfigOverrides?: WebhooksConfig): Curre
}
}

function testOrganization(): Organization {
export function testOrganization(): Organization {
return {
id: '1',
businessName: 'org1',
Expand Down
9 changes: 7 additions & 2 deletions packages/app/src/cli/services/app-context.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import link from './app/config/link.js'
import {appFromId} from './context.js'

import * as localStorage from './local-storage.js'
import {testOrganizationApp, testDeveloperPlatformClient} from '../models/app/app.test-data.js'
import {fetchOrgFromId} from './dev/fetch.js'
import {testOrganizationApp, testDeveloperPlatformClient, testOrganization} from '../models/app/app.test-data.js'
import metadata from '../metadata.js'
import * as loader from '../models/app/loader.js'
import {beforeEach, describe, expect, test, vi} from 'vitest'
Expand All @@ -15,7 +16,7 @@ import {tryParseInt} from '@shopify/cli-kit/common/string'
vi.mock('./generate/fetch-extension-specifications.js')
vi.mock('./app/config/link.js')
vi.mock('./context.js')

vi.mock('./dev/fetch.js')
async function writeAppConfig(tmp: string, content: string) {
const appConfigPath = joinPath(tmp, 'shopify.app.toml')
const packageJsonPath = joinPath(tmp, 'package.json')
Expand All @@ -24,6 +25,7 @@ async function writeAppConfig(tmp: string, content: string) {
}

const mockDeveloperPlatformClient = testDeveloperPlatformClient()
const mockOrganization = testOrganization()
const mockRemoteApp = testOrganizationApp({
apiKey: 'test-api-key',
title: 'Test App',
Expand All @@ -34,6 +36,7 @@ const mockRemoteApp = testOrganizationApp({
beforeEach(() => {
vi.mocked(fetchSpecifications).mockResolvedValue([])
vi.mocked(appFromId).mockResolvedValue(mockRemoteApp)
vi.mocked(fetchOrgFromId).mockResolvedValue(mockOrganization)
})

describe('linkedAppContext', () => {
Expand Down Expand Up @@ -62,6 +65,7 @@ describe('linkedAppContext', () => {
remoteApp: mockRemoteApp,
developerPlatformClient: expect.any(Object),
specifications: [],
organization: mockOrganization,
})
expect(link).not.toHaveBeenCalled()
})
Expand Down Expand Up @@ -105,6 +109,7 @@ describe('linkedAppContext', () => {
remoteApp: mockRemoteApp,
developerPlatformClient: expect.any(Object),
specifications: [],
organization: mockOrganization,
})
expect(link).toHaveBeenCalledWith({directory: tmp, apiKey: undefined, configName: undefined})
})
Expand Down
8 changes: 6 additions & 2 deletions packages/app/src/cli/services/app-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import {appFromId} from './context.js'
import {getCachedAppInfo, setCachedAppInfo} from './local-storage.js'
import {fetchSpecifications} from './generate/fetch-extension-specifications.js'
import link from './app/config/link.js'
import {OrganizationApp} from '../models/organization.js'
import {fetchOrgFromId} from './dev/fetch.js'
import {Organization, OrganizationApp} from '../models/organization.js'
import {DeveloperPlatformClient, selectDeveloperPlatformClient} from '../utilities/developer-platform-client.js'
import {getAppConfigurationState, loadAppUsingConfigurationState} from '../models/app/loader.js'
import {RemoteAwareExtensionSpecification} from '../models/extensions/specification.js'
Expand All @@ -14,6 +15,7 @@ interface LoadedAppContextOutput {
app: AppLinkedInterface
remoteApp: OrganizationApp
developerPlatformClient: DeveloperPlatformClient
organization: Organization
specifications: RemoteAwareExtensionSpecification[]
}

Expand Down Expand Up @@ -77,6 +79,8 @@ export async function linkedAppContext({
}
developerPlatformClient = remoteApp.developerPlatformClient ?? developerPlatformClient

const organization = await fetchOrgFromId(remoteApp.organizationId, developerPlatformClient)

// Fetch the remote app's specifications
const specifications = await fetchSpecifications({developerPlatformClient, app: remoteApp})

Expand All @@ -96,7 +100,7 @@ export async function linkedAppContext({

await logMetadata(remoteApp)

return {app: localApp, remoteApp, developerPlatformClient, specifications}
return {app: localApp, remoteApp, developerPlatformClient, specifications, organization}
}

async function logMetadata(app: {organizationId: string; apiKey: string}) {
Expand Down
Loading

0 comments on commit fac882b

Please sign in to comment.