Skip to content

Commit

Permalink
Merge pull request #5149 from Shopify/01-02-execute_adduidtotoml_in_a…
Browse files Browse the repository at this point in the history
…pp-context_for_all_commands

Execute addUidToToml in app-context for all commands
  • Loading branch information
isaacroldan authored Jan 2, 2025
2 parents 7aa290c + c431e4f commit f649fa5
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 292 deletions.
254 changes: 0 additions & 254 deletions packages/app/src/cli/models/app/identifiers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,260 +114,6 @@ describe('updateAppIdentifiers', () => {
}
})
})

test('adds the missing uid to a simple TOML for atomic deployments', async () => {
await inTemporaryDirectory(async (tmpDir: string) => {
// Given
const uiExtension = await testUIExtension({directory: tmpDir})
const app = testApp({
directory: tmpDir,
allExtensions: [uiExtension],
})
await writeFile(
uiExtension.configurationPath,
`name = "tae"
type = "theme"`,
)

// When
await updateAppIdentifiers(
{
app,
identifiers: {
app: 'FOO',
extensions: {
my_extension: 'BAR',
},
},
command: 'deploy',
developerPlatformClient: testDeveloperPlatformClient({supportsAtomicDeployments: true}),
},
{SHOPIFY_API_KEY: 'FOO', SHOPIFY_MY_EXTENSION_ID: 'BAR'},
)

// Then
const fileContent = await readFile(uiExtension.configurationPath)
expect(fileContent).toEqual(`name = "tae"
uid = "${uiExtension.uid}"
type = "theme"`)
})
})
})

test('does not change a simple TOML when the uid is already present for atomic deployments', async () => {
await inTemporaryDirectory(async (tmpDir: string) => {
// Given
const uiExtension = await testUIExtension({directory: tmpDir})
const app = testApp({
directory: tmpDir,
allExtensions: [uiExtension],
})
await writeFile(
uiExtension.configurationPath,
`name = "tae"
uid = "${uiExtension.uid}"
type = "theme"`,
)

// When
await updateAppIdentifiers(
{
app,
identifiers: {
app: 'FOO',
extensions: {
my_extension: 'BAR',
},
},
command: 'deploy',
developerPlatformClient: testDeveloperPlatformClient({supportsAtomicDeployments: true}),
},
{SHOPIFY_API_KEY: 'FOO', SHOPIFY_MY_EXTENSION_ID: 'BAR'},
)

// Then
const fileContent = await readFile(uiExtension.configurationPath)
expect(fileContent).toEqual(`name = "tae"
uid = "${uiExtension.uid}"
type = "theme"`)
})
})

test('adds the missing uid to a unified config TOML for atomic deployments', async () => {
await inTemporaryDirectory(async (tmpDir: string) => {
// Given
const uiExtension = await testUIExtension({
directory: tmpDir,
configuration: {
name: 'Extension 1',
handle: 'ext1',
type: 'ui_extension',
metafields: [],
},
})
const app = testApp({
directory: tmpDir,
allExtensions: [uiExtension],
})
await writeFile(
uiExtension.configurationPath,
`api_version = "2024-04"
[[extensions]]
name = "Extension 1"
handle = "ext1"
type = "ui_extension"`,
)

// When
await updateAppIdentifiers(
{
app,
identifiers: {
app: 'FOO',
extensions: {
my_extension: 'BAR',
},
},
command: 'deploy',
developerPlatformClient: testDeveloperPlatformClient({supportsAtomicDeployments: true}),
},
{SHOPIFY_API_KEY: 'FOO', SHOPIFY_MY_EXTENSION_ID: 'BAR'},
)

// Then
const fileContent = await readFile(uiExtension.configurationPath)
expect(fileContent).toEqual(`api_version = "2024-04"
[[extensions]]
name = "Extension 1"
handle = "ext1"
uid = "${uiExtension.uid}"
type = "ui_extension"`)
})
})

test('does not change a unified config TOML when the uid is already present for atomic deployments', async () => {
await inTemporaryDirectory(async (tmpDir: string) => {
// Given
const uiExtension = await testUIExtension({
directory: tmpDir,
configuration: {
name: 'Extension 1',
handle: 'ext1',
type: 'ui_extension',
metafields: [],
},
})
const app = testApp({
directory: tmpDir,
allExtensions: [uiExtension],
})
await writeFile(
uiExtension.configurationPath,
`api_version = "2024-04"
[[extensions]]
name = "Extension 1"
handle = "ext1"
uid = "${uiExtension.uid}"
type = "ui_extension"`,
)

// When
await updateAppIdentifiers(
{
app,
identifiers: {
app: 'FOO',
extensions: {
my_extension: 'BAR',
},
},
command: 'deploy',
developerPlatformClient: testDeveloperPlatformClient({supportsAtomicDeployments: true}),
},
{SHOPIFY_API_KEY: 'FOO', SHOPIFY_MY_EXTENSION_ID: 'BAR'},
)

// Then
const fileContent = await readFile(uiExtension.configurationPath)
expect(fileContent).toEqual(`api_version = "2024-04"
[[extensions]]
name = "Extension 1"
handle = "ext1"
uid = "${uiExtension.uid}"
type = "ui_extension"`)
})
})

