diff --git a/lib/workers/repository/process/lookup/filter.spec.ts b/lib/workers/repository/process/lookup/filter.spec.ts index 0d75534e35ec27..5fe0a6a9acd97b 100644 --- a/lib/workers/repository/process/lookup/filter.spec.ts +++ b/lib/workers/repository/process/lookup/filter.spec.ts @@ -1,37 +1,38 @@ import { partial } from '../../../../../test/util'; +import type { Release } from '../../../../modules/datasource/types'; import * as allVersioning from '../../../../modules/versioning'; import { filterVersions } from './filter'; import type { FilterConfig } from './types'; const versioning = allVersioning.get('semver'); -const releases = [ - { - version: '1.0.1', - releaseTimestamp: '2021-01-01T00:00:01.000Z', - }, - { - version: '1.2.0', - releaseTimestamp: '2021-01-03T00:00:00.000Z', - }, - { - version: '2.0.0', - releaseTimestamp: '2021-01-05T00:00:00.000Z', - }, - { - version: '2.1.0', - releaseTimestamp: '2021-01-07T00:00:00.000Z', - }, - // for coverage - { - version: 'invalid.version', - releaseTimestamp: '2021-01-07T00:00:00.000Z', - }, -]; - describe('workers/repository/process/lookup/filter', () => { describe('.filterVersions()', () => { it('should filter versions allowed by semver syntax when allowedVersions is not valid version, range or pypi syntax', () => { + const releases = [ + { + version: '1.0.1', + releaseTimestamp: '2021-01-01T00:00:01.000Z', + }, + { + version: '1.2.0', + releaseTimestamp: '2021-01-03T00:00:00.000Z', + }, + { + version: '2.0.0', + releaseTimestamp: '2021-01-05T00:00:00.000Z', + }, + { + version: '2.1.0', + releaseTimestamp: '2021-01-07T00:00:00.000Z', + }, + // for coverage + { + version: 'invalid.version', + releaseTimestamp: '2021-01-07T00:00:00.000Z', + }, + ] satisfies Release[]; + const config = partial({ ignoreUnstable: false, ignoreDeprecated: false, @@ -41,9 +42,6 @@ describe('workers/repository/process/lookup/filter', () => { const currentVersion = '1.0.0'; const latestVersion = '2.0.0'; - jest.spyOn(versioning, 'isVersion').mockReturnValue(true); - jest.spyOn(versioning, 'isGreaterThan').mockReturnValue(true); - const filteredVersions = filterVersions( config, currentVersion, @@ -57,5 +55,31 @@ describe('workers/repository/process/lookup/filter', () => { { version: '2.1.0', releaseTimestamp: '2021-01-07T00:00:00.000Z' }, ]); }); + + it('allows unstable major upgrades', () => { + const nodeVersioning = allVersioning.get('node'); + + const releases = [ + { version: '1.0.0-alpha' }, + { version: '1.2.3-beta' }, + ] satisfies Release[]; + + const config = partial({ + ignoreUnstable: true, + ignoreDeprecated: true, + }); + const currentVersion = '1.0.0-alpha'; + const latestVersion = '1.2.3-beta'; + + const filteredVersions = filterVersions( + config, + currentVersion, + latestVersion, + releases, + nodeVersioning, + ); + + expect(filteredVersions).toEqual([{ version: '1.2.3-beta' }]); + }); }); }); diff --git a/lib/workers/repository/process/lookup/filter.ts b/lib/workers/repository/process/lookup/filter.ts index dbaed9dcd0fc62..71e85ec3d1c57d 100644 --- a/lib/workers/repository/process/lookup/filter.ts +++ b/lib/workers/repository/process/lookup/filter.ts @@ -78,7 +78,11 @@ export function filterVersions( ); filteredReleases = filteredReleases.filter((r) => semver.satisfies( - semver.valid(r.version) ? r.version : semver.coerce(r.version)!, + semver.valid(r.version) + ? r.version + : /* istanbul ignore next: not reachable, but it's safer to preserve it */ semver.coerce( + r.version, + )!, allowedVersions, ), ); @@ -126,24 +130,28 @@ export function filterVersions( return filteredReleases.filter((r) => isReleaseStable(r, versioning)); } - // if current is unstable then allow unstable in the current major only - // Allow unstable only in current major + const currentMajor = versioning.getMajor(currentVersion); + const currentMinor = versioning.getMinor(currentVersion); + const currentPatch = versioning.getPatch(currentVersion); + return filteredReleases.filter((r) => { if (isReleaseStable(r, versioning)) { return true; } - if ( - versioning.getMajor(r.version) !== versioning.getMajor(currentVersion) - ) { + + const major = versioning.getMajor(r.version); + + if (major !== currentMajor) { return false; } - // istanbul ignore if: test passes without touching this + if (versioning.allowUnstableMajorUpgrades) { return true; } - return ( - versioning.getMinor(r.version) === versioning.getMinor(currentVersion) && - versioning.getPatch(r.version) === versioning.getPatch(currentVersion) - ); + + const minor = versioning.getMinor(r.version); + const patch = versioning.getPatch(r.version); + + return minor === currentMinor && patch === currentPatch; }); }