diff --git a/.changeset/auto-upgrade-escape-hatch.md b/.changeset/auto-upgrade-escape-hatch.md new file mode 100644 index 00000000000..d7ec2b7a758 --- /dev/null +++ b/.changeset/auto-upgrade-escape-hatch.md @@ -0,0 +1,6 @@ +--- +'@shopify/cli-kit': patch +'@shopify/cli': patch +--- + +Auto-upgrade is now on by default. Set SHOPIFY_CLI_NO_AUTO_UPGRADE=1 to opt out. diff --git a/packages/cli-kit/src/private/node/conf-store.ts b/packages/cli-kit/src/private/node/conf-store.ts index 55d100b3ae7..1c585eae41a 100644 --- a/packages/cli-kit/src/private/node/conf-store.ts +++ b/packages/cli-kit/src/private/node/conf-store.ts @@ -32,7 +32,6 @@ export interface ConfSchema { devSessionStore?: string currentDevSessionId?: string cache?: Cache - autoUpgradeEnabled?: boolean } let _instance: LocalStorage | undefined @@ -268,24 +267,6 @@ export async function runWithRateLimit(options: RunWithRateLimitOptions, config return true } -/** - * Get auto-upgrade preference. - * - * @returns Whether auto-upgrade is enabled, or undefined if not set. - */ -export function getAutoUpgradeEnabled(config: LocalStorage = cliKitStore()): boolean | undefined { - return config.get('autoUpgradeEnabled') -} - -/** - * Set auto-upgrade preference. - * - * @param enabled - Whether auto-upgrade should be enabled. - */ -export function setAutoUpgradeEnabled(enabled: boolean, config: LocalStorage = cliKitStore()): void { - config.set('autoUpgradeEnabled', enabled) -} - export function getConfigStoreForPartnerStatus() { return new LocalStorage>({ projectName: 'shopify-cli-kit-partner-status', diff --git a/packages/cli-kit/src/public/node/hooks/postrun.test.ts b/packages/cli-kit/src/public/node/hooks/postrun.test.ts index 4d2bc6ff6d6..a47e5a688ec 100644 --- a/packages/cli-kit/src/public/node/hooks/postrun.test.ts +++ b/packages/cli-kit/src/public/node/hooks/postrun.test.ts @@ -47,7 +47,9 @@ describe('autoUpgradeIfNeeded', () => { vi.mocked(versionToAutoUpgrade).mockReturnValue('3.100.0') vi.mocked(isMajorVersionChange).mockReturnValue(false) vi.mocked(runCLIUpgrade).mockRejectedValue(new Error('upgrade failed')) - vi.mocked(getOutputUpdateCLIReminder).mockReturnValue('💡 Version 3.100.0 available! Run `npm install -g @shopify/cli@latest`') + vi.mocked(getOutputUpdateCLIReminder).mockReturnValue( + '💡 Version 3.100.0 available! Run `npm install -g @shopify/cli@latest`', + ) await autoUpgradeIfNeeded() diff --git a/packages/cli-kit/src/public/node/is-global.test.ts b/packages/cli-kit/src/public/node/is-global.test.ts index 5142ba9d77b..5ed18d5186c 100644 --- a/packages/cli-kit/src/public/node/is-global.test.ts +++ b/packages/cli-kit/src/public/node/is-global.test.ts @@ -2,7 +2,7 @@ import {currentProcessIsGlobal, inferPackageManagerForGlobalCLI, installGlobalCL import {terminalSupportsPrompting} from './system.js' import {renderSelectPrompt} from './ui.js' import {globalCLIVersion} from './version.js' -import {beforeEach, describe, expect, test, vi, afterEach} from 'vitest' +import {describe, expect, test, vi, afterEach} from 'vitest' vi.mock('./system.js') vi.mock('./ui.js') diff --git a/packages/cli-kit/src/public/node/upgrade.test.ts b/packages/cli-kit/src/public/node/upgrade.test.ts index ab6221aeaab..83a5d3d8b99 100644 --- a/packages/cli-kit/src/public/node/upgrade.test.ts +++ b/packages/cli-kit/src/public/node/upgrade.test.ts @@ -7,7 +7,6 @@ import {vi, describe, test, expect, beforeEach} from 'vitest' vi.mock('./is-global.js') vi.mock('./node-package-manager.js') vi.mock('./system.js') -vi.mock('../../private/node/conf-store.js') describe('cliInstallCommand', () => { test('returns undefined when process is not global', () => { @@ -69,6 +68,15 @@ describe('versionToAutoUpgrade', () => { expect(got).toBeUndefined() }) + test('returns undefined when SHOPIFY_CLI_NO_AUTO_UPGRADE is set', () => { + vi.mocked(checkForCachedNewVersion).mockReturnValue('3.100.0') + vi.stubEnv('SHOPIFY_CLI_NO_AUTO_UPGRADE', '1') + + const got = versionToAutoUpgrade() + + expect(got).toBeUndefined() + }) + test('returns version when SHOPIFY_CLI_FORCE_AUTO_UPGRADE is set', () => { vi.mocked(checkForCachedNewVersion).mockReturnValue('3.100.0') vi.stubEnv('SHOPIFY_CLI_FORCE_AUTO_UPGRADE', '1') @@ -78,15 +86,14 @@ describe('versionToAutoUpgrade', () => { expect(got).toBe('3.100.0') }) - test('returns undefined when auto-upgrade is not enabled', async () => { + test('FORCE_AUTO_UPGRADE overrides NO_AUTO_UPGRADE', () => { vi.mocked(checkForCachedNewVersion).mockReturnValue('3.100.0') - - const {getAutoUpgradeEnabled} = await import('../../private/node/conf-store.js') - vi.mocked(getAutoUpgradeEnabled).mockReturnValue(false) + vi.stubEnv('SHOPIFY_CLI_NO_AUTO_UPGRADE', '1') + vi.stubEnv('SHOPIFY_CLI_FORCE_AUTO_UPGRADE', '1') const got = versionToAutoUpgrade() - expect(got).toBeUndefined() + expect(got).toBe('3.100.0') }) }) diff --git a/packages/cli-kit/src/public/node/upgrade.ts b/packages/cli-kit/src/public/node/upgrade.ts index d845a77bdf9..b7dd8810166 100644 --- a/packages/cli-kit/src/public/node/upgrade.ts +++ b/packages/cli-kit/src/public/node/upgrade.ts @@ -13,9 +13,7 @@ import { import {outputContent, outputDebug, outputInfo, outputToken} from './output.js' import {cwd, moduleDirectory, sniffForPath} from './path.js' import {exec, isCI} from './system.js' -import {renderConfirmationPrompt} from './ui.js' import {isPreReleaseVersion} from './version.js' -import {getAutoUpgradeEnabled, setAutoUpgradeEnabled} from '../../private/node/conf-store.js' import {CLI_KIT_VERSION} from '../common/version.js' /** @@ -79,7 +77,7 @@ export async function runCLIUpgrade(): Promise { /** * Returns the version to auto-upgrade to, or undefined if auto-upgrade should be skipped. - * Auto-upgrade is disabled by default and must be enabled via `shopify upgrade`. + * Auto-upgrade is on by default. Set SHOPIFY_CLI_NO_AUTO_UPGRADE=1 to opt out. * Also skips for CI, pre-release versions, or when no newer version is available. * * @returns The version string to upgrade to, or undefined if no upgrade should happen. @@ -95,8 +93,8 @@ export function versionToAutoUpgrade(): string | undefined { outputDebug('Auto-upgrade: Forcing auto-upgrade because of SHOPIFY_CLI_FORCE_AUTO_UPGRADE.') return newerVersion } - if (!getAutoUpgradeEnabled()) { - outputDebug('Auto-upgrade: Skipping because auto-upgrade is not enabled.') + if (process.env.SHOPIFY_CLI_NO_AUTO_UPGRADE === '1') { + outputDebug('Auto-upgrade: Disabled via SHOPIFY_CLI_NO_AUTO_UPGRADE.') return undefined } if (isCI()) { @@ -125,21 +123,6 @@ export function getOutputUpdateCLIReminder(version: string): string { return outputContent`💡 Version ${version} available!`.value } -/** - * Prompts the user to enable or disable automatic upgrades, then persists their choice. - * - * @returns Whether the user chose to enable auto-upgrade. - */ -export async function promptAutoUpgrade(): Promise { - const enabled = await renderConfirmationPrompt({ - message: 'Enable automatic updates for Shopify CLI?', - confirmationMessage: 'Yes, automatically update', - cancellationMessage: "No, I'll update manually", - }) - setAutoUpgradeEnabled(enabled) - return enabled -} - async function upgradeLocalShopify(projectDir: string, currentVersion: string) { const packageJson = (await findUpAndReadPackageJson(projectDir)).content const packageJsonDependencies = packageJson.dependencies ?? {} diff --git a/packages/cli/README.md b/packages/cli/README.md index 0ef528b2e4d..07fb8dee74b 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -2765,16 +2765,16 @@ DESCRIPTION ## `shopify upgrade` -Shows details on how to upgrade Shopify CLI. +Upgrades Shopify CLI. ``` USAGE $ shopify upgrade DESCRIPTION - Shows details on how to upgrade Shopify CLI. + Upgrades Shopify CLI. - Shows details on how to upgrade Shopify CLI. + Upgrades Shopify CLI using your package manager. ``` ## `shopify version` diff --git a/packages/cli/oclif.manifest.json b/packages/cli/oclif.manifest.json index 8a053bd1ea3..78675c99fcf 100644 --- a/packages/cli/oclif.manifest.json +++ b/packages/cli/oclif.manifest.json @@ -7822,8 +7822,8 @@ ], "args": { }, - "description": "Shows details on how to upgrade Shopify CLI.", - "descriptionWithMarkdown": "Shows details on how to upgrade Shopify CLI.", + "description": "Upgrades Shopify CLI using your package manager.", + "descriptionWithMarkdown": "Upgrades Shopify CLI using your package manager.", "enableJsonFlag": false, "flags": { }, @@ -7835,7 +7835,7 @@ "pluginName": "@shopify/cli", "pluginType": "core", "strict": true, - "summary": "Shows details on how to upgrade Shopify CLI." + "summary": "Upgrades Shopify CLI." }, "version": { "aliases": [ diff --git a/packages/cli/src/cli/commands/upgrade.test.ts b/packages/cli/src/cli/commands/upgrade.test.ts index 61e04ba2059..890b87ae6d0 100644 --- a/packages/cli/src/cli/commands/upgrade.test.ts +++ b/packages/cli/src/cli/commands/upgrade.test.ts @@ -1,18 +1,15 @@ import Upgrade from './upgrade.js' +import {runCLIUpgrade} from '@shopify/cli-kit/node/upgrade' import {describe, test, vi, expect} from 'vitest' -vi.mock('@shopify/cli-kit/node/upgrade', () => ({ - promptAutoUpgrade: vi.fn().mockResolvedValue(true), - runCLIUpgrade: vi.fn().mockResolvedValue(undefined), -})) +vi.mock('@shopify/cli-kit/node/upgrade') describe('upgrade command', () => { - test('calls promptAutoUpgrade and runCLIUpgrade', async () => { - const {promptAutoUpgrade, runCLIUpgrade} = await import('@shopify/cli-kit/node/upgrade') + test('calls runCLIUpgrade', async () => { + vi.mocked(runCLIUpgrade).mockResolvedValue(undefined) await Upgrade.run([], import.meta.url) - expect(promptAutoUpgrade).toHaveBeenCalledOnce() expect(runCLIUpgrade).toHaveBeenCalledOnce() }) }) diff --git a/packages/cli/src/cli/commands/upgrade.ts b/packages/cli/src/cli/commands/upgrade.ts index aeb5217ee2f..c8e39ffaf2c 100644 --- a/packages/cli/src/cli/commands/upgrade.ts +++ b/packages/cli/src/cli/commands/upgrade.ts @@ -1,5 +1,5 @@ import Command from '@shopify/cli-kit/node/base-command' -import {promptAutoUpgrade, runCLIUpgrade} from '@shopify/cli-kit/node/upgrade' +import {runCLIUpgrade} from '@shopify/cli-kit/node/upgrade' export default class Upgrade extends Command { static summary = 'Upgrades Shopify CLI.' @@ -9,7 +9,6 @@ export default class Upgrade extends Command { static description = this.descriptionWithoutMarkdown() async run(): Promise { - await promptAutoUpgrade() await runCLIUpgrade() } }