diff --git a/__tests__/distributors/liberica-installer.test.ts b/__tests__/distributors/liberica-installer.test.ts index 2ce57c2c4..2005f5343 100644 --- a/__tests__/distributors/liberica-installer.test.ts +++ b/__tests__/distributors/liberica-installer.test.ts @@ -15,7 +15,6 @@ import type { } from '../../src/distributions/liberica/models.js'; import {HttpClient} from '@actions/http-client'; import os from 'os'; -import path from 'path'; import manifestData from '../data/liberica.json' with {type: 'json'}; @@ -254,68 +253,35 @@ describe('findPackageForDownload', () => { expect(result.version).toBe(expected); }); - describe.each([ - [17, 20], - [25, 4] - ])('patch releases for Java %s.0.%s', (featureVersion, updateVersion) => { - const mainVersion = `${featureVersion}.0.${updateVersion}`; - + describe('compound build versions', () => { beforeEach(() => { distribution['getAvailableVersions'] = async () => - ['+1', '+10', '.1+1', '.1+2', '.1+10', '.2+1', '.10+1'].map(suffix => ({ - featureVersion, + ['1', '1.1', '1.2', '1.10'].map(build => ({ + featureVersion: 25, interimVersion: 0, - updateVersion, - buildVersion: Number(suffix.split('+')[1]), - version: `${mainVersion}${suffix}`, - downloadUrl: `https://download.bell-sw.com/java/${mainVersion}${suffix}/bellsoft-jdk${mainVersion}${suffix}-macos-aarch64.tar.gz` + updateVersion: 4, + buildVersion: 1, + version: `25.0.4+${build}`, + downloadUrl: `https://download.bell-sw.com/java/25.0.4+${build}/bellsoft-jdk25.0.4+${build}-macos-aarch64.tar.gz` })); }); it.each([ - [`${mainVersion}+1.1`, `${mainVersion}+1.1`, '.1+1'], - [`${mainVersion}+1.2`, `${mainVersion}+1.2`, '.1+2'], - [`${mainVersion}+1.10`, `${mainVersion}+1.10`, '.1+10'], - [`${mainVersion}+1`, `${mainVersion}+1`, '+1'], - [mainVersion, `${mainVersion}+10.1`, '.10+1'], - [`${featureVersion}`, `${mainVersion}+10.1`, '.10+1'] - ])('version is %s -> %s', async (input, expected, suffix) => { + ['25.0.4+1.1', '25.0.4+1.1'], + ['25.0.4+1', '25.0.4+1'], + ['25.0.4', '25.0.4+1.10'], + ['25', '25.0.4+1.10'] + ])('version is %s -> %s', async (input, expected) => { const result = await distribution['findPackageForDownload'](input); expect(result).toEqual({ version: expected, - url: `https://download.bell-sw.com/java/${mainVersion}${suffix}/bellsoft-jdk${mainVersion}${suffix}-macos-aarch64.tar.gz` + url: `https://download.bell-sw.com/java/${expected}/bellsoft-jdk${expected}-macos-aarch64.tar.gz` }); }); - it('sorts builds within the same patch numerically', async () => { - const versions = await distribution['getAvailableVersions'](); - distribution['getAvailableVersions'] = async () => - versions.filter(item => item.version.startsWith(`${mainVersion}.1+`)); - - const result = await distribution['findPackageForDownload'](mainVersion); - expect(result.version).toBe(`${mainVersion}+1.10`); - }); - - it('selects the newest build for a four-component patch-only request', async () => { - const patchDistribution = new LibericaDistributions({ - version: `${mainVersion}.1`, - architecture: 'x64', - packageType: 'jdk', - checkLatest: false - }); - patchDistribution['getAvailableVersions'] = - distribution['getAvailableVersions']; - - await expect( - patchDistribution['findPackageForDownload']( - patchDistribution['version'] - ) - ).resolves.toMatchObject({version: `${mainVersion}+1.10`}); - }); - it('does not substitute a different compound build', async () => { await expect( - distribution['findPackageForDownload'](`${mainVersion}+1.3`) + distribution['findPackageForDownload']('25.0.4+1.3') ).rejects.toThrow(/No matching version found for SemVer/); }); }); @@ -327,160 +293,6 @@ describe('findPackageForDownload', () => { }); }); -describe('patch request resolution from the constructor', () => { - const releases: LibericaVersion[] = ['17.0.20+10', '17.0.20.1+1'].map( - version => ({ - featureVersion: 17, - interimVersion: 0, - updateVersion: 20, - buildVersion: Number(version.split('+')[1]), - version, - downloadUrl: `https://download.bell-sw.com/java/${version}/jdk.tar.gz` - }) - ); - let cacheRoot: string; - let previousToolcache: string | undefined; - - beforeEach(async () => { - previousToolcache = process.env['RUNNER_TOOL_CACHE']; - cacheRoot = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'liberica-')); - process.env['RUNNER_TOOL_CACHE'] = cacheRoot; - for (const version of ['17.0.20-10', '17.0.20-1.1']) { - const javaPath = path.join( - cacheRoot, - 'Java_Liberica_jdk', - version, - 'x64' - ); - await fs.promises.mkdir(javaPath, {recursive: true}); - await fs.promises.writeFile(`${javaPath}.complete`, ''); - } - }); - - afterEach(async () => { - if (previousToolcache === undefined) { - delete process.env['RUNNER_TOOL_CACHE']; - } else { - process.env['RUNNER_TOOL_CACHE'] = previousToolcache; - } - await fs.promises.rm(cacheRoot, {recursive: true, force: true}); - }); - - it.each([ - ['17', '17.0.20+1.1', '17.0.20.1+1'], - ['17.0.20', '17.0.20+1.1', '17.0.20.1+1'], - ['17.0.20+10', '17.0.20+10', '17.0.20+10'], - ['17.0.20+1.1', '17.0.20+1.1', '17.0.20.1+1'], - ['17.0.20.1', '17.0.20+1.1', '17.0.20.1+1'], - ['17.0.20.1+1', '17.0.20+1.1', '17.0.20.1+1'], - ['17.0.20.0', '17.0.20+10', '17.0.20+10'] - ])( - 'resolves %s consistently remotely and in cache', - async (input, expected, apiVersion) => { - const distribution = new LibericaDistributions({ - version: input, - architecture: 'x64', - packageType: 'jdk', - checkLatest: false - }); - distribution['getAvailableVersions'] = async () => releases; - - await expect( - distribution['findPackageForDownload'](distribution['version']) - ).resolves.toEqual({ - version: expected, - url: `https://download.bell-sw.com/java/${apiVersion}/jdk.tar.gz` - }); - expect(distribution['findInToolcache']()).toEqual({ - version: expected, - path: path.join( - cacheRoot, - 'Java_Liberica_jdk', - expected.replace('+', '-'), - 'x64' - ) - }); - } - ); - - it.each(['17.0.20.2', '17.0.20+1.2'])( - 'does not substitute a different patch or exact build for %s', - async version => { - const distribution = new LibericaDistributions({ - version, - architecture: 'x64', - packageType: 'jdk', - checkLatest: false - }); - distribution['getAvailableVersions'] = async () => releases; - - await expect( - distribution['findPackageForDownload'](distribution['version']) - ).rejects.toThrow(/No matching version found/); - expect(distribution['findInToolcache']()).toBeNull(); - } - ); - - it('keeps patch-only and exact-build resolution cache identities distinct', () => { - const distribution = new LibericaDistributions({ - version: '17.0.20.1', - architecture: 'x64', - packageType: 'jdk', - checkLatest: false - }); - expect(distribution['version']).toBe('17.0.20.1'); - }); - - it('orders main versions, patches, and builds consistently in cache', async () => { - for (const version of ['17.0.20-1.2', '17.0.20-1.10', '17.0.21-1']) { - const javaPath = path.join( - cacheRoot, - 'Java_Liberica_jdk', - version, - 'x64' - ); - await fs.promises.mkdir(javaPath, {recursive: true}); - await fs.promises.writeFile(`${javaPath}.complete`, ''); - } - - for (const [version, expected] of [ - ['17', '17.0.21+1'], - ['17.0.20', '17.0.20+1.10'], - ['17.0.20.1', '17.0.20+1.10'] - ]) { - const distribution = new LibericaDistributions({ - version, - architecture: 'x64', - packageType: 'jdk', - checkLatest: false - }); - expect(distribution['findInToolcache']()?.version).toBe(expected); - } - }); - - it('preserves early-access handling for patch-only requests', async () => { - const javaPath = path.join( - cacheRoot, - 'Java_Liberica_jdk', - '17.0.20-ea.1.2', - 'x64' - ); - await fs.promises.mkdir(javaPath, {recursive: true}); - await fs.promises.writeFile(`${javaPath}.complete`, ''); - const distribution = new LibericaDistributions({ - version: '17.0.20.1-ea', - architecture: 'x64', - packageType: 'jdk', - checkLatest: false - }); - expect(distribution['stable']).toBe(false); - expect(distribution['findInToolcache']()).toEqual({ - version: '17.0.20+1.2', - path: javaPath - }); - }); -}); - describe('getPlatformOption', () => { beforeEach(() => { // The linux row below is glibc, so pin the Alpine probe rather than @@ -557,36 +369,6 @@ describe('convertVersionToSemver', () => { }, '11.0.0+13' ], - [ - { - version: '17.0.20.1+1', - featureVersion: 17, - interimVersion: 0, - updateVersion: 20, - buildVersion: 1 - }, - '17.0.20+1.1' - ], - [ - { - version: '25.0.4.1+1', - featureVersion: 25, - interimVersion: 0, - updateVersion: 4, - buildVersion: 1 - }, - '25.0.4+1.1' - ], - [ - { - version: '17.0.20.1+2', - featureVersion: 17, - interimVersion: 0, - updateVersion: 20, - buildVersion: 2 - }, - '17.0.20+1.2' - ], [ { version: '25.0.4+1.1', diff --git a/dist/setup/242.index.js b/dist/setup/242.index.js index ccbf91db4..1b0369a65 100644 --- a/dist/setup/242.index.js +++ b/dist/setup/242.index.js @@ -378,7 +378,7 @@ class JavaBase { core/* info */.pq(`Java ${foundJava.version} was downloaded`); if (javaRelease.floating) { if (!semver_default().valid(foundJava.version) || - !this.isVersionSatisfied(this.version, foundJava.version)) { + !(0,util/* isVersionSatisfies */.y)(this.version, foundJava.version)) { throw new Error(`The downloaded ${this.distribution} artifact reported Java ${foundJava.version}, which does not satisfy '${this.version}'.`); } javaRelease = { ...javaRelease, version: foundJava.version }; @@ -501,7 +501,7 @@ class JavaBase { return javaRelease; } if (!semver_default().valid(restored.release.version) || - !this.isVersionSatisfied(this.version, restored.release.version)) { + !(0,util/* isVersionSatisfies */.y)(this.version, restored.release.version)) { core/* debug */.Yz(`Ignoring the cached concrete version '${restored.release.version}' for ${this.distribution} ${this.version}.`); return javaRelease; } @@ -684,10 +684,10 @@ class JavaBase { }) .filter(item => item.stable === this.stable); const satisfiedVersions = availableVersions - .filter(item => this.isVersionSatisfied(this.version, item.version)) + .filter(item => (0,util/* isVersionSatisfies */.y)(this.version, item.version)) .filter(item => item.path) .sort((a, b) => { - return -this.compareVersions(a.version, b.version); + return -semver_default().compareBuild(a.version, b.version); }); if (!satisfiedVersions || satisfiedVersions.length === 0) { return null; @@ -697,12 +697,6 @@ class JavaBase { path: satisfiedVersions[0].path }; } - isVersionSatisfied(range, version) { - return (0,util/* isVersionSatisfies */.y)(range, version); - } - compareVersions(a, b) { - return semver_default().compareBuild(a, b); - } normalizeVersion(version) { let stable = true; const latest = false; diff --git a/dist/setup/63.index.js b/dist/setup/63.index.js index 44eb30a17..3b8ac9758 100644 --- a/dist/setup/63.index.js +++ b/dist/setup/63.index.js @@ -52,46 +52,14 @@ class LibericaDistributions extends _base_installer_js__WEBPACK_IMPORTED_MODULE_ version: this.convertVersionToSemver(item) })); const satisfiedVersion = availableVersions - .filter(item => this.isVersionSatisfied(range, item.version)) - .sort((a, b) => -this.compareVersions(a.version, b.version))[0]; + .filter(item => (0,_util_js__WEBPACK_IMPORTED_MODULE_2__/* .isVersionSatisfies */ .y)(range, item.version)) + .sort((a, b) => -semver__WEBPACK_IMPORTED_MODULE_1___default().compareBuild(a.version, b.version))[0]; if (!satisfiedVersion) { const availableVersionStrings = availableVersions.map(item => item.version); throw this.createVersionNotFoundError(range, availableVersionStrings); } return satisfiedVersion; } - normalizeVersion(version) { - const normalized = super.normalizeVersion(version); - if (/^\d+\.\d+\.\d+\.\d+(?:-ea)?$/.test(version)) { - // Keep patch-only requests distinct from exact SDKMAN build requests. - normalized.version = version.replace(/-ea$/, ''); - } - return normalized; - } - isVersionSatisfied(range, version) { - const patchRequest = range.match(/^(\d+\.\d+\.\d+)\.(\d+)$/); - if (patchRequest) { - const candidate = semver__WEBPACK_IMPORTED_MODULE_1___default().parse(version); - if (!candidate || !semver__WEBPACK_IMPORTED_MODULE_1___default().eq(patchRequest[1], candidate)) { - return false; - } - const patch = candidate.build.length > 1 ? candidate.build[0] : '0'; - return patch === patchRequest[2]; - } - return super.isVersionSatisfied(range, version); - } - compareVersions(a, b) { - const mainComparison = semver__WEBPACK_IMPORTED_MODULE_1___default().compare(a, b); - if (mainComparison !== 0) { - return mainComparison; - } - // SDKMAN encodes patch.build, but unpatched releases contain only build. - const patchAndBuild = (version) => { - const build = new (semver__WEBPACK_IMPORTED_MODULE_1___default().SemVer)(version).build; - return (build.length > 1 ? build : ['0', ...build]).join('.'); - }; - return semver__WEBPACK_IMPORTED_MODULE_1___default().compareBuild(`0.0.0+${patchAndBuild(a)}`, `0.0.0+${patchAndBuild(b)}`); - } async getAvailableVersions() { if (_actions_core__WEBPACK_IMPORTED_MODULE_3__/* .isDebug */ ._o()) { console.time('Retrieving available versions for Liberica took'); // eslint-disable-line no-console @@ -163,10 +131,6 @@ class LibericaDistributions extends _base_installer_js__WEBPACK_IMPORTED_MODULE_ const { featureVersion, interimVersion, updateVersion } = version; const buildVersion = version.version.split('+')[1] || version.buildVersion; const mainVersion = [featureVersion, interimVersion, updateVersion].join('.'); - const patchVersion = version.version.split('+')[0].split('.')[3]; - if (patchVersion) { - return `${mainVersion}+${patchVersion}.${buildVersion}`; - } if (buildVersion != 0) { return `${mainVersion}+${buildVersion}`; } diff --git a/docs/advanced-usage.md b/docs/advanced-usage.md index 8e1a61507..dedca4ed4 100644 --- a/docs/advanced-usage.md +++ b/docs/advanced-usage.md @@ -83,12 +83,6 @@ steps: ### Liberica -Exact patch releases use SDKMAN's `X.Y.Z+P.B` notation, including in `.sdkmanrc`. -For example, `java=17.0.20+1.1-librca` selects BellSoft's `17.0.20.1+1` release. -Alternatively, `java-version: '17.0.20.1'` selects the newest build of patch 1, -whereas `java-version: '17.0.20+1'` selects the exact unpatched build 1. -Floating versions such as `17` prefer newer patches before comparing build numbers. - ```yaml steps: - uses: actions/checkout@v7 diff --git a/src/distributions/base-installer.ts b/src/distributions/base-installer.ts index 42f4b7de9..32c7455c1 100644 --- a/src/distributions/base-installer.ts +++ b/src/distributions/base-installer.ts @@ -241,7 +241,7 @@ export abstract class JavaBase { if (javaRelease.floating) { if ( !semver.valid(foundJava.version) || - !this.isVersionSatisfied(this.version, foundJava.version) + !isVersionSatisfies(this.version, foundJava.version) ) { throw new Error( `The downloaded ${this.distribution} artifact reported Java ${foundJava.version}, which does not satisfy '${this.version}'.` @@ -401,7 +401,7 @@ export abstract class JavaBase { } if ( !semver.valid(restored.release.version) || - !this.isVersionSatisfied(this.version, restored.release.version) + !isVersionSatisfies(this.version, restored.release.version) ) { core.debug( `Ignoring the cached concrete version '${restored.release.version}' for ${this.distribution} ${this.version}.` @@ -622,10 +622,10 @@ export abstract class JavaBase { .filter(item => item.stable === this.stable); const satisfiedVersions = availableVersions - .filter(item => this.isVersionSatisfied(this.version, item.version)) + .filter(item => isVersionSatisfies(this.version, item.version)) .filter(item => item.path) .sort((a, b) => { - return -this.compareVersions(a.version, b.version); + return -semver.compareBuild(a.version, b.version); }); if (!satisfiedVersions || satisfiedVersions.length === 0) { return null; @@ -637,14 +637,6 @@ export abstract class JavaBase { }; } - protected isVersionSatisfied(range: string, version: string): boolean { - return isVersionSatisfies(range, version); - } - - protected compareVersions(a: string, b: string): number { - return semver.compareBuild(a, b); - } - protected normalizeVersion(version: string) { let stable = true; const latest = false; diff --git a/src/distributions/liberica/installer.ts b/src/distributions/liberica/installer.ts index 41737cea3..b4320d66a 100644 --- a/src/distributions/liberica/installer.ts +++ b/src/distributions/liberica/installer.ts @@ -9,6 +9,7 @@ import { cacheJdkDir, extractJdkFile, getDownloadArchiveExtension, + isVersionSatisfies, renameWinArchive } from '../../util.js'; import * as core from '@actions/core'; @@ -65,8 +66,8 @@ export class LibericaDistributions extends JavaBase { })); const satisfiedVersion = availableVersions - .filter(item => this.isVersionSatisfied(range, item.version)) - .sort((a, b) => -this.compareVersions(a.version, b.version))[0]; + .filter(item => isVersionSatisfies(range, item.version)) + .sort((a, b) => -semver.compareBuild(a.version, b.version))[0]; if (!satisfiedVersion) { const availableVersionStrings = availableVersions.map( @@ -78,45 +79,6 @@ export class LibericaDistributions extends JavaBase { return satisfiedVersion; } - protected normalizeVersion(version: string) { - const normalized = super.normalizeVersion(version); - if (/^\d+\.\d+\.\d+\.\d+(?:-ea)?$/.test(version)) { - // Keep patch-only requests distinct from exact SDKMAN build requests. - normalized.version = version.replace(/-ea$/, ''); - } - return normalized; - } - - protected isVersionSatisfied(range: string, version: string): boolean { - const patchRequest = range.match(/^(\d+\.\d+\.\d+)\.(\d+)$/); - if (patchRequest) { - const candidate = semver.parse(version); - if (!candidate || !semver.eq(patchRequest[1], candidate)) { - return false; - } - const patch = candidate.build.length > 1 ? candidate.build[0] : '0'; - return patch === patchRequest[2]; - } - return super.isVersionSatisfied(range, version); - } - - protected compareVersions(a: string, b: string): number { - const mainComparison = semver.compare(a, b); - if (mainComparison !== 0) { - return mainComparison; - } - - // SDKMAN encodes patch.build, but unpatched releases contain only build. - const patchAndBuild = (version: string): string => { - const build = new semver.SemVer(version).build; - return (build.length > 1 ? build : ['0', ...build]).join('.'); - }; - return semver.compareBuild( - `0.0.0+${patchAndBuild(a)}`, - `0.0.0+${patchAndBuild(b)}` - ); - } - private async getAvailableVersions(): Promise { if (core.isDebug()) { console.time('Retrieving available versions for Liberica took'); // eslint-disable-line no-console @@ -209,10 +171,6 @@ export class LibericaDistributions extends JavaBase { const mainVersion = [featureVersion, interimVersion, updateVersion].join( '.' ); - const patchVersion = version.version.split('+')[0].split('.')[3]; - if (patchVersion) { - return `${mainVersion}+${patchVersion}.${buildVersion}`; - } if (buildVersion != 0) { return `${mainVersion}+${buildVersion}`; }