Skip to content
Draft
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
6 changes: 6 additions & 0 deletions .changeset/auto-upgrade-escape-hatch.md
Original file line number Diff line number Diff line change
@@ -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.
19 changes: 0 additions & 19 deletions packages/cli-kit/src/private/node/conf-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export interface ConfSchema {
devSessionStore?: string
currentDevSessionId?: string
cache?: Cache
autoUpgradeEnabled?: boolean
}

let _instance: LocalStorage<ConfSchema> | undefined
Expand Down Expand Up @@ -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<ConfSchema> = 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<ConfSchema> = cliKitStore()): void {
config.set('autoUpgradeEnabled', enabled)
}

export function getConfigStoreForPartnerStatus() {
return new LocalStorage<Record<string, {status: true; checkedAt: string}>>({
projectName: 'shopify-cli-kit-partner-status',
Expand Down
4 changes: 3 additions & 1 deletion packages/cli-kit/src/public/node/hooks/postrun.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
2 changes: 1 addition & 1 deletion packages/cli-kit/src/public/node/is-global.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down
19 changes: 13 additions & 6 deletions packages/cli-kit/src/public/node/upgrade.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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')
Expand All @@ -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')
})
})

Expand Down
23 changes: 3 additions & 20 deletions packages/cli-kit/src/public/node/upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'

/**
Expand Down Expand Up @@ -79,7 +77,7 @@ export async function runCLIUpgrade(): Promise<void> {

/**
* 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.
Expand All @@ -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()) {
Expand Down Expand Up @@ -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<boolean> {
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 ?? {}
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/oclif.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
},
Expand All @@ -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": [
Expand Down
11 changes: 4 additions & 7 deletions packages/cli/src/cli/commands/upgrade.test.ts
Original file line number Diff line number Diff line change
@@ -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()
})
})
3 changes: 1 addition & 2 deletions packages/cli/src/cli/commands/upgrade.ts
Original file line number Diff line number Diff line change
@@ -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.'
Expand All @@ -9,7 +9,6 @@ export default class Upgrade extends Command {
static description = this.descriptionWithoutMarkdown()

async run(): Promise<void> {
await promptAutoUpgrade()
await runCLIUpgrade()
}
}
Loading