From 5ceef25e43d5d6b8c4217684c7d134345be2d092 Mon Sep 17 00:00:00 2001 From: Alfonso Noriega Date: Thu, 9 Apr 2026 22:25:38 +0200 Subject: [PATCH 1/3] Include release notes link in major version upgrade notification When isMajorVersionChange() is true, extend the notification to include a link to the GitHub release notes so users can review breaking changes before upgrading. Closes https://github.com/shop/issues-develop/issues/22372 --- .../src/public/node/hooks/postrun.test.ts | 1 + .../cli-kit/src/public/node/hooks/postrun.ts | 2 +- .../cli-kit/src/public/node/upgrade.test.ts | 34 ++++++++++++++++++- packages/cli-kit/src/public/node/upgrade.ts | 20 ++++++++--- 4 files changed, 51 insertions(+), 6 deletions(-) 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 562430d4f6e..9ba98ee8a25 100644 --- a/packages/cli-kit/src/public/node/hooks/postrun.test.ts +++ b/packages/cli-kit/src/public/node/hooks/postrun.test.ts @@ -90,6 +90,7 @@ describe('autoUpgradeIfNeeded', () => { // Then expect(runCLIUpgrade).not.toHaveBeenCalled() + expect(getOutputUpdateCLIReminder).toHaveBeenCalledWith('4.0.0', true) expect(outputMock.warn()).toMatch(installReminder) }) }) diff --git a/packages/cli-kit/src/public/node/hooks/postrun.ts b/packages/cli-kit/src/public/node/hooks/postrun.ts index 2746cb8f16e..922848a9df5 100644 --- a/packages/cli-kit/src/public/node/hooks/postrun.ts +++ b/packages/cli-kit/src/public/node/hooks/postrun.ts @@ -69,7 +69,7 @@ export async function autoUpgradeIfNeeded(): Promise { async function performAutoUpgrade(newerVersion: string): Promise { if (isMajorVersionChange(CLI_KIT_VERSION, newerVersion)) { - return outputWarn(getOutputUpdateCLIReminder(newerVersion)) + return outputWarn(getOutputUpdateCLIReminder(newerVersion, true)) } try { diff --git a/packages/cli-kit/src/public/node/upgrade.test.ts b/packages/cli-kit/src/public/node/upgrade.test.ts index 99ef1500611..a5d4551f8b0 100644 --- a/packages/cli-kit/src/public/node/upgrade.test.ts +++ b/packages/cli-kit/src/public/node/upgrade.test.ts @@ -2,7 +2,7 @@ import {isDevelopment} from './context/local.js' import {currentProcessIsGlobal, inferPackageManagerForGlobalCLI} from './is-global.js' import {checkForCachedNewVersion, packageManagerFromUserAgent, PackageManager} from './node-package-manager.js' import {exec, isCI} from './system.js' -import {cliInstallCommand, runCLIUpgrade, versionToAutoUpgrade} from './upgrade.js' +import {cliInstallCommand, getOutputUpdateCLIReminder, runCLIUpgrade, versionToAutoUpgrade} from './upgrade.js' import {isPreReleaseVersion} from './version.js' import {getAutoUpgradeEnabled} from '../../private/node/conf-store.js' import {vi, describe, test, expect, beforeEach} from 'vitest' @@ -96,6 +96,38 @@ describe('cliInstallCommand', () => { expect(got).toBeUndefined() }) }) +describe('getOutputUpdateCLIReminder', () => { + test('returns a basic upgrade message for a minor version bump', () => { + vi.mocked(inferPackageManagerForGlobalCLI).mockReturnValue('homebrew') + + const message = getOutputUpdateCLIReminder('3.91.0') + + expect(message).toContain('3.91.0') + expect(message).toContain('brew upgrade shopify-cli') + expect(message).not.toContain('major version') + }) + + test('appends the GitHub release URL for a major version bump', () => { + vi.mocked(inferPackageManagerForGlobalCLI).mockReturnValue('homebrew') + + const message = getOutputUpdateCLIReminder('4.0.0', true) + + expect(message).toContain('4.0.0') + expect(message).toContain('brew upgrade shopify-cli') + expect(message).toContain('major version') + expect(message).toContain('https://github.com/Shopify/cli/releases/tag/v4.0.0') + }) + + test('does not append the release URL for a minor version bump even when isMajor is false', () => { + vi.mocked(inferPackageManagerForGlobalCLI).mockReturnValue('npm') + + const message = getOutputUpdateCLIReminder('3.91.0', false) + + expect(message).not.toContain('major version') + expect(message).not.toContain('releases/tag') + }) +}) + describe('runCLIUpgrade', () => { beforeEach(() => { // Mock isDevelopment to return false by default (not in CLI development mode) diff --git a/packages/cli-kit/src/public/node/upgrade.ts b/packages/cli-kit/src/public/node/upgrade.ts index 79541ecd4c3..a38af73deb1 100644 --- a/packages/cli-kit/src/public/node/upgrade.ts +++ b/packages/cli-kit/src/public/node/upgrade.ts @@ -128,16 +128,28 @@ export async function warnIfUpgradeAvailable(): Promise { /** * Generates a message to remind the user to update the CLI. + * For major version bumps, appends a link to the GitHub release notes so users + * can review breaking changes before deciding to upgrade. * * @param version - The version to update to. + * @param isMajor - Whether the version bump is a major version change. * @returns The message to remind the user to update the CLI. */ -export function getOutputUpdateCLIReminder(version: string): string { +export function getOutputUpdateCLIReminder(version: string, isMajor = false): string { const installCommand = cliInstallCommand() - if (installCommand) { - return outputContent`💡 Version ${version} available! Run ${outputToken.genericShellCommand(installCommand)}`.value + const base = installCommand + ? outputContent`💡 Version ${version} available! Run ${outputToken.genericShellCommand(installCommand)}`.value + : outputContent`💡 Version ${version} available!`.value + + if (isMajor) { + const releaseUrl = `https://github.com/Shopify/cli/releases/tag/v${version}` + const majorNotice = + outputContent`⚠️ This is a major version — review breaking changes before upgrading:\n ${outputToken.link(releaseUrl, releaseUrl)}` + .value + return `${base}\n\n${majorNotice}` } - return outputContent`💡 Version ${version} available!`.value + + return base } /** From 4cc580dc8fc0cff839832dd832b1d88f2064781d Mon Sep 17 00:00:00 2001 From: Alfonso Noriega Date: Fri, 10 Apr 2026 16:54:38 +0200 Subject: [PATCH 2/3] Update changeset url --- packages/cli-kit/src/public/node/upgrade.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli-kit/src/public/node/upgrade.ts b/packages/cli-kit/src/public/node/upgrade.ts index a38af73deb1..cd5031550f8 100644 --- a/packages/cli-kit/src/public/node/upgrade.ts +++ b/packages/cli-kit/src/public/node/upgrade.ts @@ -142,7 +142,7 @@ export function getOutputUpdateCLIReminder(version: string, isMajor = false): st : outputContent`💡 Version ${version} available!`.value if (isMajor) { - const releaseUrl = `https://github.com/Shopify/cli/releases/tag/v${version}` + const releaseUrl = `https://github.com/Shopify/cli/releases/tag/${version}` const majorNotice = outputContent`⚠️ This is a major version — review breaking changes before upgrading:\n ${outputToken.link(releaseUrl, releaseUrl)}` .value From 765a71557d714c7d76bc8d3a7230172ce137e455 Mon Sep 17 00:00:00 2001 From: Alfonso Noriega Date: Fri, 10 Apr 2026 18:21:30 +0200 Subject: [PATCH 3/3] fix: remove v prefix from release URL assertion in test --- packages/cli-kit/src/public/node/upgrade.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli-kit/src/public/node/upgrade.test.ts b/packages/cli-kit/src/public/node/upgrade.test.ts index a5d4551f8b0..af82d4853de 100644 --- a/packages/cli-kit/src/public/node/upgrade.test.ts +++ b/packages/cli-kit/src/public/node/upgrade.test.ts @@ -115,7 +115,7 @@ describe('getOutputUpdateCLIReminder', () => { expect(message).toContain('4.0.0') expect(message).toContain('brew upgrade shopify-cli') expect(message).toContain('major version') - expect(message).toContain('https://github.com/Shopify/cli/releases/tag/v4.0.0') + expect(message).toContain('https://github.com/Shopify/cli/releases/tag/4.0.0') }) test('does not append the release URL for a minor version bump even when isMajor is false', () => {