Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/cli-kit/src/public/node/hooks/postrun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ async function performAutoUpgrade(newerVersion: string): Promise<void> {
}

try {
await runCLIUpgrade()
await runCLIUpgrade({autoupgrade: true})
await metadata.addPublicMetadata(() => ({env_auto_upgrade_success: true}))
// eslint-disable-next-line no-catch-all/no-catch-all
} catch (error) {
Expand Down
11 changes: 11 additions & 0 deletions packages/cli-kit/src/public/node/upgrade.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,17 @@ describe('runCLIUpgrade', () => {
// Then
expect(exec).not.toHaveBeenCalled()
})

test('skips project-local upgrade when called from the auto-upgrade postrun hook', async () => {
// Given
vi.mocked(currentProcessIsGlobal).mockReturnValue(false)

// When
await runCLIUpgrade({autoupgrade: true})

// Then
expect(exec).not.toHaveBeenCalled()
})
})

describe('versionToAutoUpgrade', () => {
Expand Down
24 changes: 23 additions & 1 deletion packages/cli-kit/src/public/node/upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,27 @@ export function cliInstallCommand(): string | undefined {
}
}

/**
* Options for {@link runCLIUpgrade}.
*/
export interface RunCLIUpgradeOptions {
/**
* `true` when the upgrade is being triggered by the automatic postrun hook.
* In that case we skip project-local upgrades — those should only happen when the
* user explicitly runs `shopify upgrade` so we don't surprise them by mutating
* their `package.json` / lockfile in the background.
*/
autoupgrade?: boolean
}

/**
* Runs the CLI upgrade using the appropriate package manager.
* Determines the install command and executes it.
*
* @param options - See {@link RunCLIUpgradeOptions}.
* @throws AbortError if the package manager or command cannot be determined.
*/
export async function runCLIUpgrade(): Promise<void> {
export async function runCLIUpgrade(options: RunCLIUpgradeOptions = {}): Promise<void> {
// Path where the current project is (app/hydrogen)
const path = sniffForPath() ?? cwd()
const projectDir = getProjectDir(path)
Expand All @@ -61,6 +75,14 @@ export async function runCLIUpgrade(): Promise<void> {
return
}

// When triggered by the automatic postrun hook, skip project-local upgrades.
// Bumping `package.json` / lockfile silently in the background would surprise users
// and produce noisy diffs; explicit `shopify upgrade` invocations still upgrade the
// local project.
if (options.autoupgrade && !isGlobal) {
return
}

// Generate the install command for the global CLI and execute it
if (isGlobal) {
const installCommand = cliInstallCommand()
Expand Down
Loading