diff --git a/packages/app/src/cli/models/app/app.ts b/packages/app/src/cli/models/app/app.ts index 721caed598..a1867ff40f 100644 --- a/packages/app/src/cli/models/app/app.ts +++ b/packages/app/src/cli/models/app/app.ts @@ -357,7 +357,8 @@ export class App< type: module.externalType, handle: module.handle, uid: module.uid, - uuid: identifiers?.extensions[module.localIdentifier] ?? undefined, + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + uuid: identifiers?.extensions[module.localIdentifier] || undefined, assets: module.configuration.uid ?? module.handle, target: module.contextValue, config: (config ?? {}) as JsonMapType, diff --git a/packages/app/src/cli/models/app/identifiers.ts b/packages/app/src/cli/models/app/identifiers.ts index e594cc7b33..93955de080 100644 --- a/packages/app/src/cli/models/app/identifiers.ts +++ b/packages/app/src/cli/models/app/identifiers.ts @@ -80,7 +80,10 @@ export async function updateAppIdentifiers( }) const contentIsEqual = deepCompare(dotenvFile.variables, updatedVariables) - const writeToFile = !contentIsEqual && (command === 'deploy' || command === 'release') + const writeToFile = + !contentIsEqual && + (command === 'deploy' || command === 'release') && + !developerPlatformClient.supportsAtomicDeployments dotenvFile.variables = updatedVariables if (writeToFile) { diff --git a/packages/app/src/cli/services/app/patch-app-configuration-file.test.ts b/packages/app/src/cli/services/app/patch-app-configuration-file.test.ts index 8aa4c5fd8b..3129a5e29d 100644 --- a/packages/app/src/cli/services/app/patch-app-configuration-file.test.ts +++ b/packages/app/src/cli/services/app/patch-app-configuration-file.test.ts @@ -48,7 +48,7 @@ describe('patchAppConfigurationFile', () => { }, } - await patchAppConfigurationFile({path: configPath, patch, schema}) + patchAppConfigurationFile({path: configPath, patch, schema}) const updatedTomlFile = await readFile(configPath) expect(updatedTomlFile) @@ -85,7 +85,7 @@ api_version = "2023-04" }, } - await patchAppConfigurationFile({path: configPath, patch, schema}) + patchAppConfigurationFile({path: configPath, patch, schema}) const updatedTomlFile = await readFile(configPath) expect(updatedTomlFile) @@ -125,7 +125,7 @@ dev_store_url = "example.myshopify.com" }, } - await patchAppConfigurationFile({path: configPath, patch, schema}) + patchAppConfigurationFile({path: configPath, patch, schema}) const updatedTomlFile = await readFile(configPath) expect(updatedTomlFile) @@ -164,7 +164,7 @@ random_toml_field = "random_value" ) const patch = {name: 123} - await patchAppConfigurationFile({path: configPath, patch, schema: undefined}) + patchAppConfigurationFile({path: configPath, patch, schema: undefined}) const updatedTomlFile = await readFile(configPath) expect(updatedTomlFile) diff --git a/packages/app/src/cli/services/app/patch-app-configuration-file.ts b/packages/app/src/cli/services/app/patch-app-configuration-file.ts index cb36d38446..fd6b5311b3 100644 --- a/packages/app/src/cli/services/app/patch-app-configuration-file.ts +++ b/packages/app/src/cli/services/app/patch-app-configuration-file.ts @@ -1,8 +1,9 @@ import {addDefaultCommentsToToml} from './write-app-configuration-file.js' import {deepMergeObjects} from '@shopify/cli-kit/common/object' -import {readFile, writeFile} from '@shopify/cli-kit/node/fs' +import {readFileSync} from '@shopify/cli-kit/node/fs' import {zod} from '@shopify/cli-kit/node/schema' import {decodeToml, encodeToml} from '@shopify/cli-kit/node/toml' +import {writeFileSync} from 'fs' export interface PatchTomlOptions { path: string @@ -22,8 +23,8 @@ export interface PatchTomlOptions { * @param patch - The patch to apply to the app configuration file. * @param schema - The schema to validate the patch against. If not provided, the toml will not be validated. */ -export async function patchAppConfigurationFile({path, patch, schema}: PatchTomlOptions) { - const tomlContents = await readFile(path) +export function patchAppConfigurationFile({path, patch, schema}: PatchTomlOptions) { + const tomlContents = readFileSync(path).toString() const configuration = decodeToml(tomlContents) // Deep merge the configuration with the patch. @@ -37,7 +38,7 @@ export async function patchAppConfigurationFile({path, patch, schema}: PatchToml let encodedString = encodeToml(updatedConfig) encodedString = addDefaultCommentsToToml(encodedString) - await writeFile(path, encodedString) + writeFileSync(path, encodedString) } export function replaceArrayStrategy(_: unknown[], newArray: unknown[]): unknown[] { diff --git a/packages/app/src/cli/services/context.ts b/packages/app/src/cli/services/context.ts index 9748d5c1d5..baf45d2de2 100644 --- a/packages/app/src/cli/services/context.ts +++ b/packages/app/src/cli/services/context.ts @@ -180,7 +180,7 @@ async function removeIncludeConfigOnDeployField(localApp: AppInterface) { if (includeConfigOnDeploy === undefined) return const patch = {build: {include_config_on_deploy: undefined}} - await patchAppConfigurationFile({path: localApp.configuration.path, patch, schema: localApp.configSchema}) + patchAppConfigurationFile({path: localApp.configuration.path, patch, schema: localApp.configSchema}) includeConfigOnDeploy ? renderInfoAboutIncludeConfigOnDeploy() : renderWarningAboutIncludeConfigOnDeploy() } @@ -219,7 +219,7 @@ async function promptIncludeConfigOnDeploy(options: ShouldOrPromptIncludeConfigD include_config_on_deploy: shouldIncludeConfigDeploy, } const patch = {build: {include_config_on_deploy: shouldIncludeConfigDeploy}} - await patchAppConfigurationFile({path: localConfiguration.path, patch, schema: options.localApp.configSchema}) + patchAppConfigurationFile({path: localConfiguration.path, patch, schema: options.localApp.configSchema}) await metadata.addPublicMetadata(() => ({cmd_deploy_confirm_include_config_used: shouldIncludeConfigDeploy})) } diff --git a/packages/app/src/cli/services/context/id-matching.ts b/packages/app/src/cli/services/context/id-matching.ts index a563cfef42..9bbc42ac79 100644 --- a/packages/app/src/cli/services/context/id-matching.ts +++ b/packages/app/src/cli/services/context/id-matching.ts @@ -54,7 +54,7 @@ function matchByNameAndType( if (possibleMatch) matched[localSource.localIdentifier] = possibleMatch.uuid }) - const pendingLocal = local.filter((elem) => !matched[elem.localIdentifier]) + const pendingLocal = local.filter((elem) => matched[elem.localIdentifier] === undefined) const pendingRemote = remote.filter((registration) => !Object.values(matched).includes(registration.uuid)) // Now we try to find a match between a local source and remote one if they have diff --git a/packages/app/src/cli/services/context/identifiers.ts b/packages/app/src/cli/services/context/identifiers.ts index cdcb57b748..85b1bb79e0 100644 --- a/packages/app/src/cli/services/context/identifiers.ts +++ b/packages/app/src/cli/services/context/identifiers.ts @@ -6,6 +6,7 @@ import {MinimalOrganizationApp} from '../../models/organization.js' import {deployOrReleaseConfirmationPrompt} from '../../prompts/deploy-release.js' import {AppVersion, DeveloperPlatformClient} from '../../utilities/developer-platform-client.js' import {AbortSilentError} from '@shopify/cli-kit/node/error' +import {randomUUID} from '@shopify/cli-kit/node/crypto' export type PartnersAppForIdentifierMatching = MinimalOrganizationApp @@ -70,6 +71,16 @@ export async function ensureDeploymentIdsPresence(options: EnsureDeploymentIdsPr extensionsToConfirm, ) + // Update the matched local extensions with the remote UIDs + Object.keys(extensionsToConfirm.validMatches).forEach((handle) => { + const extension = options.app.allExtensions.find((ext) => ext.handle === handle) + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + const uid = extensionsToConfirm.validMatches[handle] || randomUUID() + if (!extension || !uid) return + extension.uid = uid + extension.configuration.uid = uid + }) + return { app: options.appId, extensions: result.extensions, diff --git a/packages/app/src/cli/services/dev.ts b/packages/app/src/cli/services/dev.ts index 3b88ec5692..bce4d1094e 100644 --- a/packages/app/src/cli/services/dev.ts +++ b/packages/app/src/cli/services/dev.ts @@ -109,7 +109,7 @@ async function prepareForDev(commandOptions: DevOptions): Promise { dev_store_url: store.shopDomain, } const patch = {build: {dev_store_url: store.shopDomain}} - await patchAppConfigurationFile({path: app.configuration.path, patch, schema: app.configSchema}) + patchAppConfigurationFile({path: app.configuration.path, patch, schema: app.configSchema}) } if (!commandOptions.skipDependenciesInstallation && !app.usesWorkspaces) { diff --git a/packages/app/src/cli/services/dev/urls.ts b/packages/app/src/cli/services/dev/urls.ts index 42d8564b77..e310c9993e 100644 --- a/packages/app/src/cli/services/dev/urls.ts +++ b/packages/app/src/cli/services/dev/urls.ts @@ -219,7 +219,7 @@ export async function updateURLs( : {}), } - await patchAppConfigurationFile({path: localApp.configuration.path, patch, schema: localApp.configSchema}) + patchAppConfigurationFile({path: localApp.configuration.path, patch, schema: localApp.configSchema}) } } @@ -266,7 +266,7 @@ export async function shouldOrPromptUpdateURLs(options: ShouldOrPromptUpdateURLs } const patch = {build: {automatically_update_urls_on_dev: shouldUpdateURLs}} const path = options.localApp.configuration.path - await patchAppConfigurationFile({path, patch, schema: options.localApp.configSchema}) + patchAppConfigurationFile({path, patch, schema: options.localApp.configSchema}) } else { setCachedAppInfo({directory: options.appDirectory, updateURLs: shouldUpdateURLs}) } diff --git a/packages/cli-kit/src/public/node/fs.ts b/packages/cli-kit/src/public/node/fs.ts index 44799515c9..b5fa2c441b 100644 --- a/packages/cli-kit/src/public/node/fs.ts +++ b/packages/cli-kit/src/public/node/fs.ts @@ -215,7 +215,7 @@ export async function writeFile( * @param data - Content to be written. */ export function writeFileSync(path: string, data: string): void { - outputDebug(outputContent`File-writing some content to file at ${outputToken.path(path)}...`) + outputDebug(outputContent`Sync-writing some content to file at ${outputToken.path(path)}...`) fsWriteFileSync(path, data) }