Compare commits

..

7 Commits

Author SHA1 Message Date
Bruno Borges
7093e6114d Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-08 15:03:50 -04:00
Bruno Borges
7ccd392cef Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-08 15:03:31 -04:00
Bruno Borges
b79d6754e6 Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-08 15:03:15 -04:00
Bruno Borges
90c9ef6da7 feat: expose cache-primary-key output (#597)
Expose the primary cache key computed by the caching logic as a new
`cache-primary-key` action output, so workflows can compose the built-in
setup-java cache key with actions/cache or actions/cache/restore across
steps and dependent jobs.

- src/cache.ts: set the `cache-primary-key` output in restore()
- action.yml: declare the new output
- README.md: document the new output
- __tests__/cache.test.ts: assert the output is set
- dist: rebuild

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-07-08 14:49:54 -04:00
Bruno Borges
fe9b749bcb Add Maven compiler problem matcher for javac diagnostics (#1086)
The javac problem matcher only recognized javac's native diagnostic
format (File.java:12: warning: msg), which works for plain javac and
Gradle but not Maven. The maven-compiler-plugin reformats diagnostics
to [WARNING] /path/File.java:[12,5] msg, so Maven builds produced zero
annotations.

Add a new maven-javac matcher owner that recognizes the Maven format,
capturing severity, file, line, column, and message. Maven builds now
annotate consistently with Gradle and plain javac.

Fixes: #1085

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-07-08 14:28:02 -04:00
Bruno Borges
4db08ef6bf Infer distribution from asdf .tool-versions vendor prefix (#1084)
* Infer distribution from asdf .tool-versions vendor prefix

asdf-java encodes the JDK vendor as a prefix on the version string in
.tool-versions (e.g. `java temurin-17.0.3+7`). Capture that prefix and
map it to a setup-java distribution, mirroring the existing .sdkmanrc
behavior. Unknown prefixes warn and fall back to the distribution input.

Fixes #1081

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

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-08 12:57:52 -04:00
Bruno Borges
7dbccc66ee Rename jdkFile input to jdk-file with deprecated alias (#1083)
* Rename jdkFile input to jdk-file with deprecated alias

Add a standardized `jdk-file` input to match the lowercase-dash naming
used by every other action input. The camelCase `jdkFile` input is kept
as a deprecated alias: it still works, but emits a deprecation warning and
may be removed in a future release. `jdk-file` takes precedence when both
are provided.

Updates docs and the local-file e2e workflow (one case intentionally keeps
using the deprecated alias for coverage) and regenerates the dist bundles.

Fixes #1077

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

* docs: keep jdkFile in switching-to-v2 guide

The switching-to-v2 migration guide uses actions/setup-java@v2, which only supports the camelCase jdkFile input. Keep the new jdk-file spelling in current-version docs only.

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

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-07-08 12:44:58 -04:00
13 changed files with 329 additions and 19 deletions

13
.github/java.json vendored
View File

@@ -21,6 +21,19 @@
"message": 4
}
]
},
{
"owner": "maven-javac",
"pattern": [
{
"regexp": "^\\[(WARNING|ERROR)\\]\\s+(.+?\\.java):\\[(\\d+),(\\d+)\\]\\s+(.+)$",
"severity": 1,
"file": 2,
"line": 3,
"column": 4,
"message": 5
}
]
}
]
}

View File

@@ -47,7 +47,7 @@ jobs:
id: setup-java
with:
distribution: 'jdkfile'
jdkFile: ${{ runner.temp }}/${{ env.LocalFilename }}
jdk-file: ${{ runner.temp }}/${{ env.LocalFilename }}
java-version: '11.0.0-ea'
architecture: x64
- name: Verify Java version
@@ -88,7 +88,7 @@ jobs:
id: setup-java
with:
distribution: 'jdkfile'
jdkFile: ${{ runner.temp }}/${{ env.LocalFilename }}
jdk-file: ${{ runner.temp }}/${{ env.LocalFilename }}
java-version: '11.0.0-ea'
architecture: x64
- name: Verify Java version
@@ -129,6 +129,7 @@ jobs:
id: setup-java
with:
distribution: 'jdkfile'
# Intentionally uses the deprecated `jdkFile` alias to keep it covered.
jdkFile: ${{ runner.temp }}/${{ env.LocalFilename }}
java-version: '11.0.0-ea'
architecture: x64

