mirror of
https://gitea.com/actions/setup-java.git
synced 2026-10-02 21:25:25 +08:00
Accept 4-part versions with build metadata (X.Y.Z.P+B -> X.Y.Z+P.B) and match exact Temurin requests against OpenJDK-derived version keys, since the Adoptium API semver folds the patch into the build number (26.0.2+101) and adds LTS metadata (25.0.4+7.0.LTS). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -233,7 +233,7 @@ Additional distribution notes:
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| Major version | `8`, `11`, `17`, `21`, `25` |
|
| Major version | `8`, `11`, `17`, `21`, `25` |
|
||||||
| Specific feature or patch version | `11.0`, `11.0.4`, `17.0`, `8.0.282+8` |
|
| Specific feature or patch version | `11.0`, `11.0.4`, `17.0`, `8.0.282+8` |
|
||||||
| JEP 322 multi-field versions | `11.0.9.1`, `18.0.1.1` |
|
| JEP 322 multi-field versions | `11.0.9.1`, `18.0.1.1`, `26.0.2.1+1` |
|
||||||
| Early access | `15-ea`, `15.0.0-ea`, `27-ea` |
|
| Early access | `15-ea`, `15.0.0-ea`, `27-ea` |
|
||||||
| Latest stable GA release | `latest` |
|
| Latest stable GA release | `latest` |
|
||||||
|
|
||||||
|
|||||||
@@ -1758,6 +1758,8 @@ describe('normalizeVersion', () => {
|
|||||||
['11.0.9.1', {version: '11.0.9+1', stable: true, latest: false}],
|
['11.0.9.1', {version: '11.0.9+1', stable: true, latest: false}],
|
||||||
['12.0.2.1.0', {version: '12.0.2+1.0', stable: true, latest: false}],
|
['12.0.2.1.0', {version: '12.0.2+1.0', stable: true, latest: false}],
|
||||||
['18.0.1.1-ea', {version: '18.0.1+1', stable: false, latest: false}],
|
['18.0.1.1-ea', {version: '18.0.1+1', stable: false, latest: false}],
|
||||||
|
['26.0.2.1+1', {version: '26.0.2+1.1', stable: true, latest: false}],
|
||||||
|
['25.0.4.1+1', {version: '25.0.4+1.1', stable: true, latest: false}],
|
||||||
['latest', {version: 'x', stable: true, latest: true}],
|
['latest', {version: 'x', stable: true, latest: true}],
|
||||||
['LATEST', {version: 'x', stable: true, latest: true}],
|
['LATEST', {version: 'x', stable: true, latest: true}],
|
||||||
[' Latest ', {version: 'x', stable: true, latest: true}]
|
[' Latest ', {version: 'x', stable: true, latest: true}]
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ describe('getJavaDistribution', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each(['8', '23.x', '23.0.1.1', '<24'])(
|
it.each(['8', '23.x', '23.0.1.1', '23.0.1.1+1', '<24'])(
|
||||||
"rejects Temurin java-package 'jdk+jmods' for version %s",
|
"rejects Temurin java-package 'jdk+jmods' for version %s",
|
||||||
async version => {
|
async version => {
|
||||||
await expect(
|
await expect(
|
||||||
@@ -96,7 +96,7 @@ describe('getJavaDistribution', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
it.each(['24', '24.0.1.1', '25-ea', '>=21', 'latest'])(
|
it.each(['24', '24.0.1.1', '25.0.4.1+1', '25-ea', '>=21', 'latest'])(
|
||||||
"accepts Temurin java-package 'jdk+jmods' for version %s",
|
"accepts Temurin java-package 'jdk+jmods' for version %s",
|
||||||
async version => {
|
async version => {
|
||||||
expect(
|
expect(
|
||||||
|
|||||||
@@ -378,6 +378,97 @@ describe('findPackageForDownload', () => {
|
|||||||
expect(resolvedVersion.version).toBe('16.0.2+7');
|
expect(resolvedVersion.version).toBe('16.0.2+7');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('OpenJDK patch (respin) versions', () => {
|
||||||
|
const makeRelease = (
|
||||||
|
semverVersion: string,
|
||||||
|
openjdkVersion: string,
|
||||||
|
versionData: Record<string, number>
|
||||||
|
) => ({
|
||||||
|
binaries: [
|
||||||
|
{
|
||||||
|
package: {
|
||||||
|
link: `https://example.com/${openjdkVersion}.tar.gz`,
|
||||||
|
checksum: `checksum-${openjdkVersion}`,
|
||||||
|
checksum_link: `https://example.com/${openjdkVersion}.sha256.txt`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
version_data: {
|
||||||
|
semver: semverVersion,
|
||||||
|
openjdk_version: openjdkVersion,
|
||||||
|
minor: 0,
|
||||||
|
...versionData
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const respinManifest = [
|
||||||
|
makeRelease('26.0.2+101', '26.0.2.1+1', {
|
||||||
|
major: 26,
|
||||||
|
security: 2,
|
||||||
|
patch: 1,
|
||||||
|
build: 1
|
||||||
|
}),
|
||||||
|
makeRelease('26.0.2+10', '26.0.2+10', {
|
||||||
|
major: 26,
|
||||||
|
security: 2,
|
||||||
|
build: 10
|
||||||
|
}),
|
||||||
|
makeRelease('25.0.4+101.0.LTS', '25.0.4.1+1-LTS', {
|
||||||
|
major: 25,
|
||||||
|
security: 4,
|
||||||
|
patch: 1,
|
||||||
|
build: 1
|
||||||
|
}),
|
||||||
|
makeRelease('25.0.4+7.0.LTS', '25.0.4+7-LTS', {
|
||||||
|
major: 25,
|
||||||
|
security: 4,
|
||||||
|
build: 7
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
['26.0.2.1+1', '26.0.2+101'],
|
||||||
|
['26.0.2+10', '26.0.2+10'],
|
||||||
|
['26', '26.0.2+101'],
|
||||||
|
['26.0.2', '26.0.2+101'],
|
||||||
|
['25.0.4.1+1', '25.0.4+101.0.LTS'],
|
||||||
|
['25.0.4+7', '25.0.4+7.0.LTS'],
|
||||||
|
['25.0.4', '25.0.4+101.0.LTS']
|
||||||
|
])('%s resolves to %s', async (input, expected) => {
|
||||||
|
const distribution = new TemurinDistribution(
|
||||||
|
{
|
||||||
|
version: input,
|
||||||
|
architecture: 'x64',
|
||||||
|
packageType: 'jdk',
|
||||||
|
checkLatest: false
|
||||||
|
},
|
||||||
|
TemurinImplementation.Hotspot
|
||||||
|
);
|
||||||
|
distribution['getAvailableVersions'] = async () => respinManifest as any;
|
||||||
|
const resolvedVersion = await distribution['findPackageForDownload'](
|
||||||
|
distribution['version']
|
||||||
|
);
|
||||||
|
expect(resolvedVersion.version).toBe(expected);
|
||||||
|
expect(resolvedVersion).not.toHaveProperty('openjdkVersion');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not match a non-existent respin', async () => {
|
||||||
|
const distribution = new TemurinDistribution(
|
||||||
|
{
|
||||||
|
version: '26.0.2.2+1',
|
||||||
|
architecture: 'x64',
|
||||||
|
packageType: 'jdk',
|
||||||
|
checkLatest: false
|
||||||
|
},
|
||||||
|
TemurinImplementation.Hotspot
|
||||||
|
);
|
||||||
|
distribution['getAvailableVersions'] = async () => respinManifest as any;
|
||||||
|
await expect(
|
||||||
|
distribution['findPackageForDownload'](distribution['version'])
|
||||||
|
).rejects.toThrow(/No matching version found for SemVer '26.0.2\+2.1'/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('version is found but binaries list is empty', async () => {
|
it('version is found but binaries list is empty', async () => {
|
||||||
const distribution = new TemurinDistribution(
|
const distribution = new TemurinDistribution(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ const core = await import('@actions/core');
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
convertVersionToSemver,
|
convertVersionToSemver,
|
||||||
|
normalizeJavaVersionToSemver,
|
||||||
getNextPageUrlFromLinkHeader,
|
getNextPageUrlFromLinkHeader,
|
||||||
getVersionFromFileContent,
|
getVersionFromFileContent,
|
||||||
isVersionSatisfies,
|
isVersionSatisfies,
|
||||||
@@ -188,6 +189,22 @@ describe('convertVersionToSemver', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('normalizeJavaVersionToSemver', () => {
|
||||||
|
it.each([
|
||||||
|
['17', '17'],
|
||||||
|
['17.0.8', '17.0.8'],
|
||||||
|
['17.0.8+7', '17.0.8+7'],
|
||||||
|
['11.0.9.1', '11.0.9+1'],
|
||||||
|
['12.0.2.1.0', '12.0.2+1.0'],
|
||||||
|
['26.0.2.1+1', '26.0.2+1.1'],
|
||||||
|
['17.0.8.1+1080.1', '17.0.8+1.1080.1'],
|
||||||
|
['>=11.0.9.1', '>=11.0.9.1'],
|
||||||
|
['17.x', '17.x']
|
||||||
|
])('%s -> %s', (input: string, expected: string) => {
|
||||||
|
expect(normalizeJavaVersionToSemver(input)).toBe(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('getNextPageUrlFromLinkHeader', () => {
|
describe('getNextPageUrlFromLinkHeader', () => {
|
||||||
it.each([
|
it.each([
|
||||||
[
|
[
|
||||||
|
|||||||
Vendored
+15
-1
@@ -30848,7 +30848,7 @@ const DISTRIBUTIONS_ONLY_MAJOR_VERSION = (/* unused pure expression or super */
|
|||||||
/* harmony export */ Vt: () => (/* binding */ getBooleanInput),
|
/* harmony export */ Vt: () => (/* binding */ getBooleanInput),
|
||||||
/* harmony export */ lN: () => (/* binding */ isJdkCacheEnabled)
|
/* harmony export */ lN: () => (/* binding */ isJdkCacheEnabled)
|
||||||
/* harmony export */ });
|
/* harmony export */ });
|
||||||
/* unused harmony exports getVersionFromToolcachePath, extractJdkFile, cacheJdkDir, getJavaVersionFromReleaseFile, getDownloadArchiveExtension, isVersionSatisfies, getToolcachePath, isGhes, getVersionFromFileContent, convertVersionToSemver, getArtifactFingerprint, getGitHubToken, getGitHubHttpHeaders, MAX_PAGINATION_PAGES, getNextPageUrlFromLinkHeader, validatePaginationUrl, renameWinArchive, getLatestMajorVersion */
|
/* unused harmony exports getVersionFromToolcachePath, extractJdkFile, cacheJdkDir, getJavaVersionFromReleaseFile, getDownloadArchiveExtension, isVersionSatisfies, getToolcachePath, isGhes, getVersionFromFileContent, convertVersionToSemver, normalizeJavaVersionToSemver, getArtifactFingerprint, getGitHubToken, getGitHubHttpHeaders, MAX_PAGINATION_PAGES, getNextPageUrlFromLinkHeader, validatePaginationUrl, renameWinArchive, getLatestMajorVersion */
|
||||||
/* harmony import */ var os__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(857);
|
/* harmony import */ var os__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(857);
|
||||||
/* harmony import */ var os__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__nccwpck_require__.n(os__WEBPACK_IMPORTED_MODULE_0__);
|
/* harmony import */ var os__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__nccwpck_require__.n(os__WEBPACK_IMPORTED_MODULE_0__);
|
||||||
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(6928);
|
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(6928);
|
||||||
@@ -31247,6 +31247,20 @@ function convertVersionToSemver(version) {
|
|||||||
}
|
}
|
||||||
return mainVersion;
|
return mainVersion;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Java versions (JEP 322) can contain more numeric fields than SemVer allows,
|
||||||
|
* e.g. '11.0.9.1' or Temurin respins such as '26.0.2.1+1'. Move the extra
|
||||||
|
* fields into SemVer build metadata ('11.0.9+1', '26.0.2+1.1'). Any other
|
||||||
|
* input (ranges, regular SemVer versions) is returned unchanged.
|
||||||
|
*/
|
||||||
|
function normalizeJavaVersionToSemver(version) {
|
||||||
|
const match = /^(\d+(?:\.\d+){3,})(?:\+([0-9A-Za-z.-]+))?$/.exec(version);
|
||||||
|
if (!match) {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
const converted = convertVersionToSemver(match[1]);
|
||||||
|
return match[2] ? `${converted}.${match[2]}` : converted;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Builds a validator for the bytes currently served by a URL from the response
|
* Builds a validator for the bytes currently served by a URL from the response
|
||||||
* headers of a HEAD request. A vendor's `/latest/` URL never changes, so this
|
* headers of a HEAD request. A vendor's `/latest/` URL never changes, so this
|
||||||
|
|||||||
Vendored
+3
-6
@@ -730,12 +730,9 @@ class JavaBase {
|
|||||||
}
|
}
|
||||||
// Java uses a versioning scheme (JEP 322) that can contain more numeric
|
// Java uses a versioning scheme (JEP 322) that can contain more numeric
|
||||||
// fields than SemVer allows, e.g. '18.0.1.1' or '11.0.9.1'. Convert such
|
// fields than SemVer allows, e.g. '18.0.1.1' or '11.0.9.1'. Convert such
|
||||||
// exact versions to SemVer build notation ('18.0.1+1') so they are
|
// exact versions to SemVer build notation ('18.0.1+1', or '26.0.2+1.1'
|
||||||
// accepted. Ranges and versions that already carry build metadata are
|
// for '26.0.2.1+1') so they are accepted. Ranges are left untouched.
|
||||||
// left untouched.
|
version = (0,util/* normalizeJavaVersionToSemver */.zZ)(version);
|
||||||
if (/^\d+(\.\d+){3,}$/.test(version)) {
|
|
||||||
version = (0,util/* convertVersionToSemver */.ZY)(version);
|
|
||||||
}
|
|
||||||
if (!semver_default().validRange(version)) {
|
if (!semver_default().validRange(version)) {
|
||||||
throw new Error(`The string '${version}' is not valid SemVer notation for a Java version. Please check README file for code snippets and more detailed information`);
|
throw new Error(`The string '${version}' is not valid SemVer notation for a Java version. Please check README file for code snippets and more detailed information`);
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+31
-3
@@ -109,7 +109,7 @@ class TemurinDistribution extends base_installer/* JavaBase */.O {
|
|||||||
const formattedVersion = this.stable
|
const formattedVersion = this.stable
|
||||||
? item.version_data.semver
|
? item.version_data.semver
|
||||||
: item.version_data.semver.replace('-beta+', '+');
|
: item.version_data.semver.replace('-beta+', '+');
|
||||||
return {
|
const release = {
|
||||||
version: formattedVersion,
|
version: formattedVersion,
|
||||||
url: item.binaries[0].package.link,
|
url: item.binaries[0].package.link,
|
||||||
signatureUrl: item.binaries[0].package.signature_link,
|
signatureUrl: item.binaries[0].package.signature_link,
|
||||||
@@ -119,15 +119,29 @@ class TemurinDistribution extends base_installer/* JavaBase */.O {
|
|||||||
source: item.binaries[0].package.checksum_link
|
source: item.binaries[0].package.checksum_link
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
return {
|
||||||
|
release,
|
||||||
|
openjdkVersion: getOpenJdkSemverVersion(item.version_data)
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
// The Adoptium API `semver` folds the JEP 322 patch field into the build
|
||||||
|
// number ('26.0.2.1+1' -> '26.0.2+101') and appends extra metadata for LTS
|
||||||
|
// releases ('25.0.4+7' -> '25.0.4+7.0.LTS'). Exact versions requested by
|
||||||
|
// users follow the OpenJDK notation instead, so also match them against a
|
||||||
|
// key derived from the OpenJDK version fields ('26.0.2+1.1', '25.0.4+7').
|
||||||
|
const isExactBuildRequest = (semver_default().parse(version)?.build.length ?? 0) > 0;
|
||||||
const satisfiedVersions = availableVersionsWithBinaries
|
const satisfiedVersions = availableVersionsWithBinaries
|
||||||
.filter(item => (0,util/* isVersionSatisfies */.y)(version, item.version))
|
.filter(({ release, openjdkVersion }) => (0,util/* isVersionSatisfies */.y)(version, release.version) ||
|
||||||
|
(isExactBuildRequest &&
|
||||||
|
openjdkVersion !== null &&
|
||||||
|
semver_default().compareBuild(version, openjdkVersion) === 0))
|
||||||
|
.map(({ release }) => release)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
return -semver_default().compareBuild(a.version, b.version);
|
return -semver_default().compareBuild(a.version, b.version);
|
||||||
});
|
});
|
||||||
const resolvedFullVersion = satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
|
const resolvedFullVersion = satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
|
||||||
if (!resolvedFullVersion) {
|
if (!resolvedFullVersion) {
|
||||||
const availableVersionStrings = availableVersionsWithBinaries.map(item => item.version);
|
const availableVersionStrings = availableVersionsWithBinaries.map(({ release }) => release.version);
|
||||||
throw this.createVersionNotFoundError(version, availableVersionStrings);
|
throw this.createVersionNotFoundError(version, availableVersionStrings);
|
||||||
}
|
}
|
||||||
return resolvedFullVersion;
|
return resolvedFullVersion;
|
||||||
@@ -279,6 +293,20 @@ class TemurinDistribution extends base_installer/* JavaBase */.O {
|
|||||||
return architecture === 'armv7' ? 'arm' : architecture;
|
return architecture === 'armv7' ? 'arm' : architecture;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Builds a SemVer version from the OpenJDK version fields reported by the
|
||||||
|
* Adoptium API, e.g. '26.0.2.1+1' -> '26.0.2+1.1' and '25.0.4+7-LTS' ->
|
||||||
|
* '25.0.4+7'. Returns null if the fields cannot form a valid SemVer version.
|
||||||
|
*/
|
||||||
|
function getOpenJdkSemverVersion(versionData) {
|
||||||
|
const { major, minor, security, patch, build } = versionData;
|
||||||
|
if (build === undefined || build === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const buildMetadata = patch ? `${patch}.${build}` : `${build}`;
|
||||||
|
const version = `${major}.${minor}.${security}+${buildMetadata}`;
|
||||||
|
return semver_default().valid(version) ? version : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|||||||
Vendored
+17
-7
@@ -30975,12 +30975,7 @@ function canResolveTemurinJmods(version) {
|
|||||||
if (normalizedVersion === 'latest') {
|
if (normalizedVersion === 'latest') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let normalizedRange = normalizedVersion
|
const normalizedRange = (0,_util_js__WEBPACK_IMPORTED_MODULE_1__/* .normalizeJavaVersionToSemver */ .zZ)(normalizedVersion.replace(/-ea$/, '').replace('-ea.', '+'));
|
||||||
.replace(/-ea$/, '')
|
|
||||||
.replace('-ea.', '+');
|
|
||||||
if (/^\d+(\.\d+){3,}$/.test(normalizedRange)) {
|
|
||||||
normalizedRange = (0,_util_js__WEBPACK_IMPORTED_MODULE_1__/* .convertVersionToSemver */ .ZY)(normalizedRange);
|
|
||||||
}
|
|
||||||
if (!semver__WEBPACK_IMPORTED_MODULE_0___default().validRange(normalizedRange)) {
|
if (!semver__WEBPACK_IMPORTED_MODULE_0___default().validRange(normalizedRange)) {
|
||||||
// JavaBase owns general version validation and its targeted error messages.
|
// JavaBase owns general version validation and its targeted error messages.
|
||||||
return true;
|
return true;
|
||||||
@@ -31311,7 +31306,8 @@ function validateToolchainIds(versions, versionFile, toolchainIds) {
|
|||||||
/* harmony export */ rC: () => (/* binding */ getNextPageUrlFromLinkHeader),
|
/* harmony export */ rC: () => (/* binding */ getNextPageUrlFromLinkHeader),
|
||||||
/* harmony export */ ri: () => (/* binding */ getLatestMajorVersion),
|
/* harmony export */ ri: () => (/* binding */ getLatestMajorVersion),
|
||||||
/* harmony export */ y: () => (/* binding */ isVersionSatisfies),
|
/* harmony export */ y: () => (/* binding */ isVersionSatisfies),
|
||||||
/* harmony export */ yH: () => (/* binding */ getToolcachePath)
|
/* harmony export */ yH: () => (/* binding */ getToolcachePath),
|
||||||
|
/* harmony export */ zZ: () => (/* binding */ normalizeJavaVersionToSemver)
|
||||||
/* harmony export */ });
|
/* harmony export */ });
|
||||||
/* unused harmony exports getVersionFromToolcachePath, isJobStatusSuccess */
|
/* unused harmony exports getVersionFromToolcachePath, isJobStatusSuccess */
|
||||||
/* harmony import */ var os__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(857);
|
/* harmony import */ var os__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(857);
|
||||||
@@ -31712,6 +31708,20 @@ function convertVersionToSemver(version) {
|
|||||||
}
|
}
|
||||||
return mainVersion;
|
return mainVersion;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Java versions (JEP 322) can contain more numeric fields than SemVer allows,
|
||||||
|
* e.g. '11.0.9.1' or Temurin respins such as '26.0.2.1+1'. Move the extra
|
||||||
|
* fields into SemVer build metadata ('11.0.9+1', '26.0.2+1.1'). Any other
|
||||||
|
* input (ranges, regular SemVer versions) is returned unchanged.
|
||||||
|
*/
|
||||||
|
function normalizeJavaVersionToSemver(version) {
|
||||||
|
const match = /^(\d+(?:\.\d+){3,})(?:\+([0-9A-Za-z.-]+))?$/.exec(version);
|
||||||
|
if (!match) {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
const converted = convertVersionToSemver(match[1]);
|
||||||
|
return match[2] ? `${converted}.${match[2]}` : converted;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Builds a validator for the bytes currently served by a URL from the response
|
* Builds a validator for the bytes currently served by a URL from the response
|
||||||
* headers of a HEAD request. A vendor's `/latest/` URL never changes, so this
|
* headers of a HEAD request. A vendor's `/latest/` URL never changes, so this
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import semver from 'semver';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import * as httpm from '@actions/http-client';
|
import * as httpm from '@actions/http-client';
|
||||||
import {
|
import {
|
||||||
convertVersionToSemver,
|
|
||||||
getToolcachePath,
|
getToolcachePath,
|
||||||
isVersionSatisfies
|
isVersionSatisfies,
|
||||||
|
normalizeJavaVersionToSemver
|
||||||
} from '../util.js';
|
} from '../util.js';
|
||||||
import type {
|
import type {
|
||||||
ChecksumAlgorithm,
|
ChecksumAlgorithm,
|
||||||
@@ -675,12 +675,9 @@ export abstract class JavaBase {
|
|||||||
|
|
||||||
// Java uses a versioning scheme (JEP 322) that can contain more numeric
|
// Java uses a versioning scheme (JEP 322) that can contain more numeric
|
||||||
// fields than SemVer allows, e.g. '18.0.1.1' or '11.0.9.1'. Convert such
|
// fields than SemVer allows, e.g. '18.0.1.1' or '11.0.9.1'. Convert such
|
||||||
// exact versions to SemVer build notation ('18.0.1+1') so they are
|
// exact versions to SemVer build notation ('18.0.1+1', or '26.0.2+1.1'
|
||||||
// accepted. Ranges and versions that already carry build metadata are
|
// for '26.0.2.1+1') so they are accepted. Ranges are left untouched.
|
||||||
// left untouched.
|
version = normalizeJavaVersionToSemver(version);
|
||||||
if (/^\d+(\.\d+){3,}$/.test(version)) {
|
|
||||||
version = convertVersionToSemver(version);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!semver.validRange(version)) {
|
if (!semver.validRange(version)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import semver from 'semver';
|
import semver from 'semver';
|
||||||
import {convertVersionToSemver} from '../util.js';
|
import {normalizeJavaVersionToSemver} from '../util.js';
|
||||||
|
|
||||||
export enum JavaDistribution {
|
export enum JavaDistribution {
|
||||||
Temurin = 'temurin',
|
Temurin = 'temurin',
|
||||||
@@ -98,12 +98,9 @@ function canResolveTemurinJmods(version: string): boolean {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let normalizedRange = normalizedVersion
|
const normalizedRange = normalizeJavaVersionToSemver(
|
||||||
.replace(/-ea$/, '')
|
normalizedVersion.replace(/-ea$/, '').replace('-ea.', '+')
|
||||||
.replace('-ea.', '+');
|
);
|
||||||
if (/^\d+(\.\d+){3,}$/.test(normalizedRange)) {
|
|
||||||
normalizedRange = convertVersionToSemver(normalizedRange);
|
|
||||||
}
|
|
||||||
if (!semver.validRange(normalizedRange)) {
|
if (!semver.validRange(normalizedRange)) {
|
||||||
// JavaBase owns general version validation and its targeted error messages.
|
// JavaBase owns general version validation and its targeted error messages.
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export class TemurinDistribution extends JavaBase {
|
|||||||
const formattedVersion = this.stable
|
const formattedVersion = this.stable
|
||||||
? item.version_data.semver
|
? item.version_data.semver
|
||||||
: item.version_data.semver.replace('-beta+', '+');
|
: item.version_data.semver.replace('-beta+', '+');
|
||||||
return {
|
const release: JavaDownloadRelease = {
|
||||||
version: formattedVersion,
|
version: formattedVersion,
|
||||||
url: item.binaries[0].package.link,
|
url: item.binaries[0].package.link,
|
||||||
signatureUrl: item.binaries[0].package.signature_link,
|
signatureUrl: item.binaries[0].package.signature_link,
|
||||||
@@ -79,11 +79,29 @@ export class TemurinDistribution extends JavaBase {
|
|||||||
value: item.binaries[0].package.checksum,
|
value: item.binaries[0].package.checksum,
|
||||||
source: item.binaries[0].package.checksum_link
|
source: item.binaries[0].package.checksum_link
|
||||||
}
|
}
|
||||||
} as JavaDownloadRelease;
|
};
|
||||||
|
return {
|
||||||
|
release,
|
||||||
|
openjdkVersion: getOpenJdkSemverVersion(item.version_data)
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// The Adoptium API `semver` folds the JEP 322 patch field into the build
|
||||||
|
// number ('26.0.2.1+1' -> '26.0.2+101') and appends extra metadata for LTS
|
||||||
|
// releases ('25.0.4+7' -> '25.0.4+7.0.LTS'). Exact versions requested by
|
||||||
|
// users follow the OpenJDK notation instead, so also match them against a
|
||||||
|
// key derived from the OpenJDK version fields ('26.0.2+1.1', '25.0.4+7').
|
||||||
|
const isExactBuildRequest = (semver.parse(version)?.build.length ?? 0) > 0;
|
||||||
|
|
||||||
const satisfiedVersions = availableVersionsWithBinaries
|
const satisfiedVersions = availableVersionsWithBinaries
|
||||||
.filter(item => isVersionSatisfies(version, item.version))
|
.filter(
|
||||||
|
({release, openjdkVersion}) =>
|
||||||
|
isVersionSatisfies(version, release.version) ||
|
||||||
|
(isExactBuildRequest &&
|
||||||
|
openjdkVersion !== null &&
|
||||||
|
semver.compareBuild(version, openjdkVersion) === 0)
|
||||||
|
)
|
||||||
|
.map(({release}) => release)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
return -semver.compareBuild(a.version, b.version);
|
return -semver.compareBuild(a.version, b.version);
|
||||||
});
|
});
|
||||||
@@ -92,7 +110,7 @@ export class TemurinDistribution extends JavaBase {
|
|||||||
satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
|
satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
|
||||||
if (!resolvedFullVersion) {
|
if (!resolvedFullVersion) {
|
||||||
const availableVersionStrings = availableVersionsWithBinaries.map(
|
const availableVersionStrings = availableVersionsWithBinaries.map(
|
||||||
item => item.version
|
({release}) => release.version
|
||||||
);
|
);
|
||||||
throw this.createVersionNotFoundError(version, availableVersionStrings);
|
throw this.createVersionNotFoundError(version, availableVersionStrings);
|
||||||
}
|
}
|
||||||
@@ -309,3 +327,20 @@ export class TemurinDistribution extends JavaBase {
|
|||||||
return architecture === 'armv7' ? 'arm' : architecture;
|
return architecture === 'armv7' ? 'arm' : architecture;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a SemVer version from the OpenJDK version fields reported by the
|
||||||
|
* Adoptium API, e.g. '26.0.2.1+1' -> '26.0.2+1.1' and '25.0.4+7-LTS' ->
|
||||||
|
* '25.0.4+7'. Returns null if the fields cannot form a valid SemVer version.
|
||||||
|
*/
|
||||||
|
function getOpenJdkSemverVersion(
|
||||||
|
versionData: ITemurinAvailableVersions['version_data']
|
||||||
|
): string | null {
|
||||||
|
const {major, minor, security, patch, build} = versionData;
|
||||||
|
if (build === undefined || build === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const buildMetadata = patch ? `${patch}.${build}` : `${build}`;
|
||||||
|
const version = `${major}.${minor}.${security}+${buildMetadata}`;
|
||||||
|
return semver.valid(version) ? version : null;
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ export interface ITemurinAvailableVersions {
|
|||||||
minor: number;
|
minor: number;
|
||||||
openjdk_version: string;
|
openjdk_version: string;
|
||||||
security: string;
|
security: string;
|
||||||
|
patch?: number;
|
||||||
semver: string;
|
semver: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+15
@@ -510,6 +510,21 @@ export function convertVersionToSemver(version: number[] | string) {
|
|||||||
return mainVersion;
|
return mainVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java versions (JEP 322) can contain more numeric fields than SemVer allows,
|
||||||
|
* e.g. '11.0.9.1' or Temurin respins such as '26.0.2.1+1'. Move the extra
|
||||||
|
* fields into SemVer build metadata ('11.0.9+1', '26.0.2+1.1'). Any other
|
||||||
|
* input (ranges, regular SemVer versions) is returned unchanged.
|
||||||
|
*/
|
||||||
|
export function normalizeJavaVersionToSemver(version: string): string {
|
||||||
|
const match = /^(\d+(?:\.\d+){3,})(?:\+([0-9A-Za-z.-]+))?$/.exec(version);
|
||||||
|
if (!match) {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
const converted = convertVersionToSemver(match[1]);
|
||||||
|
return match[2] ? `${converted}.${match[2]}` : converted;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a validator for the bytes currently served by a URL from the response
|
* Builds a validator for the bytes currently served by a URL from the response
|
||||||
* headers of a HEAD request. A vendor's `/latest/` URL never changes, so this
|
* headers of a HEAD request. A vendor's `/latest/` URL never changes, so this
|
||||||
|
|||||||
Reference in New Issue
Block a user