diff --git a/shell/mixins/__tests__/chart.test.ts b/shell/mixins/__tests__/chart.test.ts index 009ec7d02e7..260d60158a2 100644 --- a/shell/mixins/__tests__/chart.test.ts +++ b/shell/mixins/__tests__/chart.test.ts @@ -238,5 +238,26 @@ describe('chartMixin', () => { icon: 'icon-downgrade-alt', }); }); + + it('should return "upgrade" action when upgrading from a pre-release to a stable version', () => { + const wrapper = mount(DummyComponent, { + data: () => ({ + existing: { spec: { chart: { metadata: { version: '1.0.0-rc1' } } } }, + version: { version: '1.0.0' } + }), + global: { + mocks: { + $store: mockStore, + $route: { query: {} } + } + } + }); + + expect(wrapper.vm.action).toStrictEqual({ + name: 'upgrade', + tKey: 'upgrade', + icon: 'icon-upgrade-alt', + }); + }); }); }); diff --git a/shell/mixins/chart.js b/shell/mixins/chart.js index fa907428e9c..9c294d86b02 100644 --- a/shell/mixins/chart.js +++ b/shell/mixins/chart.js @@ -10,7 +10,7 @@ import { NAME as MANAGER } from '@shell/config/product/manager'; import { OPA_GATE_KEEPER_ID } from '@shell/pages/c/_cluster/gatekeeper/index.vue'; import { formatSi, parseSi } from '@shell/utils/units'; import { CAPI, CATALOG } from '@shell/config/types'; -import { isPrerelease, compare } from '@shell/utils/version'; +import { isPrerelease, compare, isUpgradeFromPreToStable } from '@shell/utils/version'; import difference from 'lodash/difference'; import { LINUX, APP_UPGRADE_STATUS } from '@shell/store/catalog'; import { clone } from '@shell/utils/object'; @@ -240,6 +240,12 @@ export default { }; } + if (isUpgradeFromPreToStable(this.currentVersion, this.targetVersion)) { + return { + name: 'upgrade', tKey: 'upgrade', icon: 'icon-upgrade-alt' + }; + } + if (compare(this.currentVersion, this.targetVersion) < 0) { return { name: 'upgrade', tKey: 'upgrade', icon: 'icon-upgrade-alt' diff --git a/shell/utils/__tests__/version.test.ts b/shell/utils/__tests__/version.test.ts index 47bd5005160..f0ebd263518 100644 --- a/shell/utils/__tests__/version.test.ts +++ b/shell/utils/__tests__/version.test.ts @@ -1,4 +1,4 @@ -import { isDevBuild } from '@shell/utils/version'; +import { isDevBuild, isUpgradeFromPreToStable } from '@shell/utils/version'; describe('fx: isDevBuild', () => { it.each([ @@ -16,3 +16,21 @@ describe('fx: isDevBuild', () => { } ); }); + +describe('fx: isUpgradeFromPreToStable', () => { + it('should be true when going from pre-release to stable of same version', () => { + expect(isUpgradeFromPreToStable('1.0.0-rc1', '1.0.0')).toBe(true); + }); + + it('should be false when going from stable to pre-release', () => { + expect(isUpgradeFromPreToStable('1.0.0', '1.0.0-rc1')).toBe(false ); + }); + + it('should be false for stable to stable', () => { + expect(isUpgradeFromPreToStable('1.0.0', '1.1.0')).toBe(false); + }); + + it('should be false for pre-release to pre-release', () => { + expect(isUpgradeFromPreToStable('1.0.0-rc1', '1.0.0-rc2')).toBe(false); + }); +}); diff --git a/shell/utils/version.js b/shell/utils/version.js index fa4be45395b..c824c336c58 100644 --- a/shell/utils/version.js +++ b/shell/utils/version.js @@ -74,6 +74,21 @@ export function isPrerelease(version = '') { return !!semver.prerelease(version); } +export function isUpgradeFromPreToStable(currentVersion, targetVersion) { + if (!isPrerelease(currentVersion) || isPrerelease(targetVersion)) { + return false; + } + + const cVersion = semver.clean(currentVersion, { loose: true }); + const tVersion = semver.clean(targetVersion, { loose: true }); + + if (cVersion && tVersion && semver.valid(cVersion) && semver.valid(tVersion)) { + return semver.lt(cVersion, tVersion); + } + + return false; +} + export function isDevBuild(version) { if ( ['dev', 'master', 'head'].includes(version) || version.endsWith('-head') || version.match(/-rc\d+$/) || version.match(/-alpha\d+$/) ) { return true;