diff --git a/lib/modules/versioning/generic.spec.ts b/lib/modules/versioning/generic.spec.ts index 5aafc0f5c502095d751749750e38d28ec2575261..5fbcc0717cc42446ad40b23cdeb48d64056df026 100644 --- a/lib/modules/versioning/generic.spec.ts +++ b/lib/modules/versioning/generic.spec.ts @@ -68,6 +68,7 @@ describe('modules/versioning/generic', () => { 'getPatch', 'isCompatible', 'isGreaterThan', + 'isSame', 'isSingleVersion', 'isStable', 'isValid', @@ -183,5 +184,14 @@ describe('modules/versioning/generic', () => { api.getSatisfyingVersion(['1.1.1', '2.2.2', '3.3.3'], '1.2.3'), ).toBeNull(); }); + + it('isSame', () => { + expect(api.isSame('major', '4.5.6', '4.6.0')).toBe(true); + expect(api.isSame('major', '4.5.6', '5.0.0')).toBe(false); + expect(api.isSame('minor', '4.5.6', '5.5.0')).toBe(true); + expect(api.isSame('minor', '4.5.6', '4.6.0')).toBe(false); + expect(api.isSame('patch', '4.5.6', '5.5.6')).toBe(true); + expect(api.isSame('patch', '4.5.6', '4.6.0')).toBe(false); + }); }); }); diff --git a/lib/modules/versioning/generic.ts b/lib/modules/versioning/generic.ts index 35710926d33a5230630656287b682ae37bc7839e..724d12d84fafa553ecec6e29d034ae113514134e 100644 --- a/lib/modules/versioning/generic.ts +++ b/lib/modules/versioning/generic.ts @@ -149,4 +149,14 @@ export abstract class GenericVersioningApi< matches(version: string, range: string): boolean { return this.equals(version, range); } + + isSame(type: 'major' | 'minor' | 'patch', a: string, b: string): boolean { + if (type === 'major') { + return this.getMajor(a)! === this.getMajor(b)!; + } + if (type === 'minor') { + return this.getMinor(a)! === this.getMinor(b)!; + } + return this.getPatch(a)! === this.getPatch(b)!; + } } diff --git a/lib/modules/versioning/index.spec.ts b/lib/modules/versioning/index.spec.ts index ca4369fca7d0df9225b6d8b287d7b2ffd206a6c6..3de40de933336d14d7603f77aa6f120fd3667bf4 100644 --- a/lib/modules/versioning/index.spec.ts +++ b/lib/modules/versioning/index.spec.ts @@ -86,6 +86,7 @@ describe('modules/versioning/index', () => { 'toString', 'valueOf', 'subset', + 'isSame', ]; const npmApi = Object.keys(allVersioning.get(semverVersioning.id)) .filter((val) => !optionalFunctions.includes(val)) diff --git a/lib/modules/versioning/types.ts b/lib/modules/versioning/types.ts index e9e686470eac9e8cc4c489c66f8cbdd137899237..f1e66ac15b7b30b64bb601cb502e3d439787b0d4 100644 --- a/lib/modules/versioning/types.ts +++ b/lib/modules/versioning/types.ts @@ -129,6 +129,12 @@ export interface VersioningApi { * Return whether unstable-to-unstable upgrades within the same major version are allowed. */ allowUnstableMajorUpgrades?: boolean; + + /** + * Check whether the `type` in the `a` and `b` version numbers match. + * Both `a` and `b` must pass `isVersion`. + */ + isSame?(type: 'major' | 'minor' | 'patch', a: string, b: string): boolean; } export interface VersioningApiConstructor { diff --git a/lib/workers/repository/process/lookup/update-type.ts b/lib/workers/repository/process/lookup/update-type.ts index e919cfd2cbdbaf930cd0707ec94d3b1626933e52..6698e8f1e9eb7e0f99a0507f40f0e3402b8df597 100644 --- a/lib/workers/repository/process/lookup/update-type.ts +++ b/lib/workers/repository/process/lookup/update-type.ts @@ -14,6 +14,12 @@ export function getUpdateType( currentVersion: string, newVersion: string, ): UpdateType { + if ( + versioningApi.isSame && + !versioningApi.isSame('major', newVersion, currentVersion) + ) { + return 'major'; + } if ( versioningApi.getMajor(newVersion)! > versioningApi.getMajor(currentVersion)!