View File

@@ -41,7 +41,7 @@ For more details, see the full release notes on the [releases page](https://git
- `architecture`: The target architecture of the package. Possible values: `x86`, `x64`, `armv7`, `aarch64`, `ppc64le`. Default value: Derived from the runner machine.
- `jdkFile`: If a use-case requires a custom distribution setup-java uses the compressed JDK from the location pointed by this input and will take care of the installation and caching on the VM. Note: `distribution` must be set to 'jdkfile' (case-sensitive; all lowercase) when using this option.
- `jdk-file`: If a use-case requires a custom distribution setup-java uses the compressed JDK from the location pointed by this input and will take care of the installation and caching on the VM. Note: `distribution` must be set to 'jdkfile' (case-sensitive; all lowercase) when using this option. (The camelCase `jdkFile` input is still accepted as a deprecated alias and may be removed in a future release.)
- `check-latest`: Setting this option makes the action to check for the latest available version for the version spec.
@@ -149,6 +149,8 @@ When the option `cache-dependency-path` is specified, the hash is based on the m
The workflow output `cache-hit` is set to indicate if an exact match was found for the key [as actions/cache does](https://github.com/actions/cache/tree/main#outputs).
The workflow output `cache-primary-key` exposes the primary cache key computed by the action for the configured build tool. It is useful for composing with [`actions/cache`](https://github.com/actions/cache) or [`actions/cache/restore`](https://github.com/actions/cache/tree/main/restore) in later steps or dependent jobs that need to reuse the exact same key. It is empty when caching is not enabled or when caching is skipped (for example, when the cache service is unavailable).
The cache input is optional, and caching is turned off by default.
**Maven Wrapper:** when `cache: 'maven'` is enabled, the action also caches and restores the Maven Wrapper distribution downloaded to `~/.m2/wrapper/dists` (in addition to the local repository), so wrapper-based (`./mvnw`) builds don't re-download the wrapper on every run. This is keyed on `**/.mvn/wrapper/maven-wrapper.properties` as shown above.

View File

@@ -133,6 +133,7 @@ describe('dependency cache', () => {
describe('restore', () => {
let spyCacheRestore: any;
let spyGlobHashFiles: any;
let spySetOutput: any;
beforeEach(() => {
spyCacheRestore = (cache.restoreCache as any).mockImplementation(
@@ -140,6 +141,8 @@ describe('dependency cache', () => {
);
spyGlobHashFiles = glob.hashFiles as jest.Mock;
spyGlobHashFiles.mockResolvedValue('hash-stub');
spySetOutput = core.setOutput as jest.Mock;
spySetOutput.mockImplementation(() => null);
spyWarning.mockImplementation(() => null);
});
@@ -175,6 +178,15 @@ describe('dependency cache', () => {
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith('maven cache is not found');
});
it('sets the cache-primary-key output', async () => {
createFile(join(workspace, 'pom.xml'));
await restore('maven', '');
expect(spySetOutput).toHaveBeenCalledWith(
'cache-primary-key',
expect.stringContaining('setup-java-')
);
});
it('downloads cache based on maven-wrapper.properties', async () => {
createDirectory(join(workspace, '.mvn'));
createDirectory(join(workspace, '.mvn', 'wrapper'));

View File

@@ -296,6 +296,72 @@ describe('getVersionFromFileContent', () => {
);
});
});
describe('.tool-versions', () => {
it.each([
['java temurin-17.0.3+7', '17.0.3+7', 'temurin'],
['java temurin-jre-17.0.3+7', '17.0.3+7', 'temurin'],
['java adoptopenjdk-11.0.16+8', '11.0.16+8', 'temurin'],
['java adoptopenjdk-openj9-11.0.16+8', '11.0.16+8', 'temurin'],
['java zulu-11.56.19', '11.56.19', 'zulu'],
['java corretto-17.0.13.11.1', '17', 'corretto'], // corretto -> major only
['java liberica-11.0.15+10', '11.0.15+10', 'liberica'],
['java microsoft-11.0.13.8.1', '11.0.13', 'microsoft'],
['java semeru-openj9-11.0.25+9', '11.0.25+9', 'semeru'],
['java ibm-openj9-11.0.25+9', '11.0.25+9', 'semeru'],
['java dragonwell-17.0.13.0.13+11', '17.0.13', 'dragonwell'],
['java graalvm-22.3.0+java17', '22.3.0+java17', 'graalvm'],
['java graalvm-community-22.3.0', '22.3.0', 'graalvm-community'],
['java oracle-graalvm-21.0.5', '21.0.5', 'graalvm'],
['java oracle-21.0.5', '21.0.5', 'oracle'],
['java sapmachine-21.0.5', '21.0.5', 'sapmachine'],
['java kona-17.0.13', '17.0.13', 'kona'],
['java jetbrains-21.0.5', '21.0.5', 'jetbrains']
])(
'parsing %s should return version %s and distribution %s',
(content: string, expectedVersion: string, expectedDist: string) => {
const actual = getVersionFromFileContent(
content,
'openjdk',
'.tool-versions'
);
expect(actual?.version).toBe(expectedVersion);
expect(actual?.distribution).toBe(expectedDist);
}
);
it.each([
['java 17.0.7', '17.0.7'],
['java 17', '17'],
['java 1.8', '8'],
['java 21-ea', '21-ea']
])(
'parsing prefix-less %s should return version %s and no distribution',
(content: string, expectedVersion: string) => {
const actual = getVersionFromFileContent(
content,
'temurin',
'.tool-versions'
);
expect(actual?.version).toBe(expectedVersion);
expect(actual?.distribution).toBeUndefined();
}
);
it('should warn and return undefined distribution for unsupported vendor', () => {
const warnSpy = jest.spyOn(core, 'warning');
const actual = getVersionFromFileContent(
'java openjdk-17.0.7',
'temurin',
'.tool-versions'
);
expect(actual?.version).toBe('17.0.7');
expect(actual?.distribution).toBeUndefined();
expect(warnSpy).toHaveBeenCalledWith(
expect.stringContaining('Unknown asdf distribution identifier')
);
});
});
});
describe('isGhes', () => {

View File

@@ -19,9 +19,13 @@ inputs:
architecture:
description: "The architecture of the package (defaults to the action runner's architecture)"
required: false
jdkFile:
jdk-file:
description: 'Path to where the compressed JDK is located'
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
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'
required: false
@@ -99,6 +103,8 @@ outputs:
description: 'Path to where the java environment has been installed (same as $JAVA_HOME)'
cache-hit:
description: 'A boolean value to indicate an exact match was found for the primary key'
cache-primary-key:
description: 'The primary cache key computed by the action for the configured build tool. Empty when caching is not enabled or when caching is skipped (e.g. cache service unavailable). Useful for composing with actions/cache or actions/cache/restore across jobs.'
runs:
using: 'node24'
main: 'dist/setup/index.js'

53
dist/cleanup/index.js vendored
View File

@@ -95834,7 +95834,8 @@ const INPUT_JAVA_VERSION_FILE = 'java-version-file';
const INPUT_ARCHITECTURE = 'architecture';
const INPUT_JAVA_PACKAGE = 'java-package';
const INPUT_DISTRIBUTION = 'distribution';
const INPUT_JDK_FILE = 'jdkFile';
const INPUT_JDK_FILE = 'jdk-file';
const INPUT_JDK_FILE_DEPRECATED = 'jdkFile';
const INPUT_CHECK_LATEST = 'check-latest';
const INPUT_SET_DEFAULT = 'set-default';
const INPUT_VERIFY_SIGNATURE = 'verify-signature';
@@ -95965,8 +95966,10 @@ function getVersionFromFileContent(content, distributionName, versionFile) {
}
const versionFileName = getFileName(versionFile);
if (versionFileName == '.tool-versions') {
// Capture an optional asdf-java vendor prefix (e.g. `temurin-`, `corretto-`)
// in the `distribution` group so it can be mapped to a setup-java distribution.
javaVersionRegExp =
/^java\s+(?:\S*-)?(?<version>\d+(?:\.\d+)*([+_.-](?:openj9[-._]?\d[\w.-]*|java\d+|jre[-_\w]*|OpenJDK\d+[\w_.-]*|[a-z0-9]+))*)/im;
/^java\s+(?:(?<distribution>\S*)-)?(?<version>\d+(?:\.\d+)*([+_.-](?:openj9[-._]?\d[\w.-]*|java\d+|jre[-_\w]*|OpenJDK\d+[\w_.-]*|[a-z0-9]+))*)/im;
}
else if (versionFileName == '.sdkmanrc') {
// Match both version and optional distribution identifier
@@ -95986,6 +95989,14 @@ function getVersionFromFileContent(content, distributionName, versionFile) {
extractedDistribution = mapSdkmanDistribution(sdkmanDist);
core.debug(`Parsed distribution '${extractedDistribution}' from SDKMAN identifier '${sdkmanDist}'`);
}
// Extract distribution from asdf .tool-versions file
if (versionFileName == '.tool-versions' && match?.groups?.distribution) {
const asdfDist = match.groups.distribution;
extractedDistribution = mapAsdfDistribution(asdfDist);
if (extractedDistribution) {
core.debug(`Parsed distribution '${extractedDistribution}' from asdf identifier '${asdfDist}'`);
}
}
core.debug(`Parsed version '${capturedVersion}' from file '${versionFileName}'`);
if (!capturedVersion) {
return null;
@@ -96034,6 +96045,43 @@ function mapSdkmanDistribution(sdkmanDist) {
}
return mapped;
}
// Map asdf-java (.tool-versions) vendor identifiers to setup-java distribution names.
// asdf-java encodes the vendor as a prefix on the version string, e.g.
// `java temurin-17.0.3+7` or `java semeru-openj9-11.0.25+9`. Packaging variants
// (`-jre`, `-musl`, `-openj9`, `-crac`, `-javafx`, ...) are collapsed onto the
// base vendor since setup-java does not distinguish them here.
function mapAsdfDistribution(asdfDist) {
const normalized = asdfDist.toLowerCase();
// Multi-segment vendors that map to a distinct setup-java distribution.
if (normalized.startsWith('graalvm-community')) {
return 'graalvm-community';
}
if (normalized.startsWith('oracle-graalvm')) {
return 'graalvm';
}
const baseVendor = normalized.split('-')[0];
const distributionMap = {
temurin: 'temurin',
adoptopenjdk: 'temurin',
zulu: 'zulu',
corretto: 'corretto',
liberica: 'liberica',
microsoft: 'microsoft',
semeru: 'semeru',
ibm: 'semeru',
dragonwell: 'dragonwell',
graalvm: 'graalvm',
oracle: 'oracle',
sapmachine: 'sapmachine',
kona: 'kona',
jetbrains: 'jetbrains'
};
const mapped = distributionMap[baseVendor];
if (!mapped) {
core.warning(`Unknown asdf distribution identifier '${asdfDist}'. Please specify the distribution explicitly.`);
}
return mapped;
}
// By convention, action expects version 8 in the format `8.*` instead of `1.8`
function avoidOldNotation(content) {
return content.startsWith('1.') ? content.substring(2) : content;
@@ -99687,6 +99735,7 @@ async function restore(id, cacheDependencyPath) {
const primaryKey = await computeCacheKey(packageManager, cacheDependencyPath);
core.debug(`primary key is ${primaryKey}`);
core.saveState(STATE_CACHE_PRIMARY_KEY, primaryKey);
core.setOutput('cache-primary-key', primaryKey);
// No "restoreKeys" is set, to start with a clear cache after dependency update (see https://github.com/actions/setup-java/issues/269)
const matchedKey = await cache.restoreCache(packageManager.path, primaryKey);
if (matchedKey) {

63
dist/setup/index.js vendored
View File

@@ -73279,7 +73279,8 @@ const INPUT_JAVA_VERSION_FILE = 'java-version-file';
const INPUT_ARCHITECTURE = 'architecture';
const INPUT_JAVA_PACKAGE = 'java-package';
const INPUT_DISTRIBUTION = 'distribution';
const INPUT_JDK_FILE = 'jdkFile';
const INPUT_JDK_FILE = 'jdk-file';
const INPUT_JDK_FILE_DEPRECATED = 'jdkFile';
const INPUT_CHECK_LATEST = 'check-latest';
const INPUT_SET_DEFAULT = 'set-default';
const INPUT_VERIFY_SIGNATURE = 'verify-signature';
@@ -126957,8 +126958,10 @@ function getVersionFromFileContent(content, distributionName, versionFile) {
}
const versionFileName = getFileName(versionFile);
if (versionFileName == '.tool-versions') {
// Capture an optional asdf-java vendor prefix (e.g. `temurin-`, `corretto-`)
// in the `distribution` group so it can be mapped to a setup-java distribution.
javaVersionRegExp =
/^java\s+(?:\S*-)?(?<version>\d+(?:\.\d+)*([+_.-](?:openj9[-._]?\d[\w.-]*|java\d+|jre[-_\w]*|OpenJDK\d+[\w_.-]*|[a-z0-9]+))*)/im;
/^java\s+(?:(?<distribution>\S*)-)?(?<version>\d+(?:\.\d+)*([+_.-](?:openj9[-._]?\d[\w.-]*|java\d+|jre[-_\w]*|OpenJDK\d+[\w_.-]*|[a-z0-9]+))*)/im;
}
else if (versionFileName == '.sdkmanrc') {
// Match both version and optional distribution identifier
@@ -126978,6 +126981,14 @@ function getVersionFromFileContent(content, distributionName, versionFile) {
extractedDistribution = mapSdkmanDistribution(sdkmanDist);
core_debug(`Parsed distribution '${extractedDistribution}' from SDKMAN identifier '${sdkmanDist}'`);
}
// Extract distribution from asdf .tool-versions file
if (versionFileName == '.tool-versions' && match?.groups?.distribution) {
const asdfDist = match.groups.distribution;
extractedDistribution = mapAsdfDistribution(asdfDist);
if (extractedDistribution) {
core_debug(`Parsed distribution '${extractedDistribution}' from asdf identifier '${asdfDist}'`);
}
}
core_debug(`Parsed version '${capturedVersion}' from file '${versionFileName}'`);
if (!capturedVersion) {
return null;
@@ -127026,6 +127037,43 @@ function mapSdkmanDistribution(sdkmanDist) {
}
return mapped;
}
// Map asdf-java (.tool-versions) vendor identifiers to setup-java distribution names.
// asdf-java encodes the vendor as a prefix on the version string, e.g.
// `java temurin-17.0.3+7` or `java semeru-openj9-11.0.25+9`. Packaging variants
// (`-jre`, `-musl`, `-openj9`, `-crac`, `-javafx`, ...) are collapsed onto the
// base vendor since setup-java does not distinguish them here.
function mapAsdfDistribution(asdfDist) {
const normalized = asdfDist.toLowerCase();
// Multi-segment vendors that map to a distinct setup-java distribution.
if (normalized.startsWith('graalvm-community')) {
return 'graalvm-community';
}
if (normalized.startsWith('oracle-graalvm')) {
return 'graalvm';
}
const baseVendor = normalized.split('-')[0];
const distributionMap = {
temurin: 'temurin',
adoptopenjdk: 'temurin',
zulu: 'zulu',
corretto: 'corretto',
liberica: 'liberica',
microsoft: 'microsoft',
semeru: 'semeru',
ibm: 'semeru',
dragonwell: 'dragonwell',
graalvm: 'graalvm',
oracle: 'oracle',
sapmachine: 'sapmachine',
kona: 'kona',
jetbrains: 'jetbrains'
};
const mapped = distributionMap[baseVendor];
if (!mapped) {
warning(`Unknown asdf distribution identifier '${asdfDist}'. Please specify the distribution explicitly.`);
}
return mapped;
}
// By convention, action expects version 8 in the format `8.*` instead of `1.8`
function avoidOldNotation(content) {
return content.startsWith('1.') ? content.substring(2) : content;
@@ -130909,6 +130957,7 @@ async function restore(id, cacheDependencyPath) {
const primaryKey = await computeCacheKey(packageManager, cacheDependencyPath);
core_debug(`primary key is ${primaryKey}`);
saveState(STATE_CACHE_PRIMARY_KEY, primaryKey);
setOutput('cache-primary-key', primaryKey);
// No "restoreKeys" is set, to start with a clear cache after dependency update (see https://github.com/actions/setup-java/issues/269)
const matchedKey = await restoreCache(packageManager.path, primaryKey);
if (matchedKey) {
@@ -133513,7 +133562,7 @@ async function run() {
const versionFile = getInput(INPUT_JAVA_VERSION_FILE);
const architecture = getInput(INPUT_ARCHITECTURE);
const packageType = getInput(INPUT_JAVA_PACKAGE);
const jdkFile = getInput(INPUT_JDK_FILE);
const jdkFile = getJdkFileInput();
const cache = getInput(INPUT_CACHE);
const cacheDependencyPath = getInput(INPUT_CACHE_DEPENDENCY_PATH);
const checkLatest = util_getBooleanInput(INPUT_CHECK_LATEST, false);
@@ -133591,6 +133640,14 @@ async function run() {
}
}
run();
function getJdkFileInput() {
const jdkFile = getInput(INPUT_JDK_FILE);
const deprecatedJdkFile = getInput(INPUT_JDK_FILE_DEPRECATED);
if (deprecatedJdkFile) {
warning(`The '${INPUT_JDK_FILE_DEPRECATED}' input is deprecated and may be removed in a future release. Please use '${INPUT_JDK_FILE}' instead.`);
}
return jdkFile || deprecatedJdkFile;
}
async function installVersion(version, options, toolchainId = 0) {
const { distributionName, jdkFile, architecture, packageType, checkLatest, setDefault, verifySignature, verifySignaturePublicKey, toolchainIds } = options;
const installerOptions = {

View File

@@ -330,7 +330,7 @@ In this example, `JAVA_HOME` and `java` on `PATH` point to Java 17, while Java 2
If your use-case requires a custom distribution or a version that is not provided by setup-java, you can download it manually and setup-java will take care of the installation and caching on the VM:
> [!NOTE]
> This approach also lets you use builds that setup-java does not provide directly, such as **Early Access (EA)** or other unreleased JDK builds (for example, an upcoming feature release or a Loom/Valhalla preview build). Download the desired archive in a prior step and point `jdkFile` at it; setup-java will extract, install, and cache it just like a supported distribution. When targeting multiple architectures, select the correct binary per architecture in your workflow (for example, with a build matrix).
> This approach also lets you use builds that setup-java does not provide directly, such as **Early Access (EA)** or other unreleased JDK builds (for example, an upcoming feature release or a Loom/Valhalla preview build). Download the desired archive in a prior step and point `jdk-file` at it; setup-java will extract, install, and cache it just like a supported distribution. When targeting multiple architectures, select the correct binary per architecture in your workflow (for example, with a build matrix).
```yaml
steps:
@@ -340,7 +340,7 @@ steps:
- uses: actions/setup-java@v5
with:
distribution: 'jdkfile'
jdkFile: ${{ runner.temp }}/java_package.tar.gz
jdk-file: ${{ runner.temp }}/java_package.tar.gz
java-version: '11.0.0'
architecture: x64
@@ -357,7 +357,7 @@ steps:
- uses: actions/setup-java@v5
with:
distribution: 'jdkfile'
jdkFile: ${{ runner.temp }}/java_package.tar.gz
jdk-file: ${{ runner.temp }}/java_package.tar.gz
java-version: '25.0.0-ea.36'
architecture: x64
@@ -383,7 +383,7 @@ If your use-case requires a custom distribution (in the example, alpine-linux is
- uses: actions/setup-java@v5
with:
distribution: 'jdkfile'
jdkFile: ${{ runner.temp }}/java_package.tar.gz
jdk-file: ${{ runner.temp }}/java_package.tar.gz
java-version: {{ steps.fetch_latest_jdk.outputs.java_version }}
architecture: x64
- run: java --version
@@ -708,7 +708,7 @@ The result is a Toolchain with entries for JDKs 8, 11 and 15. You can even combi
- uses: actions/setup-java@v5
with:
distribution: 'jdkfile'
jdkFile: ${{ runner.temp }}/java_package.tar.gz
jdk-file: ${{ runner.temp }}/java_package.tar.gz
java-version: '1.6'
architecture: x64
```
@@ -725,7 +725,7 @@ Each JDK provider will receive a default `vendor` using the `distribution` input
- uses: actions/setup-java@v5
with:
distribution: 'jdkfile'
jdkFile: ${{ runner.temp }}/java_package.tar.gz
jdk-file: ${{ runner.temp }}/java_package.tar.gz
java-version: '1.6'
architecture: x64
mvn-toolchain-vendor: 'Oracle'
@@ -780,7 +780,27 @@ steps:
Supported files are `.java-version`, `.tool-versions` and `.sdkmanrc`.
* In `.java-version` file, only the version should be specified (e.g., 17.0.7). The `.java-version` file recognizes all variants of the version description according to [jenv](https://github.com/jenv/jenv).
* In `.tool-versions` file, java version should be preceded by the java keyword (e.g., java 17.0.7). The `.tool-versions` file supports version specifications in accordance with [asdf](https://github.com/asdf-vm/asdf) standards, adhering to Semantic Versioning ([semver](https://semver.org/)).
* In `.tool-versions` file, java version should be preceded by the java keyword (e.g., java 17.0.7). The `.tool-versions` file supports version specifications in accordance with [asdf](https://github.com/asdf-vm/asdf) standards, adhering to Semantic Versioning ([semver](https://semver.org/)). When the entry includes an [asdf-java](https://github.com/halcyon/asdf-java) vendor prefix (e.g. `java temurin-17.0.3+7`), setup-java can infer the `distribution` input automatically. Unrecognized vendor prefixes require setting `distribution` explicitly.
Supported asdf-java vendor prefix mappings (packaging variants such as `-jre`, `-musl`, `-openj9`, `-crac`, `-javafx` are collapsed onto the base vendor):
| asdf-java vendor prefix | setup-java distribution |
| ----------------------- | ----------------------- |
| `temurin` | `temurin` |
| `adoptopenjdk` | `temurin` |
| `zulu` | `zulu` |
| `corretto` | `corretto` |
| `liberica` | `liberica` |
| `microsoft` | `microsoft` |
| `semeru`, `ibm` | `semeru` |
| `dragonwell` | `dragonwell` |
| `graalvm`, `oracle-graalvm` | `graalvm` |
| `graalvm-community` | `graalvm-community` |
| `oracle` | `oracle` |
| `sapmachine` | `sapmachine` |
| `kona` | `kona` |
| `jetbrains` | `jetbrains` |
* In `.sdkmanrc` file, java version should be preceded by the `java=` prefix (e.g., `java=17.0.7-tem`). When a recognized SDKMAN distribution suffix is present, setup-java can infer the `distribution` input automatically. Unrecognized suffixes require setting `distribution` explicitly. The `.sdkmanrc` file supports version specifications in accordance with [file format](https://sdkman.io/usage#env-command), see [Sdkman! documentation](https://sdkman.io/jdks) for more information.
Supported SDKMAN suffix mappings:
@@ -816,6 +836,19 @@ steps:
java=17.0.7-tem
```
**Example step using `asdf`** (distribution inferred from `.tool-versions`):
```yml
- name: Setup java
uses: actions/setup-java@v5
with:
java-version-file: '.tool-versions'
```
**Example `.tool-versions`**:
```
java temurin-17.0.7+7
```
Valid entry options (does not apply to `.sdkmanrc`):
```
major versions: 8, 11, 16, 17, 21

View File

@@ -118,6 +118,7 @@ export async function restore(id: string, cacheDependencyPath: string) {
const primaryKey = await computeCacheKey(packageManager, cacheDependencyPath);
core.debug(`primary key is ${primaryKey}`);
core.saveState(STATE_CACHE_PRIMARY_KEY, primaryKey);
core.setOutput(STATE_CACHE_PRIMARY_KEY, primaryKey);
// No "restoreKeys" is set, to start with a clear cache after dependency update (see https://github.com/actions/setup-java/issues/269)
const matchedKey = await cache.restoreCache(packageManager.path, primaryKey);

View File

@@ -4,7 +4,8 @@ export const INPUT_JAVA_VERSION_FILE = 'java-version-file';
export const INPUT_ARCHITECTURE = 'architecture';
export const INPUT_JAVA_PACKAGE = 'java-package';
export const INPUT_DISTRIBUTION = 'distribution';
export const INPUT_JDK_FILE = 'jdkFile';
export const INPUT_JDK_FILE = 'jdk-file';
export const INPUT_JDK_FILE_DEPRECATED = 'jdkFile';
export const INPUT_CHECK_LATEST = 'check-latest';
export const INPUT_SET_DEFAULT = 'set-default';
export const INPUT_VERIFY_SIGNATURE = 'verify-signature';

View File

@@ -22,7 +22,7 @@ async function run() {
const versionFile = core.getInput(constants.INPUT_JAVA_VERSION_FILE);
const architecture = core.getInput(constants.INPUT_ARCHITECTURE);
const packageType = core.getInput(constants.INPUT_JAVA_PACKAGE);
const jdkFile = core.getInput(constants.INPUT_JDK_FILE);
const jdkFile = getJdkFileInput();
const cache = core.getInput(constants.INPUT_CACHE);
const cacheDependencyPath = core.getInput(
constants.INPUT_CACHE_DEPENDENCY_PATH
@@ -134,6 +134,19 @@ async function run() {
run();
function getJdkFileInput(): string {
const jdkFile = core.getInput(constants.INPUT_JDK_FILE);
const deprecatedJdkFile = core.getInput(constants.INPUT_JDK_FILE_DEPRECATED);
if (deprecatedJdkFile) {
core.warning(
`The '${constants.INPUT_JDK_FILE_DEPRECATED}' input is deprecated and may be removed in a future release. Please use '${constants.INPUT_JDK_FILE}' instead.`
);
}
return jdkFile || deprecatedJdkFile;
}
async function installVersion(
version: string,
options: installerInputsOptions,

View File

@@ -149,8 +149,10 @@ export function getVersionFromFileContent(
const versionFileName = getFileName(versionFile);
if (versionFileName == '.tool-versions') {
// Capture an optional asdf-java vendor prefix (e.g. `temurin-`, `corretto-`)
// in the `distribution` group so it can be mapped to a setup-java distribution.
javaVersionRegExp =
/^java\s+(?:\S*-)?(?<version>\d+(?:\.\d+)*([+_.-](?:openj9[-._]?\d[\w.-]*|java\d+|jre[-_\w]*|OpenJDK\d+[\w_.-]*|[a-z0-9]+))*)/im;
/^java\s+(?:(?<distribution>\S*)-)?(?<version>\d+(?:\.\d+)*([+_.-](?:openj9[-._]?\d[\w.-]*|java\d+|jre[-_\w]*|OpenJDK\d+[\w_.-]*|[a-z0-9]+))*)/im;
} else if (versionFileName == '.sdkmanrc') {
// Match both version and optional distribution identifier
javaVersionRegExp =
@@ -173,6 +175,17 @@ export function getVersionFromFileContent(
);
}
// Extract distribution from asdf .tool-versions file
if (versionFileName == '.tool-versions' && match?.groups?.distribution) {
const asdfDist = match.groups.distribution;
extractedDistribution = mapAsdfDistribution(asdfDist);
if (extractedDistribution) {
core.debug(
`Parsed distribution '${extractedDistribution}' from asdf identifier '${asdfDist}'`
);
}
}
core.debug(
`Parsed version '${capturedVersion}' from file '${versionFileName}'`
);
@@ -238,6 +251,49 @@ function mapSdkmanDistribution(sdkmanDist: string): string | undefined {
return mapped;
}
// Map asdf-java (.tool-versions) vendor identifiers to setup-java distribution names.
// asdf-java encodes the vendor as a prefix on the version string, e.g.
// `java temurin-17.0.3+7` or `java semeru-openj9-11.0.25+9`. Packaging variants
// (`-jre`, `-musl`, `-openj9`, `-crac`, `-javafx`, ...) are collapsed onto the
// base vendor since setup-java does not distinguish them here.
function mapAsdfDistribution(asdfDist: string): string | undefined {
const normalized = asdfDist.toLowerCase();
// Multi-segment vendors that map to a distinct setup-java distribution.
if (normalized.startsWith('graalvm-community')) {
return 'graalvm-community';
}
if (normalized.startsWith('oracle-graalvm')) {
return 'graalvm';
}
const baseVendor = normalized.split('-')[0];
const distributionMap: Record<string, string> = {
temurin: 'temurin',
adoptopenjdk: 'temurin',
zulu: 'zulu',
corretto: 'corretto',
liberica: 'liberica',
microsoft: 'microsoft',
semeru: 'semeru',
ibm: 'semeru',
dragonwell: 'dragonwell',
graalvm: 'graalvm',
oracle: 'oracle',
sapmachine: 'sapmachine',
kona: 'kona',
jetbrains: 'jetbrains'
};
const mapped = distributionMap[baseVendor];
if (!mapped) {
core.warning(
`Unknown asdf distribution identifier '${asdfDist}'. Please specify the distribution explicitly.`
);
}
return mapped;
}
// By convention, action expects version 8 in the format `8.*` instead of `1.8`
function avoidOldNotation(content: string): string {
return content.startsWith('1.') ? content.substring(2) : content;