feat: Add distribution detection support to .sdkmanrc file (#975)

* feat: Add distribution detection support to .sdkmanrc file

Extends .sdkmanrc support to automatically detect Java distribution from SDKMAN identifiers (e.g., java=21.0.5-tem maps to temurin distribution).

Makes distribution input optional when using .sdkmanrc with distribution suffix.

* fix: align SDKMAN sem identifier mapping

* fix: support SDKMAN albba identifier

* docs: clarify sdkmanrc distribution inference scope

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add Tencent Kona SDKMAN mapping and format sdkmanrc docs as a table

- Map SDKMAN 'kona' identifier to the 'kona' distribution (added in #672)
- Add a .sdkmanrc test case for the kona suffix
- Convert the inline SDKMAN suffix mapping in advanced-usage.md to a table
- Rebuild dist bundles

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Bruno Borges <brborges@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Bruno Borges <bruno.borges@gmail.com>
This commit is contained in:
Lukasz
2026-07-07 20:49:12 +02:00
committed by GitHub
parent c4922bf809
commit 0f481fcb61
9 changed files with 333 additions and 89 deletions
+49 -22
View File
@@ -17,9 +17,7 @@ import {configureMavenArgs} from './maven-args';
async function run() {
try {
const versions = core.getMultilineInput(constants.INPUT_JAVA_VERSION);
const distributionName = core.getInput(constants.INPUT_DISTRIBUTION, {
required: true
});
let distributionName = core.getInput(constants.INPUT_DISTRIBUTION);
const versionFile = core.getInput(constants.INPUT_JAVA_VERSION_FILE);
const architecture = core.getInput(constants.INPUT_ARCHITECTURE);
const packageType = core.getInput(constants.INPUT_JAVA_PACKAGE);
@@ -48,42 +46,71 @@ async function run() {
throw new Error('java-version or java-version-file input expected');
}
const installerInputsOptions: installerInputsOptions = {
architecture,
packageType,
checkLatest,
setDefault,
verifySignature,
verifySignaturePublicKey,
distributionName,
jdkFile,
toolchainIds
};
if (!versions.length) {
core.debug(
'java-version input is empty, looking for java-version-file input'
);
const content = fs.readFileSync(versionFile).toString().trim();
const version = getVersionFromFileContent(
const versionInfo = getVersionFromFileContent(
content,
distributionName,
versionFile
);
core.debug(`Parsed version from file '${version}'`);
core.debug(`Parsed version from file '${versionInfo?.version}'`);
if (!version) {
if (!versionInfo) {
throw new Error(
`No supported version was found in file ${versionFile}`
);
}
await installVersion(version, installerInputsOptions);
}
// Use distribution from file if available, otherwise use the input
if (versionInfo.distribution) {
core.info(
`Using distribution '${versionInfo.distribution}' from ${versionFile}`
);
distributionName = versionInfo.distribution;
} else if (!distributionName) {
throw new Error(
'distribution input is required when not specified in the version file'
);
}
for (const [index, version] of versions.entries()) {
await installVersion(version, installerInputsOptions, index);
const installerInputsOptions: installerInputsOptions = {
architecture,
packageType,
checkLatest,
setDefault,
verifySignature,
verifySignaturePublicKey,
distributionName,
jdkFile,
toolchainIds
};
await installVersion(versionInfo.version, installerInputsOptions);
} else {
// When using java-version input, distribution is still required
if (!distributionName) {
throw new Error('distribution input is required');
}
const installerInputsOptions: installerInputsOptions = {
architecture,
packageType,
checkLatest,
setDefault,
verifySignature,
verifySignaturePublicKey,
distributionName,
jdkFile,
toolchainIds
};
for (const [index, version] of versions.entries()) {
await installVersion(version, installerInputsOptions, index);
}
}
core.endGroup();
const matchersPath = path.join(__dirname, '..', '..', '.github');
+61 -6
View File
@@ -127,12 +127,18 @@ export function isCacheFeatureAvailable(): boolean {
return false;
}
export interface VersionInfo {
version: string;
distribution?: string;
}
export function getVersionFromFileContent(
content: string,
distributionName: string,
versionFile: string
): string | null {
): VersionInfo | null {
let javaVersionRegExp: RegExp;
let extractedDistribution: string | undefined;
function getFileName(versionFile: string) {
return path.basename(versionFile);
@@ -143,15 +149,27 @@ export function getVersionFromFileContent(
javaVersionRegExp =
/^java\s+(?:\S*-)?(?<version>\d+(?:\.\d+)*([+_.-](?:openj9[-._]?\d[\w.-]*|java\d+|jre[-_\w]*|OpenJDK\d+[\w_.-]*|[a-z0-9]+))*)/im;
} else if (versionFileName == '.sdkmanrc') {
javaVersionRegExp = /^java\s*=\s*(?<version>[^-]+)/m;
// Match both version and optional distribution identifier
javaVersionRegExp =
/^java\s*=\s*(?<version>[^-\s]+)(?:-(?<distribution>[a-z0-9]+))?/m;
} else {
javaVersionRegExp = /(?<version>(?<=(^|\s|-))(\d+\S*))(\s|$)/;
}
const capturedVersion = content.match(javaVersionRegExp)?.groups?.version
? (content.match(javaVersionRegExp)?.groups?.version as string)
const match = content.match(javaVersionRegExp);
const capturedVersion = match?.groups?.version
? (match.groups.version as string)
: '';
// Extract distribution from .sdkmanrc file
if (versionFileName == '.sdkmanrc' && match?.groups?.distribution) {
const sdkmanDist = match.groups.distribution;
extractedDistribution = mapSdkmanDistribution(sdkmanDist);
core.debug(
`Parsed distribution '${extractedDistribution}' from SDKMAN identifier '${sdkmanDist}'`
);
}
core.debug(
`Parsed version '${capturedVersion}' from file '${versionFileName}'`
);
@@ -172,12 +190,49 @@ export function getVersionFromFileContent(
return null;
}
if (DISTRIBUTIONS_ONLY_MAJOR_VERSION.includes(distributionName)) {
// Apply DISTRIBUTIONS_ONLY_MAJOR_VERSION logic whenever the effective distribution
// (either explicitly provided or extracted from the version file) is in the list.
if (
DISTRIBUTIONS_ONLY_MAJOR_VERSION.includes(
extractedDistribution || distributionName
)
) {
const coerceVersion = semver.coerce(version) ?? version;
version = semver.major(coerceVersion).toString();
}
return version.toString();
return {
version: version.toString(),
distribution: extractedDistribution
};
}
// Map SDKMAN distribution identifiers to setup-java distribution names
function mapSdkmanDistribution(sdkmanDist: string): string | undefined {
const distributionMap: Record<string, string> = {
tem: 'temurin',
sem: 'semeru',
albba: 'dragonwell',
zulu: 'zulu',
amzn: 'corretto',
graal: 'graalvm',
graalce: 'graalvm',
librca: 'liberica',
ms: 'microsoft',
oracle: 'oracle',
sapmchn: 'sapmachine',
jbr: 'jetbrains',
dragonwell: 'dragonwell',
kona: 'kona'
};
const mapped = distributionMap[sdkmanDist.toLowerCase()];
if (!mapped) {
core.warning(
`Unknown SDKMAN distribution identifier '${sdkmanDist}'. Please specify the distribution explicitly.`
);
}
return mapped;
}
// By convention, action expects version 8 in the format `8.*` instead of `1.8`