test('adds the missing uids to a unified config TOML with multiple extensions for atomic deployments', async () => {
await inTemporaryDirectory(async (tmpDir: string) => {
// Given
const uiExtension1 = await testUIExtension({
directory: tmpDir,
configuration: {
name: 'Extension 1',
handle: 'ext1',
type: 'ui_extension',
metafields: [],
},
})
const uiExtension2 = await testUIExtension({
directory: tmpDir,
configuration: {
name: 'Extension 2',
handle: 'ext2',
type: 'ui_extension',
metafields: [],
},
})
const app = testApp({
directory: tmpDir,
allExtensions: [uiExtension1, uiExtension2],
})
await writeFile(
uiExtension1.configurationPath,
`api_version = "2024-04"
[[extensions]]
name = "t:name"
handle = "ext2"
type = "ui_extension"
[[extensions]]
name = "t:name"
handle = "ext1"
type = "ui_extension"`,
)

// When
await updateAppIdentifiers(
{
app,
identifiers: {
app: 'FOO',
extensions: {
my_extension: 'BAR',
},
},
command: 'deploy',
developerPlatformClient: testDeveloperPlatformClient({supportsAtomicDeployments: true}),
},
{SHOPIFY_API_KEY: 'FOO', SHOPIFY_MY_EXTENSION_ID: 'BAR'},
)

// Then
const fileContent = await readFile(uiExtension1.configurationPath)
expect(fileContent).toEqual(`api_version = "2024-04"
[[extensions]]
name = "t:name"
handle = "ext2"
uid = "${uiExtension2.uid}"
type = "ui_extension"
[[extensions]]
name = "t:name"
handle = "ext1"
uid = "${uiExtension1.uid}"
type = "ui_extension"`)
})
})

test('does not change a unified config TOML with multiple when the uid is already present for atomic deployments', async () => {
Expand Down
40 changes: 2 additions & 38 deletions packages/app/src/cli/models/app/identifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import {patchEnvFile} from '@shopify/cli-kit/node/dot-env'
import {constantize} from '@shopify/cli-kit/common/string'
import {joinPath} from '@shopify/cli-kit/node/path'
import {fileExists, readFile, writeFile} from '@shopify/cli-kit/node/fs'
import {deepCompare, getPathValue} from '@shopify/cli-kit/common/object'
import {decodeToml} from '@shopify/cli-kit/node/toml'
import {deepCompare} from '@shopify/cli-kit/common/object'
import type {AppInterface} from './app.js'

export interface IdentifiersExtensions {
Expand Down Expand Up @@ -48,17 +47,9 @@ interface UpdateAppIdentifiersOptions {
* @returns An copy of the app with the environment updated to reflect the updated identifiers.
*/
export async function updateAppIdentifiers(
{app, identifiers, command, developerPlatformClient}: UpdateAppIdentifiersOptions,
{app, identifiers, command}: UpdateAppIdentifiersOptions,
systemEnvironment = process.env,
): Promise<AppInterface> {
if (developerPlatformClient.supportsAtomicDeployments) {
// We can't update the TOML files in parallel because some extensions might share the same file
for (const extension of app.allExtensions) {
// eslint-disable-next-line no-await-in-loop
await addUidToToml(extension)
}
}

let dotenvFile = app.dotenv

if (!dotenvFile) {
Expand Down Expand Up @@ -95,33 +86,6 @@ export async function updateAppIdentifiers(
return app
}

async function addUidToToml(extension: ExtensionInstance) {
if (!extension.isUUIDStrategyExtension) return

const tomlContents = await readFile(extension.configurationPath)
const extensionConfig = decodeToml(tomlContents)
const extensions = getPathValue(extensionConfig, 'extensions') as ExtensionInstance[]

if ('uid' in extensionConfig) return
if (extensions) {
const currentExtension = extensions.find((ext) => ext.handle === extension.handle)
if (currentExtension && 'uid' in currentExtension) return
}

let updatedTomlContents = tomlContents
if (extensions?.length > 1) {
// If the TOML has multiple extensions, we look for the correct handle to add the uid below
const regex = new RegExp(`(\\n?(\\s*)handle\\s*=\\s*"${extension.handle}")`)
updatedTomlContents = tomlContents.replace(regex, `$1\n$2uid = "${extension.uid}"`)
} else {
// If the TOML has only one extension, we add the uid before the type, which is always present
if ('uid' in extensionConfig) return
const regex = /\n?((\s*)type\s*=\s*"\S*")/
updatedTomlContents = tomlContents.replace(regex, `$2\nuid = "${extension.uid}"\n$1`)
}
await writeFile(extension.configurationPath, updatedTomlContents)
}

interface GetAppIdentifiersOptions {
app: AppInterface
}
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/cli/services/app-context.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ vi.mock('./generate/fetch-extension-specifications.js')
vi.mock('./app/config/link.js')
vi.mock('./context.js')
vi.mock('./dev/fetch.js')
vi.mock('./app/add-uid-to-extension-toml.js')

async function writeAppConfig(tmp: string, content: string) {
const appConfigPath = joinPath(tmp, 'shopify.app.toml')
Expand Down
4 changes: 4 additions & 0 deletions packages/app/src/cli/services/app-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {getCachedAppInfo, setCachedAppInfo} from './local-storage.js'
import {fetchSpecifications} from './generate/fetch-extension-specifications.js'
import link from './app/config/link.js'
import {fetchOrgFromId} from './dev/fetch.js'
import {addUidToTomlsIfNecessary} from './app/add-uid-to-extension-toml.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'
Expand Down Expand Up @@ -99,6 +100,9 @@ export async function linkedAppContext({

await logMetadata(remoteApp, forceRelink)

// Add UIDs to extension TOML files if using app-management.
await addUidToTomlsIfNecessary(localApp.allExtensions, developerPlatformClient)

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

Expand Down
Loading

0 comments on commit f649fa5

Please sign in to comment.