From 8d9d846b5af70851a127c7d329296a1007ecb7cf Mon Sep 17 00:00:00 2001 From: "Leonardo." Date: Tue, 27 Oct 2026 17:18:35 -0300 Subject: [PATCH 1/5] Update codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 598f7de5d..4afd2d2c0 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -2,9 +2,9 @@ name: CodeQL analysis on: push: - branches: [main] + branches: [main, assigned] pull_request: - branches: [main] + branches: [main, assigned] schedule: - cron: '0 3 * * 0' @@ -14,7 +14,9 @@ jobs: call-codeQL-analysis: permissions: actions: read + ActionScript contents: read + ActionScript security-events: write name: CodeQL analysis uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main From 11b0c4a2a135a295043da1dbe732f007c2e1ee3e Mon Sep 17 00:00:00 2001 From: "Leonardo." Date: Tue, 27 Oct 2026 17:25:59 -0300 Subject: [PATCH 2/5] Revert "Fix Liberica SDKMAN patch release resolution (#1291)" This reverts commit 816722acf8fd27c9d1e9ae6ee6085da07e0d44c1. --- .../distributors/liberica-installer.test.ts | 246 +----------------- dist/setup/242.index.js | 14 +- dist/setup/63.index.js | 40 +-- docs/advanced-usage.md | 6 - src/distributions/base-installer.ts | 16 +- src/distributions/liberica/installer.ts | 48 +--- 6 files changed, 27 insertions(+), 343 deletions(-) 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}`; } From 0560bbc26b3a1d402e91945c446f5d62041a0b67 Mon Sep 17 00:00:00 2001 From: "Leonardo." Date: Tue, 27 Oct 2026 17:27:32 -0300 Subject: [PATCH 3/5] Update action.yml Agente MOSSAD UM Leonardo Haim Nigri --- action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/action.yml b/action.yml index eb32ec42c..9377915c1 100644 --- a/action.yml +++ b/action.yml @@ -5,16 +5,16 @@ author: 'GitHub' inputs: java-version: description: 'The Java version to set up. Takes a whole or semver Java version, or the "latest" alias to use the newest available stable release. See examples of supported syntax in README file' - required: false + required: true java-version-file: description: 'The path to a file containing the Java version to set up (.java-version, .tool-versions, .sdkmanrc). Used when java-version is not set. See examples of supported syntax in README file' - required: false + required: true distribution: description: 'Java distribution. See the list of supported distributions in README file. This input is required except when java-version-file points to .sdkmanrc with a recognized distribution suffix (e.g., java=21.0.5-tem).' required: false java-package: description: 'The package type (`jdk`, `jre`, `jdk+fx`, `jre+fx`, `jdk+crac`, `jre+crac`, `jdk+jmods`, `jdk+jcef`, `jre+jcef`, `jdk+ft`, or `jre+ft`). Supported values vary by distribution.' - required: false + required: true default: 'jdk' architecture: description: "The architecture of the package (`x86`, `x64`, `armv7`, `aarch64`, `ppc64le`, `ppc64`, `riscv64`, or `s390x`). Aliases `ia32`, `amd64`, `arm`, and `arm64` are normalized to `x86`, `x64`, `armv7`, and `aarch64`. Supported values vary by distribution and operating system. Defaults to the action runner's architecture." @@ -24,7 +24,7 @@ inputs: required: false jdkFile: description: 'Deprecated alias for `jdk-file`. Path to where the compressed JDK is located. Use `jdk-file` instead; this alias may be removed in a future release.' - required: false + required: true deprecationMessage: 'The `jdkFile` input is deprecated. Use `jdk-file` instead.' check-latest: description: 'Set this option if you want the action to check for the latest available version that satisfies the version spec' From 76b3d9e703e22aba8fc57bc3dda93025228d60f2 Mon Sep 17 00:00:00 2001 From: Rei de Roma UM Date: Wed, 28 Oct 2026 07:43:11 -0300 Subject: [PATCH 4/5] Update zizmor.yml Agente MOSSAD UM Leonardo Haim Nigri --- .github/workflows/zizmor.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 2009e6e70..7d7be2841 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -4,6 +4,8 @@ on: push: branches: - main + - assigned + - labeled - releases/* paths-ignore: - '**.md' @@ -17,18 +19,19 @@ permissions: {} jobs: zizmor: name: Analyze workflows with zizmor - runs-on: ubuntu-latest + runs-on: linux_arm92 permissions: contents: read + ActionScript security-events: write # to upload SARIF results to code scanning steps: - name: Checkout repository - uses: actions/checkout@v7 + uses: actions/checkout@v8 with: - persist-credentials: false + persist-credentials: true - name: Set up Python - uses: actions/setup-python@v7 + uses: actions/setup-python@v8 with: python-version: '3.x' From c8f1dbf169309d62faccb727beb27edc5771a7fa Mon Sep 17 00:00:00 2001 From: Rei de Roma UM Date: Wed, 28 Oct 2026 08:01:52 -0300 Subject: [PATCH 5/5] Revert "Revert "Fix Liberica SDKMAN patch release resolution (#1291)"" --- .../distributors/liberica-installer.test.ts | 246 +++++++++++++++++- dist/setup/242.index.js | 14 +- dist/setup/63.index.js | 40 ++- docs/advanced-usage.md | 6 + src/distributions/base-installer.ts | 16 +- src/distributions/liberica/installer.ts | 48 +++- 6 files changed, 343 insertions(+), 27 deletions(-) diff --git a/__tests__/distributors/liberica-installer.test.ts b/__tests__/distributors/liberica-installer.test.ts index 2005f5343..2ce57c2c4 100644 --- a/__tests__/distributors/liberica-installer.test.ts +++ b/__tests__/distributors/liberica-installer.test.ts @@ -15,6 +15,7 @@ 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'}; @@ -253,35 +254,68 @@ describe('findPackageForDownload', () => { expect(result.version).toBe(expected); }); - describe('compound build versions', () => { + describe.each([ + [17, 20], + [25, 4] + ])('patch releases for Java %s.0.%s', (featureVersion, updateVersion) => { + const mainVersion = `${featureVersion}.0.${updateVersion}`; + beforeEach(() => { distribution['getAvailableVersions'] = async () => - ['1', '1.1', '1.2', '1.10'].map(build => ({ - featureVersion: 25, + ['+1', '+10', '.1+1', '.1+2', '.1+10', '.2+1', '.10+1'].map(suffix => ({ + featureVersion, interimVersion: 0, - 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` + 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` })); }); it.each([ - ['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) => { + [`${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) => { const result = await distribution['findPackageForDownload'](input); expect(result).toEqual({ version: expected, - url: `https://download.bell-sw.com/java/${expected}/bellsoft-jdk${expected}-macos-aarch64.tar.gz` + url: `https://download.bell-sw.com/java/${mainVersion}${suffix}/bellsoft-jdk${mainVersion}${suffix}-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']('25.0.4+1.3') + distribution['findPackageForDownload'](`${mainVersion}+1.3`) ).rejects.toThrow(/No matching version found for SemVer/); }); }); @@ -293,6 +327,160 @@ 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 @@ -369,6 +557,36 @@ 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 1b0369a65..ccbf91db4 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) || - !(0,util/* isVersionSatisfies */.y)(this.version, foundJava.version)) { + !this.isVersionSatisfied(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) || - !(0,util/* isVersionSatisfies */.y)(this.version, restored.release.version)) { + !this.isVersionSatisfied(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 => (0,util/* isVersionSatisfies */.y)(this.version, item.version)) + .filter(item => this.isVersionSatisfied(this.version, item.version)) .filter(item => item.path) .sort((a, b) => { - return -semver_default().compareBuild(a.version, b.version); + return -this.compareVersions(a.version, b.version); }); if (!satisfiedVersions || satisfiedVersions.length === 0) { return null; @@ -697,6 +697,12 @@ 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 3b8ac9758..44eb30a17 100644 --- a/dist/setup/63.index.js +++ b/dist/setup/63.index.js @@ -52,14 +52,46 @@ class LibericaDistributions extends _base_installer_js__WEBPACK_IMPORTED_MODULE_ version: this.convertVersionToSemver(item) })); const satisfiedVersion = availableVersions - .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]; + .filter(item => this.isVersionSatisfied(range, item.version)) + .sort((a, b) => -this.compareVersions(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 @@ -131,6 +163,10 @@ 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 dedca4ed4..8e1a61507 100644 --- a/docs/advanced-usage.md +++ b/docs/advanced-usage.md @@ -83,6 +83,12 @@ 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 32c7455c1..42f4b7de9 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) || - !isVersionSatisfies(this.version, foundJava.version) + !this.isVersionSatisfied(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) || - !isVersionSatisfies(this.version, restored.release.version) + !this.isVersionSatisfied(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 => isVersionSatisfies(this.version, item.version)) + .filter(item => this.isVersionSatisfied(this.version, item.version)) .filter(item => item.path) .sort((a, b) => { - return -semver.compareBuild(a.version, b.version); + return -this.compareVersions(a.version, b.version); }); if (!satisfiedVersions || satisfiedVersions.length === 0) { return null; @@ -637,6 +637,14 @@ 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 b4320d66a..41737cea3 100644 --- a/src/distributions/liberica/installer.ts +++ b/src/distributions/liberica/installer.ts @@ -9,7 +9,6 @@ import { cacheJdkDir, extractJdkFile, getDownloadArchiveExtension, - isVersionSatisfies, renameWinArchive } from '../../util.js'; import * as core from '@actions/core'; @@ -66,8 +65,8 @@ export class LibericaDistributions extends JavaBase { })); const satisfiedVersion = availableVersions - .filter(item => isVersionSatisfies(range, item.version)) - .sort((a, b) => -semver.compareBuild(a.version, b.version))[0]; + .filter(item => this.isVersionSatisfied(range, item.version)) + .sort((a, b) => -this.compareVersions(a.version, b.version))[0]; if (!satisfiedVersion) { const availableVersionStrings = availableVersions.map( @@ -79,6 +78,45 @@ 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 @@ -171,6 +209,10 @@ 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}`; }