Compare commits

..
42 Commits
Author SHA1 Message Date
dependabot[bot] f2beeb24e1 Bump actions/publish-action from 0.3.0 to 0.4.0 (#912)
Bumps [actions/publish-action](https://github.com/actions/publish-action) from 0.3.0 to 0.4.0.
- [Commits](https://github.com/actions/publish-action/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: actions/publish-action
  dependency-version: 0.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-03 20:46:45 -06:00
guicamestandmahabaleshwars 4e7e684fbb feat: Add support for .sdkmanrc file in java-version-file parameter (#736)
* chore(e2e-versions): Add e2e test scenario on `setup-java-version-from-file-major-minor-patch-with-dist` for `.sdkmanrc`

* chore(e2e-versions): Update `setup-java-version-from-file-major-minor-patch-with-dist` test to include the file name of the java-version-file that is used

* feat: Add support for `.sdkmanrc` as *Java Version File*

* chore: Add test for the latest known sdkman java versions

* docs(advanced-usage): Document support for `.sdkmanrc` as java-version-file

* chore(docs): Anyone can contribute and maintain 🤷

* Update advanced-usage.md

Add example step/file for `.sdkmanrc`

* Update advanced-usage.md

* Update util.ts

* chore: format and rebuild

* chore: untouch toolchains.ts

* fix check dist error

---------

Co-authored-by: mahabaleshwars <147705296+mahabaleshwars@users.noreply.github.com>
2025-11-25 13:36:29 -06:00
mahabaleshwars 46c56d6f92 Add GitHub Token Support for GraalVM and Refactor Code (#849)
* Code updated to let code accept github token and refactored the code.

* github token accept through environment variable

* fix test error

* audit fix commit

* update package-lock.json

* Update GraalVM Tests

* Lint Issue Resolve

* Update Test case for Windows

* update with enhance code and test
2025-11-18 12:04:23 -06:00
Christoph Langer 66b945764b Update SapMachine URLs (#955) 2025-11-17 10:33:06 -06:00
priya-kinthali 6ba5449b7d Enhance error logging for network failures to include endpoint/IP details, add retry mechanism and update workflows to use macos-15-intel (#946)
* enhance error logging and implement retry

* Replace macos-13 with macos-15-intel

* refactored code based on Copilot suggestions
2025-11-13 13:34:50 -06:00
the-mod de5a937a1d adds microsoft openjdk25 builds (#927)
* adds microsoft java 25 build

adds microsoft java 25 build

* tests and formatting

* Add Microsoft distribution for version 25 on multiple OS
2025-10-27 15:17:49 -05:00
aparnajyothi-y ead9eaa3cf Update Regex to Support All ASDF Versions for the supported distributions in tool-versions File (#767)
* Regex update to fix #719

* Check failures fix

* npm run format, npm run format-check & npm run build

* Regex update

* regex update

* fixed check failures

* updated regex

* regex update for all the versions

* regex and docmentation update

* Regex update

* format and doc update

* doc format update

* npm audit fix

* resolve conflicts

* resolve conflicts

* resolve conflicts

* doc update

* Java version upgrade
2025-09-16 13:23:22 -05:00
Chiranjib Swain 8c57fa3627 Clarify JAVA_HOME and PATH setup in README (#841)
* Update README to clarify JAVA_HOME and PATH setup

* Clarify instructions for setting up multiple JDKs in README
2025-09-16 13:19:02 -05:00
dependabot[bot]andAparna Jyothi a7ab372554 Bump prettier from 2.8.8 to 3.6.2 (#873)
* Bump prettier from 2.8.8 to 3.6.2

Bumps [prettier](https://github.com/prettier/prettier) from 2.8.8 to 3.6.2.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.8.8...3.6.2)

---
updated-dependencies:
- dependency-name: prettier
  dependency-version: 3.6.2
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* doc update and check failure fix

* npm run format-check

* doc format update

* doc update

* doc update

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>
2025-09-09 10:02:46 -05:00
lmvysakhandlmvysakh d0351b4837 Update documentation to use checkout and Java v5 (#903)
Co-authored-by: lmvysakh <lmvysakh@github.com>
2025-09-03 14:04:05 -05:00
dependabot[bot] dded088883 Bump actions/checkout from 4 to 5 (#896)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-20 21:56:38 -05:00
0913e9a06e Upgrade to node 24 (#888)
* Upgrade to node 24

Upgrading action to node 24 since new runner version.

* fix tests

* Fix tests and licences

* format

* format x2

* Upgrade Node.js version in workflow files to 24.x

* check failure fix

* check failures fix

* Fix mock platform

---------

Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>
Co-authored-by: Haritha <73516759+HarithaVattikuti@users.noreply.github.com>
2025-08-20 14:07:47 -05:00
gowridurgadand“gowridurgad” e9343db97e Bumps form-data (#887)
Co-authored-by: “gowridurgad” <“hgowridurgad@github.com>
2025-07-30 14:34:56 -05:00
dependabot[bot]andHarithaVattikuti ae2b61dbc6 Bump undici from 5.28.5 to 5.29.0 (#833)
* Bump undici from 5.28.5 to 5.29.0

Bumps [undici](https://github.com/nodejs/undici) from 5.28.5 to 5.29.0.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v5.28.5...v5.29.0)

---
updated-dependencies:
- dependency-name: undici
  dependency-version: 5.29.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fix CI failures

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: HarithaVattikuti <73516759+HarithaVattikuti@users.noreply.github.com>
2025-07-15 12:32:37 -05:00
dependabot[bot]andHarithaVattikuti c190c18feb Bump eslint-plugin-jest from 27.9.0 to 29.0.1 (#730)
* Bump eslint-plugin-jest from 27.9.0 to 29.0.1

Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 27.9.0 to 28.11.0.
- [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases)
- [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v27.9.0...v28.11.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-jest
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fix failures

* Fix lint error

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: HarithaVattikuti <73516759+HarithaVattikuti@users.noreply.github.com>
2025-07-07 13:51:25 -05:00
Priya Gupta 67aec007b3 Fix: prevent default installation of JetBrains pre-releases (#859)
* fix: prevent default installation of JetBrains pre-releases

* simplify prerelease filter logic

* fix basic validation checks
2025-07-03 12:03:51 -05:00
gowridurgadand“gowridurgad” ebb356cc4e Improve Error Handling for Setup-Java Action to Help Debug Intermittent Failures (#848)
* error-handling

* Logic update

---------

Co-authored-by: “gowridurgad” <“hgowridurgad@github.com>
2025-06-23 12:32:03 -05:00
Haritha f4f1212c88 Update publish-immutable-actions.yml (#798) 2025-04-16 11:13:56 -05:00
aparnajyothi-y c5195efecf actions/cache upgrade to 4.0.3 (#773) 2025-04-08 09:20:46 -05:00
dependabot[bot]andAparna Jyothi dd38875f93 Bump ts-jest from 29.1.2 to 29.2.5 (#743)
* Bump ts-jest from 29.1.2 to 29.2.5

Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.1.2 to 29.2.5.
- [Release notes](https://github.com/kulshekhar/ts-jest/releases)
- [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.1.2...v29.2.5)

---
updated-dependencies:
- dependency-name: ts-jest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* check failures fix

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>
2025-04-08 09:19:01 -05:00
dependabot[bot]andAparna Jyothi 148017a9b0 Bump @actions/glob from 0.4.0 to 0.5.0 (#744)
* Bump @actions/glob from 0.4.0 to 0.5.0

Bumps [@actions/glob](https://github.com/actions/toolkit/tree/HEAD/packages/glob) from 0.4.0 to 0.5.0.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/glob/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/glob)

---
updated-dependencies:
- dependency-name: "@actions/glob"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* check failures fix

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>
2025-04-01 12:02:03 -05:00
Marcono1234 3b6c050358 Remove duplicated GraalVM section in documentation (#716) 2025-03-25 18:33:29 -05:00
aparnajyothi-y b8ebb8ba1d upgrade @action/cache from 4.0.0 to 4.0.2 (#766)
* actions/cache upgrade to 4.0.2

* check failures fix

* fix for licensed check failure
2025-03-19 13:20:08 -05:00
aparnajyothi-y 799ee7c97e Add Documentation to Recommend Using GraalVM JDK 17 Version to 17.0.12 to Align with GFTC License Terms (#704)
* Update the graalvm documentation

* update the documentation
2025-03-03 16:27:48 -06:00
dependabot[bot]andAparna Jyothi 3a4f6e1af5 Bump @types/jest from 29.5.12 to 29.5.14 (#729)
* Bump @types/jest from 29.5.12 to 29.5.14

Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 29.5.12 to 29.5.14.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

---
updated-dependencies:
- dependency-name: "@types/jest"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix for check failures

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>
2025-01-28 10:20:39 -06:00
dependabot[bot] 25f376e348 Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 (#727)
Bumps [actions/publish-immutable-action](https://github.com/actions/publish-immutable-action) from 0.0.3 to 0.0.4.
- [Release notes](https://github.com/actions/publish-immutable-action/releases)
- [Commits](https://github.com/actions/publish-immutable-action/compare/0.0.3...v0.0.4)

---
updated-dependencies:
- dependency-name: actions/publish-immutable-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-28 09:29:04 -06:00
dependabot[bot]andAparna Jyothi d4e4b6bbc1 Bump @actions/http-client from 2.2.1 to 2.2.3 (#728)
* Bump @actions/http-client from 2.2.1 to 2.2.3

Bumps [@actions/http-client](https://github.com/actions/toolkit/tree/HEAD/packages/http-client) from 2.2.1 to 2.2.3.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/http-client/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/http-client)

---
updated-dependencies:
- dependency-name: "@actions/http-client"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix for check-dist and license failures

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>
2025-01-28 09:27:56 -06:00
HarithaVattikuti 28b532bcb3 Create dependabot.yml (#722) 2025-01-21 16:15:18 -06:00
aparnajyothi-y 51ab6d2e30 Update cache from 3.2.4 to 4.0.0 (#724)
* update package-lock.json

* licensed update and cache upgrade

* cache upgrade
2025-01-16 16:05:15 -06:00
Ben Wells 99d3141d9b Update README.md (#723) 2025-01-16 08:49:13 -06:00
Gregory Mitchell 7a6d8a8234 Add Support for JetBrains Runtime (#637)
* Add Support for JetBrains Runtime

- Add Installer, Models
- Includes Tests & Test Manifest Data
- Add to `e2e-versions.yml`
- Run `npm run build`
- Update README.md

* Add Docs + Distro Factory

* Fix Runtime Unrecognizable

* `npm run build` (JBR)

* Fix Incorrect JBR Distribution

* Switch to `jbrsdk_jcef`

* Fix Incorrect File Extension

* `npm run build` (JBR)

* Fix Windows Support

* Add `GITHUB_TOKEN` Authentication

* Update Authorization, Add Documentation

* Fix PR Issues

- Fix JDK 11 URL Bug
- Add JDK URL Testing to ensure versions can be downloaded
- Run Prettier

* Change Distribution to \`jbrsdk\`

* Don't Replace Underscores

* Fix `semver` not resolving correctly

* Update e2e-versions.yml

- Add `GITHUB_TOKEN` environment variable for JetBrains requests
- Add `jetbrains` to other E2E tests

* `npm run format`

* Fix Format, Inaccessible URLs

* Update Tests

* Fix Broken URLs, Add Additional Package Types

* `npm run build`

* Fix JetBrains Tests, Issues in `e2e-versions.yml`

* Add Hidden JDK 11 Versions

* Update `jetbrains-installer` Tests

* Add Notices in Documentation

* Fix Documentation

* Run `npm audit fix`

* Fix Tests on Windows
2024-12-12 16:21:52 -06:00
mahabaleshwars 7136edc5e8 Fix sbt and x86 CI failures on Ubuntu-24 (#693)
* updated workflows with ubuntu 24.04 runner

* added workflow_dispatch to test workflows

* updated workflow to ubnutu 22.04

* Updated workflows for PR

* workflows updated to ubuntu-latest

* Audit fixes
2024-12-10 22:04:58 -06:00
John Wesley Walker III 8df1039502 Refine isGhes logic (#697) 2024-10-21 19:57:52 +02:00
mahabaleshwars 870c199c48 Update workflows for GraalVM and Version Enhancements (#699)
* workflow update graalvm version

* updated workflow for publish action version update
2024-10-21 11:43:20 -05:00
Priya Gupta 83a06ff9d9 Fix Windows archives extraction issue (#689) 2024-10-10 16:32:25 -05:00
Joel Ambass 292cc14be8 Merge pull request #686 from actions/Jcambass-patch-1
Upgrade IA Publish
2024-09-26 08:24:15 +02:00
aparnajyothi-y b36c23c0d9 check-dist-failure-fix (#687) 2024-09-23 11:07:17 -05:00
Zxilly 40b9536ce5 fix: add arch to cache key (#664) 2024-09-19 08:51:30 -05:00
Fabio Niephaus 0a40ce6f61 Add support for Oracle GraalVM (#501)
* Add support for Oracle GraalVM

* Add support for EA builds of Oracle GraalVM
2024-09-18 10:17:11 -05:00
Joel Ambass 68b1d5a3da Upgrade IA Publish 2024-09-16 17:19:52 +02:00
Joel Ambass bcfbca5b71 Merge pull request #684 from actions/Jcambass-patch-1
Add workflow file for publishing releases to immutable action package
2024-09-11 09:54:38 +02:00
Joel Ambass 78eae7945c Add workflow file for publishing releases to immutable action package
This workflow file publishes new action releases to the immutable action package of the same name as this repo.

This is part of the Immutable Actions project which is not yet fully released to the public. First party actions like this one are part of our initial testing of this feature.
2024-09-11 09:48:56 +02:00
92 changed files with 21610 additions and 4842 deletions
+22
View File
@@ -0,0 +1,22 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
# Enable version updates for npm
- package-ecosystem: 'npm'
# Look for `package.json` and `lock` files in the `root` directory
directory: '/'
# Check the npm registry for updates every day (weekdays)
schedule:
interval: 'weekly'
# Enable version updates for GitHub Actions
- package-ecosystem: 'github-actions'
# Workflow files stored in the default location of `.github/workflows`
# You don't need to specify `/.github/workflows` for `directory`. You can use `directory: "/"`.
directory: '/'
schedule:
interval: 'weekly'
+1 -1
View File
@@ -16,4 +16,4 @@ jobs:
name: Basic validation
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
with:
node-version: '20.x'
node-version: '24.x'
+1 -1
View File
@@ -16,4 +16,4 @@ jobs:
name: Check dist/
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
with:
node-version: '20.x'
node-version: '24.x'
@@ -24,13 +24,13 @@ jobs:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Run setup-java with the cache for gradle
uses: ./
id: setup-java
with:
distribution: 'adopt'
java-version: '11'
java-version: '17'
cache: gradle
cache-dependency-path: __tests__/cache/gradle1/*.gradle*
- name: Create files to cache
@@ -51,7 +51,7 @@ jobs:
needs: gradle1-save
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Run setup-java with the cache for gradle
uses: ./
id: setup-java
@@ -76,7 +76,7 @@ jobs:
needs: gradle1-save
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Run setup-java with the cache for gradle
uses: ./
id: setup-java
+16 -16
View File
@@ -21,16 +21,16 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-13, windows-latest, ubuntu-latest]
os: [macos-15-intel, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Run setup-java with the cache for gradle
uses: ./
id: setup-java
with:
distribution: 'adopt'
java-version: '11'
java-version: '17'
cache: gradle
- name: Create files to cache
# Need to avoid using Gradle daemon to stabilize the save process on Windows
@@ -46,11 +46,11 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-13, windows-latest, ubuntu-latest]
os: [macos-15-intel, windows-latest, ubuntu-latest]
needs: gradle-save
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Run setup-java with the cache for gradle
uses: ./
id: setup-java
@@ -70,10 +70,10 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-13, windows-latest, ubuntu-latest]
os: [macos-15-intel, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Run setup-java with the cache for maven
uses: ./
id: setup-java
@@ -93,11 +93,11 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-13, windows-latest, ubuntu-latest]
os: [macos-15-intel, windows-latest, ubuntu-latest]
needs: maven-save
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Run setup-java with the cache for maven
uses: ./
id: setup-java
@@ -121,10 +121,10 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-13, windows-latest, ubuntu-latest]
os: [macos-15-intel, windows-latest, ubuntu-22.04]
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Run setup-java with the cache for sbt
uses: ./
id: setup-java
@@ -133,7 +133,7 @@ jobs:
java-version: '11'
cache: sbt
- name: Setup SBT
if: matrix.os == 'macos-13'
if: matrix.os == 'macos-15-intel'
run: |
echo ""Installing SBT...""
brew install sbt
@@ -141,7 +141,7 @@ jobs:
run: sbt update
- name: Check files to cache on macos-latest
if: matrix.os == 'macos-13'
if: matrix.os == 'macos-15-intel'
run: |
if [ ! -d ~/Library/Caches/Coursier ]; then
echo "::error::The ~/Library/Caches/Coursier directory does not exist unexpectedly"
@@ -170,11 +170,11 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-13, windows-latest, ubuntu-latest]
os: [macos-15-intel, windows-latest, ubuntu-22.04]
needs: sbt-save
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Run setup-java with the cache for sbt
uses: ./
id: setup-java
@@ -184,7 +184,7 @@ jobs:
cache: sbt
- name: Confirm that ~/Library/Caches/Coursier directory has been made
if: matrix.os == 'macos-13'
if: matrix.os == 'macos-15-intel'
run: |
if [ ! -d ~/Library/Caches/Coursier ]; then
echo "::error::The ~/Library/Caches/Coursier directory does not exist unexpectedly"
+3 -3
View File
@@ -21,7 +21,7 @@ jobs:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Download Adopt OpenJDK file
run: |
if ($IsLinux) {
@@ -58,7 +58,7 @@ jobs:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Download Zulu OpenJDK file
run: |
if ($IsLinux) {
@@ -95,7 +95,7 @@ jobs:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Download Eclipse Temurin file
run: |
if ($IsLinux) {
+4 -4
View File
@@ -25,7 +25,7 @@ jobs:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: setup-java
uses: ./
id: setup-java
@@ -60,7 +60,7 @@ jobs:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Create fake settings.xml
run: |
$xmlDirectory = Join-Path $HOME ".m2"
@@ -96,7 +96,7 @@ jobs:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Create fake settings.xml
run: |
$xmlDirectory = Join-Path $HOME ".m2"
@@ -133,7 +133,7 @@ jobs:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: setup-java
uses: ./
id: setup-java
+128 -29
View File
@@ -20,7 +20,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-13, windows-latest, ubuntu-latest]
os: [macos-15-intel, windows-latest, ubuntu-latest]
distribution: [
'temurin',
'adopt',
@@ -31,34 +31,57 @@ jobs:
'semeru',
'corretto',
'dragonwell',
'sapmachine'
'sapmachine',
'jetbrains'
] # internally 'adopt-hotspot' is the same as 'adopt'
version: ['21', '11', '17']
exclude:
- distribution: microsoft
version: 8
- distribution: dragonwell
os: macos-13
os: macos-15-intel
include:
- distribution: microsoft
os: windows-latest
version: 25
- distribution: microsoft
os: ubuntu-latest
version: 25
- distribution: microsoft
os: macos-latest
version: 25
- distribution: oracle
os: macos-13
os: macos-15-intel
version: 17
- distribution: oracle
os: windows-latest
version: 20
version: 21
- distribution: oracle
os: ubuntu-latest
version: 20
version: 21
- distribution: graalvm
os: macos-latest
version: 17.0.12
- distribution: graalvm
os: windows-latest
version: 21
- distribution: graalvm
os: ubuntu-latest
version: 21
- distribution: graalvm
os: ubuntu-latest
version: '24-ea'
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: setup-java
uses: ./
id: setup-java
with:
java-version: ${{ matrix.version }}
distribution: ${{ matrix.distribution }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Verify Java
run: bash __tests__/verify-java.sh "${{ matrix.version }}" "${{ steps.setup-java.outputs.path }}"
shell: bash
@@ -79,7 +102,10 @@ jobs:
include:
- distribution: oracle
os: ubuntu-latest
version: '20.0.1'
version: '21.0.4'
- distribution: graalvm
os: ubuntu-latest
version: '21.0.4'
- distribution: dragonwell
os: ubuntu-latest
version: '11.0'
@@ -89,9 +115,15 @@ jobs:
- distribution: sapmachine
os: ubuntu-latest
version: '17.0.7'
- distribution: jetbrains
os: ubuntu-latest
version: '11.0.11'
- distribution: jetbrains
os: ubuntu-latest
version: '17.0.7'
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: setup-java
uses: ./
id: setup-java
@@ -101,6 +133,8 @@ jobs:
- name: Verify Java
run: bash __tests__/verify-java.sh "${{ matrix.version }}" "${{ steps.setup-java.outputs.path }}"
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
setup-java-check-latest:
name: ${{ matrix.distribution }} ${{ matrix.version }} - check-latest flag - ${{ matrix.os }}
@@ -111,13 +145,20 @@ jobs:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
distribution:
['temurin', 'zulu', 'liberica', 'dragonwell', 'sapmachine']
[
'temurin',
'zulu',
'liberica',
'dragonwell',
'sapmachine',
'jetbrains'
]
exclude:
- distribution: dragonwell
os: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: setup-java
uses: ./
id: setup-java
@@ -125,6 +166,8 @@ jobs:
distribution: ${{ matrix.distribution }}
java-version: 11
check-latest: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Verify Java
run: bash __tests__/verify-java.sh "11" "${{ steps.setup-java.outputs.path }}"
shell: bash
@@ -138,13 +181,20 @@ jobs:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
distribution:
['temurin', 'zulu', 'liberica', 'dragonwell', 'sapmachine']
[
'temurin',
'zulu',
'liberica',
'dragonwell',
'sapmachine',
'jetbrains'
]
exclude:
- distribution: dragonwell
os: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: setup-java
uses: ./
id: setup-java
@@ -153,6 +203,8 @@ jobs:
java-version: |
11
17
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Verify Java env variables
run: |
$versionsArr = "11","17"
@@ -177,11 +229,11 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-13, windows-latest, ubuntu-latest]
os: [macos-15-intel, windows-latest, ubuntu-latest]
version: ['17-ea', '15.0.0-ea.14']
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: setup-java
uses: ./
id: setup-java
@@ -203,7 +255,7 @@ jobs:
version: ['17-ea']
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: setup-java
uses: ./
id: setup-java
@@ -225,7 +277,7 @@ jobs:
version: ['17-ea', '21-ea']
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: setup-java
uses: ./
id: setup-java
@@ -243,8 +295,9 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-13, windows-latest, ubuntu-latest]
distribution: ['temurin', 'zulu', 'liberica', 'semeru', 'sapmachine']
os: [macos-15-intel, windows-latest, ubuntu-latest]
distribution:
['temurin', 'zulu', 'liberica', 'semeru', 'sapmachine', 'jetbrains']
java-package: ['jre']
version: ['17.0']
include:
@@ -268,9 +321,50 @@ jobs:
java-package: jre
version: '8'
os: windows-latest
- distribution: 'jetbrains'
java-package: jdk+jcef
version: '11'
os: ubuntu-latest
- distribution: 'jetbrains'
java-package: jdk+jcef
version: '17'
os: ubuntu-latest
- distribution: 'jetbrains'
java-package: jdk+jcef
version: '21'
os: ubuntu-latest
- distribution: 'jetbrains'
java-package: jre+jcef
version: '11'
os: ubuntu-latest
- distribution: 'jetbrains'
java-package: jre+jcef
version: '17'
os: ubuntu-latest
- distribution: 'jetbrains'
java-package: jre+jcef
version: '21'
os: ubuntu-latest
- distribution: 'jetbrains'
java-package: jdk+ft
version: '17'
os: ubuntu-latest
- distribution: 'jetbrains'
java-package: jdk+ft
version: '21'
os: ubuntu-latest
- distribution: 'jetbrains'
java-package: jre+ft
version: '17'
os: ubuntu-latest
- distribution: 'jetbrains'
java-package: jre+ft
version: '21'
os: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: setup-java
uses: ./
id: setup-java
@@ -278,6 +372,8 @@ jobs:
java-version: ${{ matrix.version }}
java-package: ${{ matrix.java-package }}
distribution: ${{ matrix.distribution }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Verify Java
run: bash __tests__/verify-java.sh "${{ matrix.version }}" "${{ steps.setup-java.outputs.path }}"
shell: bash
@@ -291,12 +387,12 @@ jobs:
fail-fast: false
matrix:
# x86 is not supported on macOS
os: [windows-latest, ubuntu-latest]
os: [windows-latest, ubuntu-22.04]
distribution: ['liberica', 'zulu', 'corretto']
version: ['11']
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: setup-java
uses: ./
id: setup-java
@@ -319,7 +415,7 @@ jobs:
java-version-file: ['.java-version', '.tool-versions']
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Create .java-version file
shell: bash
run: echo "17" > .java-version
@@ -348,7 +444,7 @@ jobs:
java-version-file: ['.java-version', '.tool-versions']
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Create .java-version file
shell: bash
run: echo "11" > .java-version
@@ -376,7 +472,7 @@ jobs:
java-version-file: ['.java-version', '.tool-versions']
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Create .java-version file
shell: bash
run: echo "17.0.10" > .java-version
@@ -394,23 +490,26 @@ jobs:
shell: bash
setup-java-version-from-file-major-minor-patch-with-dist:
name: ${{ matrix.distribution }} version from file 'openjdk64-17.0.10' - ${{ matrix.os }}
name: ${{ matrix.distribution }} version from file '${{ matrix.java-version-file }}' - ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['adopt', 'zulu', 'liberica']
java-version-file: ['.java-version', '.tool-versions']
java-version-file: ['.java-version', '.tool-versions', '.sdkmanrc']
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Create .java-version file
shell: bash
run: echo "openjdk64-17.0.10" > .java-version
- name: Create .tool-versions file
shell: bash
run: echo "java openjdk64-17.0.10" > .tool-versions
- name: Create .sdkmanrc file
shell: bash
run: echo "java=17.0.10-tem" > .sdkmanrc
- name: setup-java
uses: ./
id: setup-java
@@ -0,0 +1,21 @@
name: 'Publish Immutable Action Version'
on:
release:
types: [released]
workflow_dispatch:
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
packages: write
steps:
- name: Checking out
uses: actions/checkout@v5
- name: Publish
id: publish
uses: actions/publish-immutable-action@v0.0.4
@@ -23,7 +23,7 @@ jobs:
steps:
- name: Update the ${{ env.TAG_NAME }} tag
id: update-major-tag
uses: actions/publish-action@v0.2.2
uses: actions/publish-action@v0.4.0
with:
source-tag: ${{ env.TAG_NAME }}
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+41 -18
View File
@@ -18,11 +18,20 @@ The `setup-java` action provides the following functionality for GitHub Actions
This action allows you to work with Java and Scala projects.
## Breaking changes in V5
- Upgraded action from node20 to node24
> Make sure your runner is on version v2.327.1 or later to ensure compatibility with this release [Release Notes](https://github.com/actions/runner/releases/tag/v2.327.1)
For more details, see the full release notes on the [releases page](https://github.com/actions/setup-java/releases/tag/v5.0.0)
## V2 vs V1
- V2 supports custom distributions and provides support for Azul Zulu OpenJDK, Eclipse Temurin and AdoptOpenJDK out of the box. V1 supports only Azul Zulu OpenJDK.
- V2 requires you to specify distribution along with the version. V1 defaults to Azul Zulu OpenJDK, only version input is required. Follow [the migration guide](docs/switching-to-v2.md) to switch from V1 to V2.
For information about the latest releases, recent updates, and newly supported distributions, please refer to the `setup-java` [Releases](https://github.com/actions/setup-java/releases).
## Usage
- `java-version`: The Java version that is going to be set up. Takes a whole or [semver](#supported-version-syntax) Java version. If not specified, the action will expect `java-version-file` input to be specified.
@@ -69,8 +78,8 @@ This action allows you to work with Java and Scala projects.
#### Eclipse Temurin
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'temurin' # See 'Supported distributions' for available options
java-version: '21'
@@ -80,8 +89,8 @@ steps:
#### Azul Zulu OpenJDK
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'zulu' # See 'Supported distributions' for available options
java-version: '21'
@@ -109,6 +118,8 @@ Currently, the following distributions are supported:
| `oracle` | Oracle JDK | [Link](https://www.oracle.com/java/technologies/downloads/) | [Link](https://java.com/freeuselicense)
| `dragonwell` | Alibaba Dragonwell JDK | [Link](https://dragonwell-jdk.io/) | [Link](https://www.aliyun.com/product/dragonwell/)
| `sapmachine` | SAP SapMachine JDK/JRE | [Link](https://sapmachine.io/) | [Link](https://github.com/SAP/SapMachine/blob/sapmachine/LICENSE)
| `graalvm` | Oracle GraalVM | [Link](https://www.graalvm.org/) | [Link](https://www.oracle.com/downloads/licenses/graal-free-license.html)
| `jetbrains` | JetBrains Runtime | [Link](https://github.com/JetBrains/JetBrainsRuntime/) | [Link](https://github.com/JetBrains/JetBrainsRuntime/blob/main/LICENSE)
**NOTE:** The different distributors can provide discrepant list of available versions / supported configurations. Please refer to the official documentation to see the list of supported versions.
@@ -116,6 +127,8 @@ Currently, the following distributions are supported:
**NOTE:** For Azul Zulu OpenJDK architectures x64 and arm64 are mapped to x86 / arm with proper hw_bitness.
**NOTE:** To comply with the GraalVM Free Terms and Conditions (GFTC) license, it is recommended to use GraalVM JDK 17 version 17.0.12, as this is the only version of GraalVM JDK 17 available under the GFTC license. Additionally, it is encouraged to consider upgrading to GraalVM JDK 21, which offers the latest features and improvements.
### Caching packages dependencies
The action has a built-in functionality for caching and restoring dependencies. It uses [toolkit/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under hood for caching dependencies but requires less configuration settings. Supported package managers are gradle, maven and sbt. The format of the used cache key is `setup-java-${{ platform }}-${{ packageManager }}-${{ fileHash }}`, where the hash is based on the following files:
@@ -132,8 +145,8 @@ The cache input is optional, and caching is turned off by default.
#### Caching gradle dependencies
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '21'
@@ -147,8 +160,8 @@ steps:
#### Caching maven dependencies
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '21'
@@ -161,8 +174,8 @@ steps:
#### Caching sbt dependencies
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '21'
@@ -181,8 +194,8 @@ Usually, cache gets downloaded in multiple segments of fixed sizes. Sometimes, a
env:
SEGMENT_DOWNLOAD_TIMEOUT_MINS: '5'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '21'
@@ -201,8 +214,8 @@ For Java distributions that are not cached on Hosted images, `check-latest` alwa
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '21'
@@ -220,9 +233,9 @@ jobs:
java: [ '8', '11', '17', '21' ]
name: Java ${{ matrix.Java }} sample
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Setup java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: '<distribution>'
java-version: ${{ matrix.java }}
@@ -231,11 +244,11 @@ jobs:
### Install multiple JDKs
All versions are added to the PATH. The last version will be used and available globally. Other Java versions can be accessed through env variables with such specification as 'JAVA_HOME_{{ MAJOR_VERSION }}_{{ ARCHITECTURE }}'.
All configured Java versions are added to the PATH. The last one added to the PATH (i.e., the last JDK set up by this action) will be used as the default and available globally. Other Java versions can be accessed through environment variables such as 'JAVA_HOME_{{ MAJOR_VERSION }}_{{ ARCHITECTURE }}'. To use a specific Java version, set the JAVA_HOME environment variable accordingly and prepend its bin directory to the PATH to ensure it takes priority during execution.
```yaml
steps:
- uses: actions/setup-java@v4
- uses: actions/setup-java@v5
with:
distribution: '<distribution>'
java-version: |
@@ -259,6 +272,7 @@ In the example above multiple JDKs are installed for the same job. The result af
- [Oracle](docs/advanced-usage.md#Oracle)
- [Alibaba Dragonwell](docs/advanced-usage.md#Alibaba-Dragonwell)
- [SapMachine](docs/advanced-usage.md#SapMachine)
- [GraalVM](docs/advanced-usage.md#GraalVM)
- [Installing custom Java package type](docs/advanced-usage.md#Installing-custom-Java-package-type)
- [Installing custom Java architecture](docs/advanced-usage.md#Installing-custom-Java-architecture)
- [Installing custom Java distribution from local file](docs/advanced-usage.md#Installing-Java-from-local-file)
@@ -270,6 +284,15 @@ In the example above multiple JDKs are installed for the same job. The result af
- [Modifying Maven Toolchains](docs/advanced-usage.md#Modifying-Maven-Toolchains)
- [Java Version File](docs/advanced-usage.md#Java-version-file)
## Recommended permissions
When using the `setup-java` action in your GitHub Actions workflow, it is recommended to set the following permissions to ensure proper functionality:
```yaml
permissions:
contents: read # access to check out code and install dependencies
```
## License
The scripts and documentation in this project are released under the [MIT License](LICENSE).
File diff suppressed because it is too large Load Diff
+43
View File
@@ -1,4 +1,47 @@
[
{
"version": "25.0.0",
"stable": true,
"release_url": "https://aka.ms/download-jdk",
"files": [
{
"filename": "microsoft-jdk-25.0.0-macos-x64.tar.gz",
"arch": "x64",
"platform": "darwin",
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-25.0.0-macos-x64.tar.gz"
},
{
"filename": "microsoft-jdk-25.0.0-linux-x64.tar.gz",
"arch": "x64",
"platform": "linux",
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-25.0.0-linux-x64.tar.gz"
},
{
"filename": "microsoft-jdk-25.0.0-windows-x64.zip",
"arch": "x64",
"platform": "win32",
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-25.0.0-windows-x64.zip"
},
{
"filename": "microsoft-jdk-25.0.0-macos-aarch64.tar.gz",
"arch": "aarch64",
"platform": "darwin",
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-25.0.0-macos-aarch64.tar.gz"
},
{
"filename": "microsoft-jdk-25.0.0-linux-aarch64.tar.gz",
"arch": "aarch64",
"platform": "linux",
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-25.0.0-linux-aarch64.tar.gz"
},
{
"filename": "microsoft-jdk-25.0.0-windows-aarch64.zip",
"arch": "aarch64",
"platform": "win32",
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-25.0.0-windows-aarch64.zip"
}
]
},
{
"version": "21.0.0",
"stable": true,
+135
View File
@@ -0,0 +1,135 @@
6.0.119-zulu, 6.0.119
7.0.352-zulu, 7.0.352
8.0.282-trava, 8.0.282
8.0.432-albba, 8.0.432
8.0.432-amzn, 8.0.432
8.0.432-kona, 8.0.432
8.0.432-librca, 8.0.432
8.0.432-sem, 8.0.432
8.0.432-tem, 8.0.432
8.0.432-zulu, 8.0.432
8.0.432.fx-librca, 8.0.432
8.0.432.fx-zulu, 8.0.432
8.0.442-amzn, 8.0.442
8.0.442-librca, 8.0.442
8.0.442-tem, 8.0.442
8.0.442-zulu, 8.0.442
8.0.442.fx-librca, 8.0.442
8.0.442.fx-zulu, 8.0.442
11.0.14.1-jbr, 11.0.14
11.0.15-trava, 11.0.15
11.0.25-albba, 11.0.25
11.0.25-amzn, 11.0.25
11.0.25-kona, 11.0.25
11.0.25-librca, 11.0.25
11.0.25-ms, 11.0.25
11.0.25-sapmchn, 11.0.25
11.0.25-sem, 11.0.25
11.0.25-tem, 11.0.25
11.0.25-zulu, 11.0.25
11.0.25.fx-librca, 11.0.25
11.0.25.fx-zulu, 11.0.25
11.0.26-amzn, 11.0.26
11.0.26-librca, 11.0.26
11.0.26-ms, 11.0.26
11.0.26-sapmchn, 11.0.26
11.0.26-zulu, 11.0.26
11.0.26.fx-librca, 11.0.26
11.0.26.fx-zulu, 11.0.26
17.0.12-graal, 17.0.12
17.0.12-jbr, 17.0.12
17.0.12-oracle, 17.0.12
17.0.13-albba, 17.0.13
17.0.13-amzn, 17.0.13
17.0.13-kona, 17.0.13
17.0.13-librca, 17.0.13
17.0.13-ms, 17.0.13
17.0.13-sapmchn, 17.0.13
17.0.13-sem, 17.0.13
17.0.13-tem, 17.0.13
17.0.13-zulu, 17.0.13
17.0.13.crac-librca, 17.0.13
17.0.13.crac-zulu, 17.0.13
17.0.13.fx-librca, 17.0.13
17.0.13.fx-zulu, 17.0.13
17.0.14-amzn, 17.0.14
17.0.14-librca, 17.0.14
17.0.14-ms, 17.0.14
17.0.14-sapmchn, 17.0.14
17.0.14-zulu, 17.0.14
17.0.14.fx-librca, 17.0.14
17.0.14.fx-zulu, 17.0.14
17.0.9-graalce, 17.0.9
21.0.2-graalce, 21.0.2
21.0.2-open, 21.0.2
21.0.5-amzn, 21.0.5
21.0.5-graal, 21.0.5
21.0.5-jbr, 21.0.5
21.0.5-kona, 21.0.5
21.0.5-librca, 21.0.5
21.0.5-ms, 21.0.5
21.0.5-oracle, 21.0.5
21.0.5-sapmchn, 21.0.5
21.0.5-sem, 21.0.5
21.0.5-tem, 21.0.5
21.0.5-zulu, 21.0.5
21.0.5.crac-librca, 21.0.5
21.0.5.crac-zulu, 21.0.5
21.0.5.fx-librca, 21.0.5
21.0.5.fx-zulu, 21.0.5
21.0.6-amzn, 21.0.6
21.0.6-graal, 21.0.6
21.0.6-librca, 21.0.6
21.0.6-ms, 21.0.6
21.0.6-oracle, 21.0.6
21.0.6-sapmchn, 21.0.6
21.0.6-tem, 21.0.6
21.0.6-zulu, 21.0.6
21.0.6.fx-librca, 21.0.6
21.0.6.fx-zulu, 21.0.6
22.0.2-oracle, 22.0.2
22.1.0.1.r11-gln, 22.1.0
22.1.0.1.r17-gln, 22.1.0
22.3.5.r11-nik, 22.3.5
22.3.5.r17-mandrel, 22.3.5
22.3.5.r17-nik, 22.3.5
23-open, 23
23.0.1-amzn, 23.0.1
23.0.1-graal, 23.0.1
23.0.1-graalce, 23.0.1
23.0.1-librca, 23.0.1
23.0.1-open, 23.0.1
23.0.1-oracle, 23.0.1
23.0.1-sapmchn, 23.0.1
23.0.1-tem, 23.0.1
23.0.1-zulu, 23.0.1
23.0.1.crac-zulu, 23.0.1
23.0.1.fx-librca, 23.0.1
23.0.1.fx-zulu, 23.0.1
23.0.2-amzn, 23.0.2
23.0.2-graal, 23.0.2
23.0.2-graalce, 23.0.2
23.0.2-librca, 23.0.2
23.0.2-oracle, 23.0.2
23.0.2-sapmchn, 23.0.2
23.0.2-tem, 23.0.2
23.0.2-zulu, 23.0.2
23.0.2.fx-librca, 23.0.2
23.0.2.fx-zulu, 23.0.2
23.0.6.fx-nik, 23.0.6
23.0.6.r17-mandrel, 23.0.6
23.0.6.r17-nik, 23.0.6
23.1.5.fx-nik, 23.1.5
23.1.5.r21-mandrel, 23.1.5
23.1.5.r21-nik, 23.1.5
24.0.2.r22-mandrel, 24.0.2
24.ea.27-graal, 24.0.0
24.ea.28-graal, 24.0.0
24.ea.31-open, 24.0.0
24.ea.32-open, 24.0.0
24.1.1.r23-mandrel, 24.1.1
24.1.1.r23-nik, 24.1.1
25.ea.4-graal, 25.0.0
25.ea.5-graal, 25.0.0
25.ea.5-open, 25.0.0
25.ea.6-open, 25.0.0
1 6.0.119-zulu 6.0.119
2 7.0.352-zulu 7.0.352
3 8.0.282-trava 8.0.282
4 8.0.432-albba 8.0.432
5 8.0.432-amzn 8.0.432
6 8.0.432-kona 8.0.432
7 8.0.432-librca 8.0.432
8 8.0.432-sem 8.0.432
9 8.0.432-tem 8.0.432
10 8.0.432-zulu 8.0.432
11 8.0.432.fx-librca 8.0.432
12 8.0.432.fx-zulu 8.0.432
13 8.0.442-amzn 8.0.442
14 8.0.442-librca 8.0.442
15 8.0.442-tem 8.0.442
16 8.0.442-zulu 8.0.442
17 8.0.442.fx-librca 8.0.442
18 8.0.442.fx-zulu 8.0.442
19 11.0.14.1-jbr 11.0.14
20 11.0.15-trava 11.0.15
21 11.0.25-albba 11.0.25
22 11.0.25-amzn 11.0.25
23 11.0.25-kona 11.0.25
24 11.0.25-librca 11.0.25
25 11.0.25-ms 11.0.25
26 11.0.25-sapmchn 11.0.25
27 11.0.25-sem 11.0.25
28 11.0.25-tem 11.0.25
29 11.0.25-zulu 11.0.25
30 11.0.25.fx-librca 11.0.25
31 11.0.25.fx-zulu 11.0.25
32 11.0.26-amzn 11.0.26
33 11.0.26-librca 11.0.26
34 11.0.26-ms 11.0.26
35 11.0.26-sapmchn 11.0.26
36 11.0.26-zulu 11.0.26
37 11.0.26.fx-librca 11.0.26
38 11.0.26.fx-zulu 11.0.26
39 17.0.12-graal 17.0.12
40 17.0.12-jbr 17.0.12
41 17.0.12-oracle 17.0.12
42 17.0.13-albba 17.0.13
43 17.0.13-amzn 17.0.13
44 17.0.13-kona 17.0.13
45 17.0.13-librca 17.0.13
46 17.0.13-ms 17.0.13
47 17.0.13-sapmchn 17.0.13
48 17.0.13-sem 17.0.13
49 17.0.13-tem 17.0.13
50 17.0.13-zulu 17.0.13
51 17.0.13.crac-librca 17.0.13
52 17.0.13.crac-zulu 17.0.13
53 17.0.13.fx-librca 17.0.13
54 17.0.13.fx-zulu 17.0.13
55 17.0.14-amzn 17.0.14
56 17.0.14-librca 17.0.14
57 17.0.14-ms 17.0.14
58 17.0.14-sapmchn 17.0.14
59 17.0.14-zulu 17.0.14
60 17.0.14.fx-librca 17.0.14
61 17.0.14.fx-zulu 17.0.14
62 17.0.9-graalce 17.0.9
63 21.0.2-graalce 21.0.2
64 21.0.2-open 21.0.2
65 21.0.5-amzn 21.0.5
66 21.0.5-graal 21.0.5
67 21.0.5-jbr 21.0.5
68 21.0.5-kona 21.0.5
69 21.0.5-librca 21.0.5
70 21.0.5-ms 21.0.5
71 21.0.5-oracle 21.0.5
72 21.0.5-sapmchn 21.0.5
73 21.0.5-sem 21.0.5
74 21.0.5-tem 21.0.5
75 21.0.5-zulu 21.0.5
76 21.0.5.crac-librca 21.0.5
77 21.0.5.crac-zulu 21.0.5
78 21.0.5.fx-librca 21.0.5
79 21.0.5.fx-zulu 21.0.5
80 21.0.6-amzn 21.0.6
81 21.0.6-graal 21.0.6
82 21.0.6-librca 21.0.6
83 21.0.6-ms 21.0.6
84 21.0.6-oracle 21.0.6
85 21.0.6-sapmchn 21.0.6
86 21.0.6-tem 21.0.6
87 21.0.6-zulu 21.0.6
88 21.0.6.fx-librca 21.0.6
89 21.0.6.fx-zulu 21.0.6
90 22.0.2-oracle 22.0.2
91 22.1.0.1.r11-gln 22.1.0
92 22.1.0.1.r17-gln 22.1.0
93 22.3.5.r11-nik 22.3.5
94 22.3.5.r17-mandrel 22.3.5
95 22.3.5.r17-nik 22.3.5
96 23-open 23
97 23.0.1-amzn 23.0.1
98 23.0.1-graal 23.0.1
99 23.0.1-graalce 23.0.1
100 23.0.1-librca 23.0.1
101 23.0.1-open 23.0.1
102 23.0.1-oracle 23.0.1
103 23.0.1-sapmchn 23.0.1
104 23.0.1-tem 23.0.1
105 23.0.1-zulu 23.0.1
106 23.0.1.crac-zulu 23.0.1
107 23.0.1.fx-librca 23.0.1
108 23.0.1.fx-zulu 23.0.1
109 23.0.2-amzn 23.0.2
110 23.0.2-graal 23.0.2
111 23.0.2-graalce 23.0.2
112 23.0.2-librca 23.0.2
113 23.0.2-oracle 23.0.2
114 23.0.2-sapmchn 23.0.2
115 23.0.2-tem 23.0.2
116 23.0.2-zulu 23.0.2
117 23.0.2.fx-librca 23.0.2
118 23.0.2.fx-zulu 23.0.2
119 23.0.6.fx-nik 23.0.6
120 23.0.6.r17-mandrel 23.0.6
121 23.0.6.r17-nik 23.0.6
122 23.1.5.fx-nik 23.1.5
123 23.1.5.r21-mandrel 23.1.5
124 23.1.5.r21-nik 23.1.5
125 24.0.2.r22-mandrel 24.0.2
126 24.ea.27-graal 24.0.0
127 24.ea.28-graal 24.0.0
128 24.ea.31-open 24.0.0
129 24.ea.32-open 24.0.0
130 24.1.1.r23-mandrel 24.1.1
131 24.1.1.r23-nik 24.1.1
132 25.ea.4-graal 25.0.0
133 25.ea.5-graal 25.0.0
134 25.ea.5-open 25.0.0
135 25.ea.6-open 25.0.0
@@ -191,7 +191,9 @@ describe('getAvailableVersions', () => {
])(
'defaults to os.arch(): %s mapped to distro arch: %s',
async (osArch: string, distroArch: string) => {
jest.spyOn(os, 'arch').mockReturnValue(osArch);
jest
.spyOn(os, 'arch')
.mockReturnValue(osArch as ReturnType<typeof os.arch>);
const installerOptions: JavaInstallerOptions = {
version: '17',
@@ -287,7 +287,7 @@ describe('setupJava', () => {
spyCoreSetOutput = jest.spyOn(core, 'setOutput');
spyCoreSetOutput.mockImplementation(() => undefined);
jest.spyOn(os, 'arch').mockReturnValue('x86');
jest.spyOn(os, 'arch').mockReturnValue('x86' as ReturnType<typeof os.arch>);
});
afterEach(() => {
@@ -150,9 +150,8 @@ describe('getAvailableVersions', () => {
});
mockPlatform(distribution, platform);
const availableVersion = await distribution['findPackageForDownload'](
version
);
const availableVersion =
await distribution['findPackageForDownload'](version);
expect(availableVersion).not.toBeNull();
expect(availableVersion.url).toBe(expectedLink);
});
@@ -203,29 +202,27 @@ describe('getAvailableVersions', () => {
});
it.each([
['arm64', 'aarch64'],
['amd64', 'x64']
['amd64', 'x64'],
['arm64', 'aarch64']
])(
'defaults to os.arch(): %s mapped to distro arch: %s',
async (osArch: string, distroArch: string) => {
jest.spyOn(os, 'arch').mockReturnValue(osArch);
jest
.spyOn(os, 'arch')
.mockReturnValue(osArch as ReturnType<typeof os.arch>);
const version = '17';
const installerOptions: JavaInstallerOptions = {
version,
const distribution = new CorrettoDistribution({
version: '17',
architecture: '', // to get default value
packageType: 'jdk',
checkLatest: false
};
const distribution = new CorrettoDistribution(installerOptions);
});
mockPlatform(distribution, 'macos');
const expectedLink = `https://corretto.aws/downloads/resources/17.0.2.8.1/amazon-corretto-17.0.2.8.1-macosx-${distroArch}.tar.gz`;
const availableVersion = await distribution['findPackageForDownload'](
version
);
const availableVersion =
await distribution['findPackageForDownload']('17');
expect(availableVersion).not.toBeNull();
expect(availableVersion.url).toBe(expectedLink);
}
@@ -206,9 +206,8 @@ describe('getAvailableVersions', () => {
});
mockPlatform(distribution, platform);
const availableVersion = await distribution['findPackageForDownload'](
jdkVersion
);
const availableVersion =
await distribution['findPackageForDownload'](jdkVersion);
expect(availableVersion).not.toBeNull();
expect(availableVersion.url).toBe(expectedLink);
}
@@ -0,0 +1,924 @@
import * as core from '@actions/core';
import * as tc from '@actions/tool-cache';
import * as http from '@actions/http-client';
import fs from 'fs';
import path from 'path';
import {GraalVMDistribution} from '../../src/distributions/graalvm/installer';
import {JavaInstallerOptions} from '../../src/distributions/base-models';
import * as util from '../../src/util';
jest.mock('@actions/core');
jest.mock('@actions/tool-cache');
jest.mock('@actions/http-client');
jest.mock('../../src/util', () => ({
...jest.requireActual('../../src/util'),
extractJdkFile: jest.fn(),
getDownloadArchiveExtension: jest.fn(),
renameWinArchive: jest.fn(),
getGitHubHttpHeaders: jest.fn().mockReturnValue({Accept: 'application/json'})
}));
jest.mock('fs', () => ({
...jest.requireActual('fs'),
readdirSync: jest.fn(),
existsSync: jest.fn()
}));
beforeAll(() => {
process.env.NODE_ENV = 'test';
if (!jest.isMockFunction(http.HttpClient)) {
throw new Error('HTTP client must be mocked in tests!');
}
if (!jest.isMockFunction(tc.downloadTool)) {
throw new Error('Tool cache downloadTool must be mocked in tests!');
}
console.log('✅ All external dependencies are properly mocked');
});
describe('GraalVMDistribution', () => {
let distribution: GraalVMDistribution;
let mockHttpClient: jest.Mocked<http.HttpClient>;
const defaultOptions: JavaInstallerOptions = {
version: '17',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
};
beforeEach(() => {
jest.clearAllMocks();
distribution = new GraalVMDistribution(defaultOptions);
mockHttpClient = new http.HttpClient() as jest.Mocked<http.HttpClient>;
(distribution as any).http = mockHttpClient;
(util.getDownloadArchiveExtension as jest.Mock).mockReturnValue('tar.gz');
});
afterAll(() => {
expect(jest.isMockFunction(http.HttpClient)).toBe(true);
expect(jest.isMockFunction(tc.downloadTool)).toBe(true);
expect(jest.isMockFunction(tc.cacheDir)).toBe(true);
jest.restoreAllMocks();
jest.clearAllMocks();
});
describe('getPlatform', () => {
it('should map darwin to macos', () => {
const result = distribution.getPlatform('darwin');
expect(result).toBe('macos');
});
it('should map win32 to windows', () => {
const result = distribution.getPlatform('win32');
expect(result).toBe('windows');
});
it('should map linux to linux', () => {
const result = distribution.getPlatform('linux');
expect(result).toBe('linux');
});
it('should throw error for unsupported platform', () => {
expect(() => distribution.getPlatform('aix' as NodeJS.Platform)).toThrow(
"Platform 'aix' is not supported. Supported platforms: 'linux', 'macos', 'windows'"
);
});
});
describe('downloadTool', () => {
const javaRelease = {
version: '17.0.5',
url: 'https://example.com/graalvm.tar.gz'
};
beforeEach(() => {
(tc.downloadTool as jest.Mock).mockResolvedValue('/tmp/archive.tar.gz');
(tc.cacheDir as jest.Mock).mockResolvedValue('/cached/java/path');
(util.extractJdkFile as jest.Mock).mockResolvedValue('/tmp/extracted');
// Mock renameWinArchive - it returns the same path (no renaming)
(util.renameWinArchive as jest.Mock).mockImplementation((p: string) => p);
(util.getDownloadArchiveExtension as jest.Mock).mockReturnValue('tar.gz');
// Mock fs.existsSync to return true for extracted path
(fs.existsSync as jest.Mock).mockReturnValue(true);
(fs.readdirSync as jest.Mock).mockReturnValue(['graalvm-jdk-17.0.5']);
jest
.spyOn(distribution as any, 'getToolcacheVersionName')
.mockImplementation(version => version);
});
it('should download, extract and cache the tool successfully', async () => {
const result = await (distribution as any).downloadTool(javaRelease);
// Verify the download was initiated
expect(tc.downloadTool).toHaveBeenCalledWith(javaRelease.url);
// The implementation uses the original path for extraction
expect(util.extractJdkFile).toHaveBeenCalledWith(
'/tmp/archive.tar.gz', // Original path
'tar.gz'
);
// Verify path existence check
expect(fs.existsSync).toHaveBeenCalledWith('/tmp/extracted');
// Verify directory reading
expect(fs.readdirSync).toHaveBeenCalledWith('/tmp/extracted');
// Verify caching with correct parameters
expect(tc.cacheDir).toHaveBeenCalledWith(
path.join('/tmp/extracted', 'graalvm-jdk-17.0.5'),
'Java_GraalVM_jdk',
'17.0.5',
'x64'
);
// Verify the result
expect(result).toEqual({
version: '17.0.5',
path: '/cached/java/path'
});
// Verify logging
expect(core.info).toHaveBeenCalledWith(
'Downloading Java 17.0.5 (GraalVM) from https://example.com/graalvm.tar.gz ...'
);
expect(core.info).toHaveBeenCalledWith('Extracting Java archive...');
});
it('should throw error when extracted path does not exist', async () => {
(fs.existsSync as jest.Mock).mockReturnValue(false);
await expect(
(distribution as any).downloadTool(javaRelease)
).rejects.toThrow(
'Extraction failed: path /tmp/extracted does not exist'
);
expect(core.error).toHaveBeenCalledWith(
expect.stringContaining('Failed to download and extract GraalVM:')
);
});
it('should throw error when extracted directory is empty', async () => {
(fs.existsSync as jest.Mock).mockReturnValue(true);
(fs.readdirSync as jest.Mock).mockReturnValue([]);
await expect(
(distribution as any).downloadTool(javaRelease)
).rejects.toThrow(
'Extraction failed: no files found in extracted directory'
);
expect(core.error).toHaveBeenCalledWith(
expect.stringContaining('Failed to download and extract GraalVM:')
);
});
it('should handle download errors', async () => {
const downloadError = new Error('Network error during download');
(tc.downloadTool as jest.Mock).mockRejectedValue(downloadError);
await expect(
(distribution as any).downloadTool(javaRelease)
).rejects.toThrow('Network error during download');
expect(core.error).toHaveBeenCalledWith(
'Failed to download and extract GraalVM: Error: Network error during download'
);
});
it('should handle extraction errors', async () => {
const extractError = new Error('Failed to extract archive');
(util.extractJdkFile as jest.Mock).mockRejectedValue(extractError);
await expect(
(distribution as any).downloadTool(javaRelease)
).rejects.toThrow('Failed to extract archive');
expect(core.error).toHaveBeenCalledWith(
'Failed to download and extract GraalVM: Error: Failed to extract archive'
);
});
it('should handle different archive extensions', async () => {
// Test with a .zip file
(util.getDownloadArchiveExtension as jest.Mock).mockReturnValue('zip');
(tc.downloadTool as jest.Mock).mockResolvedValue('/tmp/archive.zip');
const zipRelease = {
version: '17.0.5',
url: 'https://example.com/graalvm.zip'
};
const result = await (distribution as any).downloadTool(zipRelease);
expect(util.extractJdkFile).toHaveBeenCalledWith(
'/tmp/archive.zip',
'zip'
);
expect(result).toEqual({
version: '17.0.5',
path: '/cached/java/path'
});
});
});
describe('findPackageForDownload', () => {
beforeEach(() => {
jest.spyOn(distribution, 'getPlatform').mockReturnValue('linux');
});
describe('input validation', () => {
it('should throw error for null version range', async () => {
await expect(
(distribution as any).findPackageForDownload(null)
).rejects.toThrow('Version range is required and must be a string');
});
it('should throw error for undefined version range', async () => {
await expect(
(distribution as any).findPackageForDownload(undefined)
).rejects.toThrow('Version range is required and must be a string');
});
it('should throw error for empty string version range', async () => {
await expect(
(distribution as any).findPackageForDownload('')
).rejects.toThrow('Version range is required and must be a string');
});
it('should throw error for non-string version range', async () => {
await expect(
(distribution as any).findPackageForDownload(123)
).rejects.toThrow('Version range is required and must be a string');
});
it('should throw error for invalid version format', async () => {
await expect(
(distribution as any).findPackageForDownload('abc')
).rejects.toThrow('Invalid version format: abc');
});
});
describe('stable builds', () => {
it('should construct correct URL for specific version', async () => {
const mockResponse = {
message: {statusCode: 200}
} as http.HttpClientResponse;
mockHttpClient.head.mockResolvedValue(mockResponse);
const result = await (distribution as any).findPackageForDownload(
'17.0.5'
);
expect(result).toEqual({
url: 'https://download.oracle.com/graalvm/17/archive/graalvm-jdk-17.0.5_linux-x64_bin.tar.gz',
version: '17.0.5'
});
expect(mockHttpClient.head).toHaveBeenCalledWith(result.url);
});
it('should construct correct URL for major version (latest)', async () => {
const mockResponse = {
message: {statusCode: 200}
} as http.HttpClientResponse;
mockHttpClient.head.mockResolvedValue(mockResponse);
const result = await (distribution as any).findPackageForDownload('21');
expect(result).toEqual({
url: 'https://download.oracle.com/graalvm/21/latest/graalvm-jdk-21_linux-x64_bin.tar.gz',
version: '21'
});
});
it('should throw error for unsupported architecture', async () => {
distribution = new GraalVMDistribution({
...defaultOptions,
architecture: 'x86'
});
(distribution as any).http = mockHttpClient;
await expect(
(distribution as any).findPackageForDownload('17')
).rejects.toThrow(
'Unsupported architecture: x86. Supported architectures are: x64, aarch64'
);
});
it('should throw error for JDK versions less than 17', async () => {
await expect(
(distribution as any).findPackageForDownload('11')
).rejects.toThrow(
'GraalVM is only supported for JDK 17 and later. Requested version: 11'
);
});
it('should throw error for non-jdk package types', async () => {
distribution = new GraalVMDistribution({
...defaultOptions,
packageType: 'jre'
});
(distribution as any).http = mockHttpClient;
await expect(
(distribution as any).findPackageForDownload('17')
).rejects.toThrow('GraalVM provides only the `jdk` package type');
});
it('should throw error when file not found (404)', async () => {
const mockResponse = {
message: {statusCode: 404}
} as http.HttpClientResponse;
mockHttpClient.head.mockResolvedValue(mockResponse);
await expect(
(distribution as any).findPackageForDownload('17.0.99')
).rejects.toThrow(
'Could not find GraalVM for SemVer 17.0.99. Please check if this version is available at https://download.oracle.com/graalvm'
);
});
it('should throw error for unauthorized access (401)', async () => {
const mockResponse = {
message: {statusCode: 401}
} as http.HttpClientResponse;
mockHttpClient.head.mockResolvedValue(mockResponse);
await expect(
(distribution as any).findPackageForDownload('17')
).rejects.toThrow(
'Access denied when downloading GraalVM. Status code: 401. Please check your credentials or permissions.'
);
});
it('should throw error for forbidden access (403)', async () => {
const mockResponse = {
message: {statusCode: 403}
} as http.HttpClientResponse;
mockHttpClient.head.mockResolvedValue(mockResponse);
await expect(
(distribution as any).findPackageForDownload('17')
).rejects.toThrow(
'Access denied when downloading GraalVM. Status code: 403. Please check your credentials or permissions.'
);
});
it('should throw error for other HTTP errors with status message', async () => {
const mockResponse = {
message: {
statusCode: 500,
statusMessage: 'Internal Server Error'
}
} as http.HttpClientResponse;
mockHttpClient.head.mockResolvedValue(mockResponse);
await expect(
(distribution as any).findPackageForDownload('17')
).rejects.toThrow(
'HTTP request for GraalVM failed with status code: 500 (Internal Server Error)'
);
});
it('should throw error for other HTTP errors without status message', async () => {
const mockResponse = {
message: {statusCode: 500}
} as http.HttpClientResponse;
mockHttpClient.head.mockResolvedValue(mockResponse);
await expect(
(distribution as any).findPackageForDownload('17')
).rejects.toThrow(
'HTTP request for GraalVM failed with status code: 500 (Unknown error)'
);
});
});
describe('EA builds', () => {
beforeEach(() => {
distribution = new GraalVMDistribution(defaultOptions);
(distribution as any).http = mockHttpClient;
(distribution as any).stable = false;
});
it('should delegate to findEABuildDownloadUrl for unstable versions', async () => {
const currentPlatform =
process.platform === 'win32' ? 'windows' : process.platform;
const mockEAVersions = [
{
version: '23-ea-20240716',
latest: true,
download_base_url: 'https://example.com/download/',
files: [
{
arch: 'x64',
platform: currentPlatform,
filename: 'graalvm-jdk-23_linux-x64_bin.tar.gz'
},
{
arch: 'aarch64',
platform: currentPlatform,
filename: 'graalvm-jdk-23_linux-aarch64_bin.tar.gz'
}
]
}
];
mockHttpClient.getJson.mockResolvedValue({
result: mockEAVersions,
statusCode: 200,
headers: {}
});
jest
.spyOn(distribution as any, 'distributionArchitecture')
.mockReturnValue('x64');
const result = await (distribution as any).findPackageForDownload('23');
expect(result).toEqual({
url: 'https://example.com/download/graalvm-jdk-23_linux-x64_bin.tar.gz',
version: '23-ea-20240716'
});
expect(mockHttpClient.getJson).toHaveBeenCalledWith(
'https://api.github.com/repos/graalvm/oracle-graalvm-ea-builds/contents/versions/23-ea.json?ref=main',
{Accept: 'application/json'}
);
});
it('should throw error when no latest EA version found', async () => {
const currentPlatform =
process.platform === 'win32' ? 'windows' : process.platform;
const mockEAVersions = [
{
version: '23-ea-20240716',
latest: false,
download_base_url: 'https://example.com/download/',
files: [
{
arch: 'x64',
platform: currentPlatform,
filename: 'graalvm-jdk-23_linux-x64_bin.tar.gz'
}
]
}
];
mockHttpClient.getJson.mockResolvedValue({
result: mockEAVersions,
statusCode: 200,
headers: {}
});
jest
.spyOn(distribution as any, 'distributionArchitecture')
.mockReturnValue('x64');
await expect(
(distribution as any).findPackageForDownload('23')
).rejects.toThrow("Unable to find latest version for '23-ea'");
// Verify error logging
expect(core.error).toHaveBeenCalledWith(
'Available versions: 23-ea-20240716'
);
});
it('should throw error when no matching file for architecture in EA build', async () => {
const currentPlatform =
process.platform === 'win32' ? 'windows' : process.platform;
const mockEAVersions = [
{
version: '23-ea-20240716',
latest: true,
download_base_url: 'https://example.com/download/',
files: [
{
arch: 'arm64',
platform: currentPlatform,
filename: 'graalvm-jdk-23_linux-arm64_bin.tar.gz'
}
]
}
];
mockHttpClient.getJson.mockResolvedValue({
result: mockEAVersions,
statusCode: 200,
headers: {}
});
jest
.spyOn(distribution as any, 'distributionArchitecture')
.mockReturnValue('x64');
await expect(
(distribution as any).findPackageForDownload('23')
).rejects.toThrow(
`Unable to find file for architecture 'x64' and platform '${currentPlatform}'`
);
// Verify error logging
expect(core.error).toHaveBeenCalledWith(
expect.stringContaining('Available files for architecture x64:')
);
});
it('should throw error when no matching platform in EA build', async () => {
const mockEAVersions = [
{
version: '23-ea-20240716',
latest: true,
download_base_url: 'https://example.com/download/',
files: [
{
arch: 'x64',
platform: 'different-platform',
filename: 'graalvm-jdk-23_different-x64_bin.tar.gz'
}
]
}
];
mockHttpClient.getJson.mockResolvedValue({
result: mockEAVersions,
statusCode: 200,
headers: {}
});
jest
.spyOn(distribution as any, 'distributionArchitecture')
.mockReturnValue('x64');
const currentPlatform =
process.platform === 'win32' ? 'windows' : process.platform;
await expect(
(distribution as any).findPackageForDownload('23')
).rejects.toThrow(
`Unable to find file for architecture 'x64' and platform '${currentPlatform}'`
);
});
it('should throw error when filename does not start with graalvm-jdk-', async () => {
const currentPlatform =
process.platform === 'win32' ? 'windows' : process.platform;
const mockEAVersions = [
{
version: '23-ea-20240716',
latest: true,
download_base_url: 'https://example.com/download/',
files: [
{
arch: 'x64',
platform: currentPlatform,
filename: 'wrong-prefix-23_linux-x64_bin.tar.gz'
}
]
}
];
mockHttpClient.getJson.mockResolvedValue({
result: mockEAVersions,
statusCode: 200,
headers: {}
});
jest
.spyOn(distribution as any, 'distributionArchitecture')
.mockReturnValue('x64');
await expect(
(distribution as any).findPackageForDownload('23')
).rejects.toThrow(
"Invalid filename format: wrong-prefix-23_linux-x64_bin.tar.gz. Expected to start with 'graalvm-jdk-'"
);
});
it('should throw error when EA version JSON is not found', async () => {
mockHttpClient.getJson.mockResolvedValue({
result: null,
statusCode: 404,
headers: {}
});
await expect(
(distribution as any).findPackageForDownload('23')
).rejects.toThrow(
"No GraalVM EA build found for version '23-ea'. Please check if the version is correct."
);
});
});
});
describe('findEABuildDownloadUrl', () => {
const currentPlatform =
process.platform === 'win32' ? 'windows' : process.platform;
const mockEAVersions = [
{
version: '23-ea-20240716',
latest: true,
download_base_url: 'https://example.com/download/',
files: [
{
arch: 'x64',
platform: currentPlatform,
filename: 'graalvm-jdk-23_linux-x64_bin.tar.gz'
},
{
arch: 'aarch64',
platform: currentPlatform,
filename: 'graalvm-jdk-23_linux-aarch64_bin.tar.gz'
}
]
},
{
version: '23-ea-20240709',
latest: false,
download_base_url: 'https://example.com/old/',
files: [
{
arch: 'x64',
platform: currentPlatform,
filename: 'graalvm-jdk-23_linux-x64_bin.tar.gz'
}
]
}
];
let fetchEASpy: jest.SpyInstance;
beforeEach(() => {
fetchEASpy = jest.spyOn(distribution as any, 'fetchEAJson');
jest
.spyOn(distribution as any, 'distributionArchitecture')
.mockReturnValue('x64');
});
it('should find latest version and return correct URL', async () => {
fetchEASpy.mockResolvedValue(mockEAVersions);
const result = await (distribution as any).findEABuildDownloadUrl(
'23-ea'
);
expect(fetchEASpy).toHaveBeenCalledWith('23-ea');
expect(result).toEqual({
url: 'https://example.com/download/graalvm-jdk-23_linux-x64_bin.tar.gz',
version: '23-ea-20240716'
});
// Verify debug logging
expect(core.debug).toHaveBeenCalledWith('Searching for EA build: 23-ea');
expect(core.debug).toHaveBeenCalledWith('Found 2 EA versions');
expect(core.debug).toHaveBeenCalledWith(
'Latest version found: 23-ea-20240716'
);
expect(core.debug).toHaveBeenCalledWith(
'Download URL: https://example.com/download/graalvm-jdk-23_linux-x64_bin.tar.gz'
);
});
it('should throw error when no latest version found', async () => {
const noLatestVersions = mockEAVersions.map(v => ({...v, latest: false}));
fetchEASpy.mockResolvedValue(noLatestVersions);
await expect(
(distribution as any).findEABuildDownloadUrl('23-ea')
).rejects.toThrow("Unable to find latest version for '23-ea'");
expect(core.error).toHaveBeenCalledWith(
'Available versions: 23-ea-20240716, 23-ea-20240709'
);
});
it('should throw error when no matching file for architecture', async () => {
const wrongArchVersions = [
{
version: '23-ea-20240716',
latest: true,
download_base_url: 'https://example.com/download/',
files: [
{
arch: 'arm',
platform: currentPlatform,
filename: 'graalvm-jdk-23_linux-arm_bin.tar.gz'
}
]
}
];
fetchEASpy.mockResolvedValue(wrongArchVersions);
await expect(
(distribution as any).findEABuildDownloadUrl('23-ea')
).rejects.toThrow(
`Unable to find file for architecture 'x64' and platform '${currentPlatform}'`
);
expect(core.error).toHaveBeenCalledWith(
expect.stringContaining('Available files for architecture x64:')
);
});
it('should throw error when filename does not start with graalvm-jdk-', async () => {
const badFilenameVersions = [
{
version: '23-ea-20240716',
latest: true,
download_base_url: 'https://example.com/download/',
files: [
{
arch: 'x64',
platform: currentPlatform,
filename: 'wrong-name.tar.gz'
}
]
}
];
fetchEASpy.mockResolvedValue(badFilenameVersions);
await expect(
(distribution as any).findEABuildDownloadUrl('23-ea')
).rejects.toThrow(
"Invalid filename format: wrong-name.tar.gz. Expected to start with 'graalvm-jdk-'"
);
});
it('should work with aarch64 architecture', async () => {
jest
.spyOn(distribution as any, 'distributionArchitecture')
.mockReturnValue('aarch64');
fetchEASpy.mockResolvedValue(mockEAVersions);
const result = await (distribution as any).findEABuildDownloadUrl(
'23-ea'
);
expect(result).toEqual({
url: 'https://example.com/download/graalvm-jdk-23_linux-aarch64_bin.tar.gz',
version: '23-ea-20240716'
});
});
it('should throw error when platform does not match', async () => {
const wrongPlatformVersions = [
{
version: '23-ea-20240716',
latest: true,
download_base_url: 'https://example.com/download/',
files: [
{
arch: 'x64',
platform: 'different-platform',
filename: 'graalvm-jdk-23_different-x64_bin.tar.gz'
}
]
}
];
fetchEASpy.mockResolvedValue(wrongPlatformVersions);
await expect(
(distribution as any).findEABuildDownloadUrl('23-ea')
).rejects.toThrow(
`Unable to find file for architecture 'x64' and platform '${currentPlatform}'`
);
});
});
describe('fetchEAJson', () => {
it('should fetch and return EA version data', async () => {
const mockData = [{version: '23-ea', files: []}];
mockHttpClient.getJson.mockResolvedValue({
result: mockData,
statusCode: 200,
headers: {}
});
const result = await (distribution as any).fetchEAJson('23-ea');
expect(mockHttpClient.getJson).toHaveBeenCalledWith(
'https://api.github.com/repos/graalvm/oracle-graalvm-ea-builds/contents/versions/23-ea.json?ref=main',
{Accept: 'application/json'}
);
expect(result).toEqual(mockData);
expect(core.debug).toHaveBeenCalled();
});
it('should throw error when no data returned', async () => {
mockHttpClient.getJson.mockResolvedValue({
result: null,
statusCode: 200,
headers: {}
});
await expect((distribution as any).fetchEAJson('23-ea')).rejects.toThrow(
"No GraalVM EA build found for version '23-ea'. Please check if the version is correct."
);
});
it('should handle 404 errors with specific message', async () => {
const error404 = new Error('Not Found: 404');
mockHttpClient.getJson.mockRejectedValue(error404);
await expect((distribution as any).fetchEAJson('23-ea')).rejects.toThrow(
"GraalVM EA version '23-ea' not found. Please verify the version exists in the EA builds repository."
);
});
it('should handle generic HTTP errors with context', async () => {
const networkError = new Error('Network timeout');
mockHttpClient.getJson.mockRejectedValue(networkError);
await expect((distribution as any).fetchEAJson('23-ea')).rejects.toThrow(
"Failed to fetch GraalVM EA version information for '23-ea': Network timeout"
);
});
it('should handle non-Error exceptions', async () => {
mockHttpClient.getJson.mockRejectedValue('String error');
await expect((distribution as any).fetchEAJson('23-ea')).rejects.toThrow(
"Failed to fetch GraalVM EA version information for '23-ea'"
);
});
});
describe('Integration tests', () => {
it('should handle different architectures correctly', async () => {
const architectures = ['x64', 'aarch64'];
for (const arch of architectures) {
distribution = new GraalVMDistribution({
...defaultOptions,
architecture: arch
});
(distribution as any).http = mockHttpClient;
const mockResponse = {
message: {statusCode: 200}
} as http.HttpClientResponse;
mockHttpClient.head.mockResolvedValue(mockResponse);
const result = await (distribution as any).findPackageForDownload('17');
expect(result.url).toContain(arch);
}
});
it('should handle different platforms correctly', async () => {
const platforms = [
{process: 'darwin', expected: 'macos'},
{process: 'win32', expected: 'windows'},
{process: 'linux', expected: 'linux'}
];
const originalPlatform = process.platform;
for (const {process: proc, expected} of platforms) {
Object.defineProperty(process, 'platform', {
value: proc,
configurable: true
});
distribution = new GraalVMDistribution(defaultOptions);
(distribution as any).http = mockHttpClient;
const mockResponse = {
message: {statusCode: 200}
} as http.HttpClientResponse;
mockHttpClient.head.mockResolvedValue(mockResponse);
const result = await (distribution as any).findPackageForDownload('17');
expect(result.url).toContain(expected);
}
Object.defineProperty(process, 'platform', {
value: originalPlatform,
configurable: true
});
});
});
});
@@ -0,0 +1,117 @@
import https from 'https';
import {HttpClient} from '@actions/http-client';
import {JetBrainsDistribution} from '../../src/distributions/jetbrains/installer';
import manifestData from '../data/jetbrains.json';
import os from 'os';
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
beforeEach(() => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
spyHttpClient.mockReturnValue({
statusCode: 200,
headers: {},
result: []
});
});
afterEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
});
it('load available versions', async () => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
spyHttpClient.mockReturnValueOnce({
statusCode: 200,
headers: {},
result: manifestData as any
});
const distribution = new JetBrainsDistribution({
version: '17',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
const availableVersions = await distribution['getAvailableVersions']();
expect(availableVersions).not.toBeNull();
const length =
os.platform() === 'win32' ? manifestData.length : manifestData.length + 2;
expect(availableVersions.length).toBe(length);
}, 10_000);
});
describe('findPackageForDownload', () => {
it.each([
['17', '17.0.11+1207.24'],
['11.0', '11.0.16+2043.64'],
['11.0.11', '11.0.11+1542.1'],
['21.0.2', '21.0.2+375.1'],
['21', '21.0.3+465.3'],
['x', '21.0.3+465.3']
])('version is resolved correctly %s -> %s', async (input, expected) => {
const distribution = new JetBrainsDistribution({
version: input,
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
distribution['getAvailableVersions'] = async () => manifestData as any;
const resolvedVersion = await distribution['findPackageForDownload'](input);
expect(resolvedVersion.version).toBe(expected);
});
it.each(['17', '11.0', '11.0.11', '21.0.2', '21'])(
'version %s can be downloaded',
async input => {
const distribution = new JetBrainsDistribution({
version: input,
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
distribution['getAvailableVersions'] = async () => manifestData as any;
const resolvedVersion =
await distribution['findPackageForDownload'](input);
const url = resolvedVersion.url;
const options = {method: 'HEAD'};
https.request(url, options, res => {
// JetBrains uses 403 for inexistent packages
expect(res.statusCode).not.toBe(403);
res.resume();
});
}
);
it('version is not found', async () => {
const distribution = new JetBrainsDistribution({
version: '8.0.452',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
distribution['getAvailableVersions'] = async () => manifestData as any;
await expect(distribution['findPackageForDownload']('8.x')).rejects.toThrow(
/Could not find satisfied version for SemVer */
);
});
it('version list is empty', async () => {
const distribution = new JetBrainsDistribution({
version: '8',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
distribution['getAvailableVersions'] = async () => [];
await expect(distribution['findPackageForDownload']('8')).rejects.toThrow(
/Could not find satisfied version for SemVer */
);
});
});
@@ -105,9 +105,11 @@ describe('getAvailableVersions', () => {
])(
'defaults to os.arch(): %s mapped to distro arch: %s',
async (osArch: string, distroArch: DistroArch) => {
jest.spyOn(os, 'arch').mockReturnValue(osArch);
jest
.spyOn(os, 'arch')
.mockReturnValue(osArch as ReturnType<typeof os.arch>);
const distribution = new LibericaDistributions({
const distributions = new LibericaDistributions({
version: '17',
architecture: '', // to get default value
packageType: 'jdk',
@@ -117,11 +119,11 @@ describe('getAvailableVersions', () => {
const additionalParams =
'&installation-type=archive&fields=downloadUrl%2Cversion%2CfeatureVersion%2CinterimVersion%2C' +
'updateVersion%2CbuildVersion';
distribution['getPlatformOption'] = () => 'macos';
distributions['getPlatformOption'] = () => 'macos';
const buildUrl = `https://api.bell-sw.com/v1/liberica/releases?os=macos&bundle-type=jdk&bitness=${distroArch.bitness}&arch=${distroArch.arch}&build-type=all${additionalParams}`;
await distribution['getAvailableVersions']();
await distributions['getAvailableVersions']();
expect(spyHttpClient.mock.calls).toHaveLength(1);
expect(spyHttpClient.mock.calls[0][0]).toBe(buildUrl);
@@ -105,7 +105,9 @@ describe('getAvailableVersions', () => {
])(
'defaults to os.arch(): %s mapped to distro arch: %s',
async (osArch: string, distroArch: DistroArch) => {
jest.spyOn(os, 'arch').mockReturnValue(osArch);
jest
.spyOn(os, 'arch')
.mockReturnValue(osArch as ReturnType<typeof os.arch>);
const distribution = new LibericaDistributions({
version: '17',
@@ -105,7 +105,9 @@ describe('getAvailableVersions', () => {
])(
'defaults to os.arch(): %s mapped to distro arch: %s',
async (osArch: string, distroArch: DistroArch) => {
jest.spyOn(os, 'arch').mockReturnValue(osArch);
jest
.spyOn(os, 'arch')
.mockReturnValue(osArch as ReturnType<typeof os.arch>);
const distribution = new LibericaDistributions({
version: '17',
@@ -29,6 +29,11 @@ describe('findPackageForDownload', () => {
});
it.each([
[
'25.x',
'25.0.0',
'https://aka.ms/download-jdk/microsoft-jdk-25.0.0-{{OS_TYPE}}-x64.{{ARCHIVE_TYPE}}'
],
[
'21.x',
'21.0.0',
@@ -95,7 +100,9 @@ describe('findPackageForDownload', () => {
])(
'defaults to os.arch(): %s mapped to distro arch: %s',
async (osArch: string, distroArch: string) => {
jest.spyOn(os, 'arch').mockReturnValue(osArch);
jest
.spyOn(os, 'arch')
.mockReturnValue(osArch as ReturnType<typeof os.arch>);
jest.spyOn(os, 'platform').mockReturnValue('darwin');
const version = '17';
@@ -119,7 +126,9 @@ describe('findPackageForDownload', () => {
])(
'defaults to os.arch(): %s mapped to distro arch: %s',
async (osArch: string, distroArch: string) => {
jest.spyOn(os, 'arch').mockReturnValue(osArch);
jest
.spyOn(os, 'arch')
.mockReturnValue(osArch as ReturnType<typeof os.arch>);
jest.spyOn(os, 'platform').mockReturnValue('linux');
const version = '17';
@@ -143,7 +152,9 @@ describe('findPackageForDownload', () => {
])(
'defaults to os.arch(): %s mapped to distro arch: %s',
async (osArch: string, distroArch: string) => {
jest.spyOn(os, 'arch').mockReturnValue(osArch);
jest
.spyOn(os, 'arch')
.mockReturnValue(osArch as ReturnType<typeof os.arch>);
jest.spyOn(os, 'platform').mockReturnValue('win32');
const version = '17';
@@ -95,7 +95,9 @@ describe('findPackageForDownload', () => {
])(
'defaults to os.arch(): %s mapped to distro arch: %s',
async (osArch: string, distroArch: string) => {
jest.spyOn(os, 'arch').mockReturnValue(osArch);
jest
.spyOn(os, 'arch')
.mockReturnValue(osArch as ReturnType<typeof os.arch>);
jest.spyOn(os, 'platform').mockReturnValue('linux');
const version = '18';
@@ -61,9 +61,8 @@ describe('getAvailableVersions', () => {
mockPlatform(distribution, 'linux');
const availableVersion = await distribution['findPackageForDownload'](
version
);
const availableVersion =
await distribution['findPackageForDownload'](version);
expect(availableVersion).not.toBeNull();
expect(availableVersion.url).toBe(
'https://github.com/SAP/SapMachine/releases/download/sapmachine-17.0.10/sapmachine-jdk-17.0.10_linux-x64_bin.tar.gz'
@@ -230,9 +229,8 @@ describe('getAvailableVersions', () => {
});
mockPlatform(distribution, platform);
const availableVersion = await distribution['findPackageForDownload'](
normalizedVersion
);
const availableVersion =
await distribution['findPackageForDownload'](normalizedVersion);
expect(availableVersion).not.toBeNull();
expect(availableVersion.url).toBe(expectedLink);
}
@@ -147,7 +147,9 @@ describe('getAvailableVersions', () => {
])(
'defaults to os.arch(): %s mapped to distro arch: %s',
async (osArch: string, distroArch: string) => {
jest.spyOn(os, 'arch').mockReturnValue(distroArch);
jest
.spyOn(os, 'arch')
.mockReturnValue(osArch as ReturnType<typeof os.arch>);
const installerOptions: JavaInstallerOptions = {
version: '17',
@@ -1,5 +1,4 @@
import {HttpClient} from '@actions/http-client';
import * as semver from 'semver';
import {ZuluDistribution} from '../../src/distributions/zulu/installer';
import {IZuluVersions} from '../../src/distributions/zulu/models';
import * as utils from '../../src/util';
@@ -126,7 +125,9 @@ describe('getAvailableVersions', () => {
])(
'defaults to os.arch(): %s mapped to distro arch: %s',
async (osArch: string, distroArch: DistroArch) => {
jest.spyOn(os, 'arch').mockReturnValue(osArch);
jest
.spyOn(os, 'arch')
.mockReturnValue(osArch as ReturnType<typeof os.arch>);
const distribution = new ZuluDistribution({
version: '17',
@@ -126,7 +126,9 @@ describe('getAvailableVersions', () => {
])(
'defaults to os.arch(): %s mapped to distro arch: %s',
async (osArch: string, distroArch: DistroArch) => {
jest.spyOn(os, 'arch').mockReturnValue(osArch);
jest
.spyOn(os, 'arch')
.mockReturnValue(osArch as ReturnType<typeof os.arch>);
const distribution = new ZuluDistribution({
version: '17',
@@ -135,7 +137,9 @@ describe('getAvailableVersions', () => {
checkLatest: false
});
distribution['getPlatformOption'] = () => 'linux';
const buildUrl = `https://api.azul.com/zulu/download/community/v1.0/bundles/?os=linux&ext=zip&bundle_type=jdk&javafx=false&arch=${distroArch.arch}&hw_bitness=${distroArch.bitness}&release_status=ga`;
// Override extension for linux default arch case to match util behavior
spyUtilGetDownloadArchiveExtension.mockReturnValue('tar.gz');
const buildUrl = `https://api.azul.com/zulu/download/community/v1.0/bundles/?os=linux&ext=tar.gz&bundle_type=jdk&javafx=false&arch=${distroArch.arch}&hw_bitness=${distroArch.bitness}&release_status=ga`;
await distribution['getAvailableVersions']();
@@ -126,7 +126,9 @@ describe('getAvailableVersions', () => {
])(
'defaults to os.arch(): %s mapped to distro arch: %s',
async (osArch: string, distroArch: DistroArch) => {
jest.spyOn(os, 'arch').mockReturnValue(osArch);
jest
.spyOn(os, 'arch')
.mockReturnValue(osArch as ReturnType<typeof os.arch>);
const distribution = new ZuluDistribution({
version: '17',
+80 -1
View File
@@ -1,9 +1,13 @@
import * as cache from '@actions/cache';
import * as core from '@actions/core';
import * as fs from 'fs';
import * as path from 'path';
import {
convertVersionToSemver,
getVersionFromFileContent,
isVersionSatisfies,
isCacheFeatureAvailable
isCacheFeatureAvailable,
isGhes
} from '../src/util';
jest.mock('@actions/cache');
@@ -80,3 +84,78 @@ describe('convertVersionToSemver', () => {
expect(actual).toBe(expected);
});
});
describe('getVersionFromFileContent', () => {
describe('.sdkmanrc', () => {
it.each([
['java=11.0.20.1-tem', '11.0.20'],
['java = 11.0.20.1-tem', '11.0.20'],
['java=11.0.20.1-tem # a comment in sdkmanrc', '11.0.20'],
['java=11.0.20.1-tem\n#java=21.0.20.1-tem\n', '11.0.20'], // choose first match
['java=11.0.20.1-tem\njava=21.0.20.1-tem\n', '11.0.20'], // choose first match
['#java=11.0.20.1-tem\njava=21.0.20.1-tem\n', '21.0.20'] // first one is 'commented' in .sdkmanrc
])('parsing %s should return %s', (content: string, expected: string) => {
const actual = getVersionFromFileContent(content, 'openjdk', '.sdkmanrc');
expect(actual).toBe(expected);
});
describe('known versions', () => {
const csv = fs.readFileSync(
path.join(__dirname, 'data/sdkman-java-versions.csv'),
'utf8'
);
const versions = csv.split('\n').map(r => r.split(', '));
it.each(versions)(
'parsing %s should return %s',
(sdkmanJavaVersion: string, expected: string) => {
const asContent = `java=${sdkmanJavaVersion}`;
const actual = getVersionFromFileContent(
asContent,
'openjdk',
'.sdkmanrc'
);
expect(actual).toBe(expected);
}
);
});
});
});
describe('isGhes', () => {
const pristineEnv = process.env;
beforeEach(() => {
jest.resetModules();
process.env = {...pristineEnv};
});
afterAll(() => {
process.env = pristineEnv;
});
it('returns false when the GITHUB_SERVER_URL environment variable is not defined', async () => {
delete process.env['GITHUB_SERVER_URL'];
expect(isGhes()).toBeFalsy();
});
it('returns false when the GITHUB_SERVER_URL environment variable is set to github.com', async () => {
process.env['GITHUB_SERVER_URL'] = 'https://github.com';
expect(isGhes()).toBeFalsy();
});
it('returns false when the GITHUB_SERVER_URL environment variable is set to a GitHub Enterprise Cloud-style URL', async () => {
process.env['GITHUB_SERVER_URL'] = 'https://contoso.ghe.com';
expect(isGhes()).toBeFalsy();
});
it('returns false when the GITHUB_SERVER_URL environment variable has a .localhost suffix', async () => {
process.env['GITHUB_SERVER_URL'] = 'https://mock-github.localhost';
expect(isGhes()).toBeFalsy();
});
it('returns true when the GITHUB_SERVER_URL environment variable is set to some other URL', async () => {
process.env['GITHUB_SERVER_URL'] = 'https://src.onpremise.fabrikam.com';
expect(isGhes()).toBeTruthy();
});
});
+1 -1
View File
@@ -81,6 +81,6 @@ outputs:
cache-hit:
description: 'A boolean value to indicate an exact match was found for the primary key'
runs:
using: 'node20'
using: 'node24'
main: 'dist/setup/index.js'
post: 'dist/cleanup/index.js'
+8040 -1882
View File
File diff suppressed because it is too large Load Diff
+8615 -1906
View File
File diff suppressed because it is too large Load Diff
+130 -51
View File
@@ -9,6 +9,8 @@
- [Oracle](#Oracle)
- [Alibaba Dragonwell](#Alibaba-Dragonwell)
- [SapMachine](#SapMachine)
- [GraalVM](#GraalVM)
- [JetBrains](#JetBrains)
- [Installing custom Java package type](#Installing-custom-Java-package-type)
- [Installing custom Java architecture](#Installing-custom-Java-architecture)
- [Installing custom Java distribution from local file](#Installing-Java-from-local-file)
@@ -29,8 +31,8 @@ Inputs `java-version` and `distribution` are mandatory and needs to be provided.
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '21'
@@ -42,8 +44,8 @@ steps:
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'adopt-hotspot'
java-version: '11'
@@ -54,8 +56,8 @@ steps:
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'zulu'
java-version: '21'
@@ -67,8 +69,8 @@ steps:
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'liberica'
java-version: '21'
@@ -80,8 +82,8 @@ steps:
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'microsoft'
java-version: '21'
@@ -95,7 +97,7 @@ steps:
To get a higher rate limit, you can [generate a personal access token on github.com](https://github.com/settings/tokens/new) and pass it as the `token` input for the action:
```yaml
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
token: ${{ secrets.GH_DOTCOM_TOKEN }}
distribution: 'microsoft'
@@ -109,8 +111,8 @@ If the runner is not able to access github.com, any Java versions requested duri
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'corretto'
java-version: '21'
@@ -122,8 +124,8 @@ steps:
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'oracle'
java-version: '21'
@@ -135,8 +137,8 @@ steps:
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'dragonwell'
java-version: '8'
@@ -147,19 +149,78 @@ steps:
**NOTE:** An OpenJDK release maintained and supported by SAP
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'sapmachine'
java-version: '21'
- run: java -cp java HelloWorldApp
```
### GraalVM
**NOTE:** Oracle GraalVM is only available for JDK 17 and later.
```yaml
steps:
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'graalvm'
java-version: '21'
- run: |
java -cp java HelloWorldApp
native-image -cp java HelloWorldApp
```
### JetBrains
**NOTE:** JetBrains is only available for LTS versions on 11 or later (11, 17, 21, etc.).
Not all minor LTS versions are guarenteed to be available, since JetBrains considers what to ship IntelliJ IDEA with, most commonly on JDK 11.
For example, `11.0.24` is not available but `11.0.16` is.
```yaml
steps:
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'jetbrains'
java-version: '11'
- run: java -cp java HelloWorldApp
```
The JetBrains installer uses the GitHub API to fetch the latest version. If you believe your project is going to be running into rate limits, you can provide a
GitHub token to the action to increase the rate limit. Set the `GITHUB_TOKEN` environment variable to the value of your GitHub token in the workflow file.
```yaml
steps:
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'jetbrains'
java-version: '17'
java-package: 'jdk' # optional (jdk, jre, jdk+jcef, jre+jcef, jdk+ft, or jre+ft) - defaults to jdk
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: java -cp java HelloWorldApp
```
You can specify your package type (as shown in the [releases page](https://github.com/JetBrains/JetBrainsRuntime/releases/)) in the `java-package` parameter.
The available package types are:
- `jdk` - JBRSDK
- `jre` - JBR (Vanilla)
- `jdk+jcef` - JBRSDK with JCEF
- `jre+jcef` - JBR with JCEF
- `jdk+ft` - JBRSDK (FreeType)
- `jre+ft` - JBR (FreeType)
## Installing custom Java package type
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: '<distribution>'
java-version: '11'
@@ -167,13 +228,12 @@ steps:
- run: java -cp java HelloWorldApp
```
## Installing custom Java architecture
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: '<distribution>'
java-version: '11'
@@ -189,7 +249,7 @@ steps:
- run: |
download_url="https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.10_9.tar.gz"
wget -O $RUNNER_TEMP/java_package.tar.gz $download_url
- uses: actions/setup-java@v4
- uses: actions/setup-java@v5
with:
distribution: 'jdkfile'
jdkFile: ${{ runner.temp }}/java_package.tar.gz
@@ -215,7 +275,7 @@ If your use-case requires a custom distribution (in the example, alpine-linux is
latest_semver_version=$(curl -sL $latest_jdk_json_url | jq -r 'version.semver')
echo "java_version=$latest_semver_version" >> "$GITHUB_OUTPUT"
- uses: actions/setup-java@v4
- uses: actions/setup-java@v5
with:
distribution: 'jdkfile'
jdkFile: ${{ runner.temp }}/java_package.tar.gz
@@ -236,9 +296,9 @@ jobs:
java: [ '8', '11' ]
name: Java ${{ matrix.Java }} (${{ matrix.distribution }}) sample
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Setup java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: ${{ matrix.distribution }}
java-version: ${{ matrix.java }}
@@ -256,9 +316,9 @@ jobs:
os: [ 'ubuntu-latest', 'macos-latest', 'windows-latest' ]
name: Java ${{ matrix.Java }} (${{ matrix.os }}) sample
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Setup java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: ${{ matrix.java }}
@@ -273,9 +333,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Set up JDK 11
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: '<distribution>'
java-version: '11'
@@ -289,7 +349,7 @@ jobs:
GITHUB_TOKEN: ${{ github.token }} # GITHUB_TOKEN is the default env for the password
- name: Set up Apache Maven Central
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with: # running setup-java again overwrites the settings.xml
distribution: 'temurin'
java-version: '11'
@@ -386,9 +446,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Set up JDK 11 for Shared Runner
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: '<distribution>'
java-version: '11'
@@ -412,10 +472,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Set up JDK 11
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: '<distribution>'
java-version: '11'
@@ -449,14 +509,14 @@ Subsequent calls to `setup-java` with distinct distribution and version paramete
```yaml
steps:
- uses: actions/setup-java@v4
- uses: actions/setup-java@v5
with:
distribution: '<distribution>'
java-version: |
8
11
- uses: actions/setup-java@v4
- uses: actions/setup-java@v5
with:
distribution: '<distribution>'
java-version: '15'
@@ -468,7 +528,7 @@ The result is a Toolchain with entries for JDKs 8, 11 and 15. You can even combi
- run: |
download_url="https://example.com/java/jdk/6u45-b06/jdk-6u45-linux-x64.tar.gz"
wget -O $RUNNER_TEMP/java_package.tar.gz $download_url
- uses: actions/setup-java@v4
- uses: actions/setup-java@v5
with:
distribution: 'jdkfile'
jdkFile: ${{ runner.temp }}/java_package.tar.gz
@@ -485,7 +545,7 @@ Each JDK provider will receive a default `vendor` using the `distribution` input
- run: |
download_url="https://example.com/java/jdk/6u45-b06/jdk-6u45-linux-x64.tar.gz"
wget -O $RUNNER_TEMP/java_package.tar.gz $download_url
- uses: actions/setup-java@v4
- uses: actions/setup-java@v5
with:
distribution: 'jdkfile'
jdkFile: ${{ runner.temp }}/java_package.tar.gz
@@ -500,7 +560,7 @@ In case you install multiple versions of Java at once with multi-line `java-vers
```yaml
steps:
- uses: actions/setup-java@v4
- uses: actions/setup-java@v5
with:
distribution: '<distribution>'
java-version: |
@@ -514,8 +574,8 @@ Each JDK provider will receive a default `id` based on the combination of `distr
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '11'
@@ -527,7 +587,7 @@ In case you install multiple versions of Java at once you can use the same synta
```yaml
steps:
- uses: actions/setup-java@v4
- uses: actions/setup-java@v5
with:
distribution: '<distribution>'
java-version: |
@@ -541,18 +601,37 @@ steps:
## Java version file
If the `java-version-file` input is specified, the action will extract the version from the file and install it.
Supported files are .java-version and .tool-versions.
In .java-version file, only the version should be specified (e.g., 17.0.7).
In .tool-versions file, java version should be preceded by the java keyword (e.g., java 17.0.7).
The `.java-version` file recognizes all variants of the version description according to [jenv](https://github.com/jenv/jenv). Similarly, 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/)).
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 `.sdkmanrc` file, java version should be preceded by the `java=` prefix (e.g., java=17.0.7-tem) and include the distribution. 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.
If both java-version and java-version-file inputs are provided, the java-version input will be used.
Valid entry options:
If both `java-version` and `java-version-file` **inputs** are provided, the `java-version` input will be used.
**Example step using `Sdkman!`**:
```yml
- name: Setup java
uses: actions/setup-java@v5
with:
java-version-file: '.sdkmanrc'
distribution: 'temurin'
```
**Example `.sdkmanrc`**:
```
java=17.0.7-tem
```
Valid entry options (does not apply to `.sdkmanrc`):
```
major versions: 8, 11, 16, 17, 21
more specific versions: 8.0.282+8, 8.0.232, 11.0, 11.0.4, 17.0
early access (EA) versions: 15-ea, 15.0.0-ea
versions with specified distribution: openjdk64-11.0.2
LTS versions : temurin-21.0.5+11.0.LTS
```
If the file contains multiple versions, only the first one will be recognized.
***NOTE***:
For the tool-version file, ensure that you use standard semantic versioning (semver) formats, as non-standard formats (such as jetbrains-21b212.1) may not be parsed correctly. Additionally, for complex version strings containing multiple version-like segments (for example, java semeru-openj9-11.0.15+10_openj9-0.32.0), the extraction logic may incorrectly capture the last segment (0.32.0) instead of the main version (11.0.15+10).
+2 -2
View File
@@ -68,7 +68,7 @@ Pull requests are the easiest way to contribute changes to git repos at GitHub.
Adding or changing tests is an integral part of making a change to the code.
Unit tests are in the `__tests__` folder, and end-to-end tests are in the `workflows` folder, particularly take a look at the files with `e2e` prefix, for instance, [e2e-cache.yml](https://github.com/actions/setup-java/blob/main/.github/workflows/e2e-cache.yml).
- The contributor can add various types of tests (like unit tests or end-to-end tests), which, in his opinion, will be necessary and sufficient for testing new or changed functionality
- The contributor can add various types of tests (like unit tests or end-to-end tests), which, in their opinion, will be necessary and sufficient for testing new or changed functionality
- Tests should cover a successful execution, as well as some edge cases and possible errors
- As already mentioned, pull requests without tests will be considered more carefully by maintainers. If you are sure that in this situation the tests are not needed or cannot be implemented with a commensurate effort - please add this clarification message to your pull request
@@ -76,7 +76,7 @@ Unit tests are in the `__tests__` folder, and end-to-end tests are in the `workf
- CI will start automatically with some checks. Wait until the end of the execution and make sure that all checks passed successfully. If some checks fail, you can open them one by one, try to find the reason for failing and make changes to your code to resolve the problem
- Maintainers will review your pull request
- If a maintainer requests changes, first of all, try to think about his request critically and only after that implement and request another review
- If a maintainer requests changes, first of all, try to think about their request critically and only after that implement and request another review
- If your PR gets accepted, it will soon be merged into the main branch. But your contribution will take effect only after the release of a new version of the action and updating the major tag
> Sometimes maintainers reject pull requests and that's ok! Usually, along with rejection, we supply the reason for it. Nonetheless, we still really appreciate you taking the time to do it, and we don't take that lightly :heart:
+685 -527
View File
File diff suppressed because it is too large Load Diff
+14 -11
View File
@@ -1,9 +1,12 @@
{
"name": "setup-java",
"version": "4.0.0",
"version": "5.0.0",
"private": true,
"description": "setup java action",
"main": "dist/setup/index.js",
"engines": {
"node": ">=24.0.0"
},
"scripts": {
"build": "ncc build -o dist/setup src/setup-java.ts && ncc build -o dist/cleanup src/cleanup-java.ts",
"format": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --write \"**/*.{ts,yml,yaml}\"",
@@ -26,31 +29,31 @@
"author": "GitHub",
"license": "MIT",
"dependencies": {
"@actions/cache": "^3.2.4",
"@actions/cache": "^4.0.3",
"@actions/core": "^1.10.0",
"@actions/exec": "^1.0.4",
"@actions/glob": "^0.4.0",
"@actions/http-client": "^2.2.1",
"@actions/glob": "^0.5.0",
"@actions/http-client": "^2.2.3",
"@actions/io": "^1.0.2",
"@actions/tool-cache": "^2.0.1",
"semver": "^7.6.0",
"xmlbuilder2": "^2.4.0"
},
"devDependencies": {
"@types/jest": "^29.5.12",
"@types/node": "^20.11.24",
"@types/jest": "^29.5.14",
"@types/node": "^24.1.0",
"@types/semver": "^7.5.8",
"@typescript-eslint/eslint-plugin": "^5.54.0",
"@typescript-eslint/parser": "^5.54.0",
"@typescript-eslint/eslint-plugin": "^8.35.1",
"@typescript-eslint/parser": "^8.35.1",
"@vercel/ncc": "^0.38.1",
"eslint": "^8.57.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-jest": "^27.9.0",
"eslint-plugin-jest": "^29.0.1",
"eslint-plugin-node": "^11.1.0",
"jest": "^29.7.0",
"jest-circus": "^29.7.0",
"prettier": "^2.8.4",
"ts-jest": "^29.1.2",
"prettier": "^3.6.2",
"ts-jest": "^29.3.0",
"typescript": "^5.3.3"
},
"bugs": {
+1 -1
View File
@@ -98,7 +98,7 @@ async function computeCacheKey(
`No file in ${process.cwd()} matched to [${pattern}], make sure you have checked out the target repository`
);
}
return `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${packageManager.id}-${fileHash}`;
return `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${process.arch}-${packageManager.id}-${fileHash}`;
}
/**
+6 -3
View File
@@ -15,7 +15,8 @@ import {
import {
extractJdkFile,
getDownloadArchiveExtension,
isVersionSatisfies
isVersionSatisfies,
renameWinArchive
} from '../../util';
export enum AdoptImplementation {
@@ -73,11 +74,13 @@ export class AdoptDistribution extends JavaBase {
core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
);
const javaArchivePath = await tc.downloadTool(javaRelease.url);
let javaArchivePath = await tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`);
const extension = getDownloadArchiveExtension();
if (process.platform === 'win32') {
javaArchivePath = renameWinArchive(javaArchivePath);
}
const extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
const archiveName = fs.readdirSync(extractedJavaPath)[0];
+99 -1
View File
@@ -51,6 +51,22 @@ export abstract class JavaBase {
core.info(`Resolved Java ${foundJava.version} from tool-cache`);
} else {
core.info('Trying to resolve the latest version from remote');
const MAX_RETRIES = 4;
const RETRY_DELAY_MS = 2000;
const retryableCodes = [
'ETIMEDOUT',
'ECONNRESET',
'ENOTFOUND',
'ECONNREFUSED'
];
let retries = MAX_RETRIES;
while (retries > 0) {
try {
// Clear console timers before each attempt to prevent conflicts
if (retries < MAX_RETRIES && core.isDebug()) {
const consoleAny = console as any;
consoleAny._times?.clear?.();
}
const javaRelease = await this.findPackageForDownload(this.version);
core.info(`Resolved latest version as ${javaRelease.version}`);
if (foundJava?.version === javaRelease.version) {
@@ -60,8 +76,90 @@ export abstract class JavaBase {
foundJava = await this.downloadTool(javaRelease);
core.info(`Java ${foundJava.version} was downloaded`);
}
break;
} catch (error: any) {
retries--;
// Check if error is retryable (including aggregate errors)
const isRetryable =
(error instanceof tc.HTTPError &&
error.httpStatusCode &&
[429, 502, 503, 504].includes(error.httpStatusCode)) ||
retryableCodes.includes(error?.code) ||
(error?.errors &&
Array.isArray(error.errors) &&
error.errors.some((err: any) =>
retryableCodes.includes(err?.code)
));
if (retries > 0 && isRetryable) {
core.debug(
`Attempt failed due to network or timeout issues, initiating retry... (${retries} attempts left)`
);
await new Promise(r => setTimeout(r, RETRY_DELAY_MS));
continue;
}
if (error instanceof tc.HTTPError) {
if (error.httpStatusCode === 403) {
core.error('HTTP 403: Permission denied or access restricted.');
} else if (error.httpStatusCode === 429) {
core.warning(
'HTTP 429: Rate limit exceeded. Please retry later.'
);
} else {
core.error(`HTTP ${error.httpStatusCode}: ${error.message}`);
}
} else if (error && error.errors && Array.isArray(error.errors)) {
core.error(
`Java setup failed due to network or configuration error(s)`
);
if (error instanceof Error && error.stack) {
core.debug(error.stack);
}
for (const err of error.errors) {
const endpoint = err?.address || err?.hostname || '';
const port = err?.port ? `:${err.port}` : '';
const message = err?.message || 'Aggregate error';
const endpointInfo = !message.includes(endpoint)
? ` ${endpoint}${port}`
: '';
const localInfo =
err.localAddress && err.localPort
? ` - Local (${err.localAddress}:${err.localPort})`
: '';
const logMessage = `${message}${endpointInfo}${localInfo}`;
core.error(logMessage);
core.debug(`${err.stack || err.message}`);
Object.entries(err).forEach(([key, value]) => {
core.debug(`"${key}": ${JSON.stringify(value)}`);
});
}
} else {
const message =
error instanceof Error ? error.message : JSON.stringify(error);
core.error(`Java setup process failed due to: ${message}`);
if (typeof error?.code === 'string') {
core.debug(error.stack);
}
const errorDetails = {
name: error.name,
message: error.message,
...Object.getOwnPropertyNames(error)
.filter(prop => !['name', 'message', 'stack'].includes(prop))
.reduce<{[key: string]: any}>((acc, prop) => {
acc[prop] = error[prop];
return acc;
}, {})
};
Object.entries(errorDetails).forEach(([key, value]) => {
core.debug(`"${key}": ${JSON.stringify(value)}`);
});
}
throw error;
}
}
}
if (!foundJava) {
throw new Error('Failed to resolve Java version');
}
// JDK folder may contain postfix "Contents/Home" on macOS
const macOSPostfixPath = path.join(
foundJava.path,
+8 -7
View File
@@ -5,7 +5,8 @@ import path from 'path';
import {
extractJdkFile,
getDownloadArchiveExtension,
convertVersionToSemver
convertVersionToSemver,
renameWinArchive
} from '../../util';
import {JavaBase} from '../base-installer';
import {
@@ -29,14 +30,14 @@ export class CorrettoDistribution extends JavaBase {
core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
);
const javaArchivePath = await tc.downloadTool(javaRelease.url);
let javaArchivePath = await tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`);
const extractedJavaPath = await extractJdkFile(
javaArchivePath,
getDownloadArchiveExtension()
);
const extension = getDownloadArchiveExtension();
if (process.platform === 'win32') {
javaArchivePath = renameWinArchive(javaArchivePath);
}
const extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
const archiveName = fs.readdirSync(extractedJavaPath)[0];
const archivePath = path.join(extractedJavaPath, archiveName);
+9 -1
View File
@@ -11,6 +11,8 @@ import {CorrettoDistribution} from './corretto/installer';
import {OracleDistribution} from './oracle/installer';
import {DragonwellDistribution} from './dragonwell/installer';
import {SapMachineDistribution} from './sapmachine/installer';
import {GraalVMDistribution} from './graalvm/installer';
import {JetBrainsDistribution} from './jetbrains/installer';
enum JavaDistribution {
Adopt = 'adopt',
@@ -25,7 +27,9 @@ enum JavaDistribution {
Corretto = 'corretto',
Oracle = 'oracle',
Dragonwell = 'dragonwell',
SapMachine = 'sapmachine'
SapMachine = 'sapmachine',
GraalVM = 'graalvm',
JetBrains = 'jetbrains'
}
export function getJavaDistribution(
@@ -68,6 +72,10 @@ export function getJavaDistribution(
return new DragonwellDistribution(installerOptions);
case JavaDistribution.SapMachine:
return new SapMachineDistribution(installerOptions);
case JavaDistribution.GraalVM:
return new GraalVMDistribution(installerOptions);
case JavaDistribution.JetBrains:
return new JetBrainsDistribution(installerOptions);
default:
return null;
}
+8 -7
View File
@@ -11,7 +11,8 @@ import {
extractJdkFile,
getDownloadArchiveExtension,
getGitHubHttpHeaders,
isVersionSatisfies
isVersionSatisfies,
renameWinArchive
} from '../../util';
import {IDragonwellVersions, IDragonwellAllVersions} from './models';
import {
@@ -100,14 +101,14 @@ export class DragonwellDistribution extends JavaBase {
core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
);
const javaArchivePath = await tc.downloadTool(javaRelease.url);
let javaArchivePath = await tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`);
const extractedJavaPath = await extractJdkFile(
javaArchivePath,
getDownloadArchiveExtension()
);
const extension = getDownloadArchiveExtension();
if (process.platform === 'win32') {
javaArchivePath = renameWinArchive(javaArchivePath);
}
const extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
const archiveName = fs.readdirSync(extractedJavaPath)[0];
const archivePath = path.join(extractedJavaPath, archiveName);
+278
View File
@@ -0,0 +1,278 @@
import * as core from '@actions/core';
import * as tc from '@actions/tool-cache';
import fs from 'fs';
import path from 'path';
import {JavaBase} from '../base-installer';
import {HttpCodes} from '@actions/http-client';
import {GraalVMEAVersion} from './models';
import {
JavaDownloadRelease,
JavaInstallerOptions,
JavaInstallerResults
} from '../base-models';
import {
extractJdkFile,
getDownloadArchiveExtension,
getGitHubHttpHeaders,
renameWinArchive
} from '../../util';
const GRAALVM_DL_BASE = 'https://download.oracle.com/graalvm';
const IS_WINDOWS = process.platform === 'win32';
const GRAALVM_PLATFORM = IS_WINDOWS ? 'windows' : process.platform;
const GRAALVM_MIN_VERSION = 17;
const SUPPORTED_ARCHITECTURES = ['x64', 'aarch64'] as const;
type SupportedArchitecture = (typeof SUPPORTED_ARCHITECTURES)[number];
type OsVersions = 'linux' | 'macos' | 'windows';
export class GraalVMDistribution extends JavaBase {
constructor(installerOptions: JavaInstallerOptions) {
super('GraalVM', installerOptions);
}
protected async downloadTool(
javaRelease: JavaDownloadRelease
): Promise<JavaInstallerResults> {
try {
core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
);
let javaArchivePath = await tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`);
const extension = getDownloadArchiveExtension();
if (IS_WINDOWS) {
javaArchivePath = renameWinArchive(javaArchivePath);
}
const extractedJavaPath = await extractJdkFile(
javaArchivePath,
extension
);
// Add validation for extracted path
if (!fs.existsSync(extractedJavaPath)) {
throw new Error(
`Extraction failed: path ${extractedJavaPath} does not exist`
);
}
const dirContents = fs.readdirSync(extractedJavaPath);
if (dirContents.length === 0) {
throw new Error(
'Extraction failed: no files found in extracted directory'
);
}
const archivePath = path.join(extractedJavaPath, dirContents[0]);
const version = this.getToolcacheVersionName(javaRelease.version);
const javaPath = await tc.cacheDir(
archivePath,
this.toolcacheFolderName,
version,
this.architecture
);
return {version: javaRelease.version, path: javaPath};
} catch (error) {
core.error(`Failed to download and extract GraalVM: ${error}`);
throw error;
}
}
protected async findPackageForDownload(
range: string
): Promise<JavaDownloadRelease> {
// Add input validation
if (!range || typeof range !== 'string') {
throw new Error('Version range is required and must be a string');
}
const arch = this.distributionArchitecture();
if (!SUPPORTED_ARCHITECTURES.includes(arch as SupportedArchitecture)) {
throw new Error(
`Unsupported architecture: ${this.architecture}. Supported architectures are: ${SUPPORTED_ARCHITECTURES.join(', ')}`
);
}
if (!this.stable) {
return this.findEABuildDownloadUrl(`${range}-ea`);
}
if (this.packageType !== 'jdk') {
throw new Error('GraalVM provides only the `jdk` package type');
}
const platform = this.getPlatform();
const extension = getDownloadArchiveExtension();
const major = range.includes('.') ? range.split('.')[0] : range;
const majorVersion = parseInt(major);
if (isNaN(majorVersion)) {
throw new Error(`Invalid version format: ${range}`);
}
if (majorVersion < GRAALVM_MIN_VERSION) {
throw new Error(
`GraalVM is only supported for JDK ${GRAALVM_MIN_VERSION} and later. Requested version: ${major}`
);
}
const fileUrl = this.constructFileUrl(
range,
major,
platform,
arch,
extension
);
const response = await this.http.head(fileUrl);
this.handleHttpResponse(response, range);
return {url: fileUrl, version: range};
}
private constructFileUrl(
range: string,
major: string,
platform: string,
arch: string,
extension: string
): string {
return range.includes('.')
? `${GRAALVM_DL_BASE}/${major}/archive/graalvm-jdk-${range}_${platform}-${arch}_bin.${extension}`
: `${GRAALVM_DL_BASE}/${range}/latest/graalvm-jdk-${range}_${platform}-${arch}_bin.${extension}`;
}
private handleHttpResponse(response: any, range: string): void {
const statusCode = response.message.statusCode;
if (statusCode === HttpCodes.NotFound) {
throw new Error(
`Could not find GraalVM for SemVer ${range}. Please check if this version is available at ${GRAALVM_DL_BASE}`
);
}
if (
statusCode === HttpCodes.Unauthorized ||
statusCode === HttpCodes.Forbidden
) {
throw new Error(
`Access denied when downloading GraalVM. Status code: ${statusCode}. Please check your credentials or permissions.`
);
}
if (statusCode !== HttpCodes.OK) {
throw new Error(
`HTTP request for GraalVM failed with status code: ${statusCode} (${response.message.statusMessage || 'Unknown error'})`
);
}
}
private async findEABuildDownloadUrl(
javaEaVersion: string
): Promise<JavaDownloadRelease> {
core.debug(`Searching for EA build: ${javaEaVersion}`);
const versions = await this.fetchEAJson(javaEaVersion);
core.debug(`Found ${versions.length} EA versions`);
const latestVersion = versions.find(v => v.latest);
if (!latestVersion) {
core.error(
`Available versions: ${versions.map(v => v.version).join(', ')}`
);
throw new Error(`Unable to find latest version for '${javaEaVersion}'`);
}
core.debug(`Latest version found: ${latestVersion.version}`);
const arch = this.distributionArchitecture();
const file = latestVersion.files.find(
f => f.arch === arch && f.platform === GRAALVM_PLATFORM
);
if (!file) {
core.error(
`Available files for architecture ${arch}: ${JSON.stringify(latestVersion.files)}`
);
throw new Error(
`Unable to find file for architecture '${arch}' and platform '${GRAALVM_PLATFORM}'`
);
}
if (!file.filename.startsWith('graalvm-jdk-')) {
throw new Error(
`Invalid filename format: ${file.filename}. Expected to start with 'graalvm-jdk-'`
);
}
const downloadUrl = `${latestVersion.download_base_url}${file.filename}`;
core.debug(`Download URL: ${downloadUrl}`);
return {
url: downloadUrl,
version: latestVersion.version
};
}
private async fetchEAJson(
javaEaVersion: string
): Promise<GraalVMEAVersion[]> {
const url = `https://api.github.com/repos/graalvm/oracle-graalvm-ea-builds/contents/versions/${javaEaVersion}.json?ref=main`;
const headers = getGitHubHttpHeaders();
core.debug(
`Trying to fetch available version info for GraalVM EA builds from '${url}'`
);
try {
const response = await this.http.getJson<GraalVMEAVersion[]>(
url,
headers
);
if (!response.result) {
throw new Error(
`No GraalVM EA build found for version '${javaEaVersion}'. Please check if the version is correct.`
);
}
return response.result;
} catch (error) {
if (error instanceof Error) {
// Check if it's a 404 error (file not found)
if (error.message?.includes('404')) {
throw new Error(
`GraalVM EA version '${javaEaVersion}' not found. Please verify the version exists in the EA builds repository.`
);
}
// Re-throw with more context
throw new Error(
`Failed to fetch GraalVM EA version information for '${javaEaVersion}': ${error.message}`
);
}
// If it's not an Error instance, throw a generic error
throw new Error(
`Failed to fetch GraalVM EA version information for '${javaEaVersion}'`
);
}
}
public getPlatform(platform: NodeJS.Platform = process.platform): OsVersions {
const platformMap: Record<string, OsVersions> = {
darwin: 'macos',
win32: 'windows',
linux: 'linux'
};
const result = platformMap[platform];
if (!result) {
throw new Error(
`Platform '${platform}' is not supported. Supported platforms: 'linux', 'macos', 'windows'`
);
}
return result;
}
}
+14
View File
@@ -0,0 +1,14 @@
export type OsVersions = 'linux' | 'macos' | 'windows';
export interface GraalVMEAFile {
filename: string;
arch: 'aarch64' | 'x64';
platform: 'darwin' | 'linux' | 'windows';
}
export interface GraalVMEAVersion {
version: string;
latest?: boolean;
download_base_url: string;
files: GraalVMEAFile[];
}
+246
View File
@@ -0,0 +1,246 @@
import * as core from '@actions/core';
import * as tc from '@actions/tool-cache';
import fs from 'fs';
import path from 'path';
import semver from 'semver';
import {JavaBase} from '../base-installer';
import {IJetBrainsRawVersion, IJetBrainsVersion} from './models';
import {
JavaDownloadRelease,
JavaInstallerOptions,
JavaInstallerResults
} from '../base-models';
import {extractJdkFile, isVersionSatisfies} from '../../util';
import {OutgoingHttpHeaders} from 'http';
import {HttpCodes} from '@actions/http-client';
export class JetBrainsDistribution extends JavaBase {
constructor(installerOptions: JavaInstallerOptions) {
super('JetBrains', installerOptions);
}
protected async findPackageForDownload(
range: string
): Promise<JavaDownloadRelease> {
const versionsRaw = await this.getAvailableVersions();
const versions = versionsRaw.map(v => {
const formattedVersion = `${v.semver}+${v.build}`;
return {
version: formattedVersion,
url: v.url
} as JavaDownloadRelease;
});
const satisfiedVersions = versions
.filter(item => isVersionSatisfies(range, item.version))
.sort((a, b) => {
return -semver.compareBuild(a.version, b.version);
});
const resolvedFullVersion =
satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) {
const availableOptions = versionsRaw
.map(item => `${item.tag_name} (${item.semver}+${item.build})`)
.join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(
`Could not find satisfied version for SemVer '${range}'. ${availableOptionsMessage}`
);
}
return resolvedFullVersion;
}
protected async downloadTool(
javaRelease: JavaDownloadRelease
): Promise<JavaInstallerResults> {
core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
);
const javaArchivePath = await tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`);
const extractedJavaPath = await extractJdkFile(javaArchivePath, 'tar.gz');
const archiveName = fs.readdirSync(extractedJavaPath)[0];
const archivePath = path.join(extractedJavaPath, archiveName);
const version = this.getToolcacheVersionName(javaRelease.version);
const javaPath = await tc.cacheDir(
archivePath,
this.toolcacheFolderName,
version,
this.architecture
);
return {version: javaRelease.version, path: javaPath};
}
private async getAvailableVersions(): Promise<IJetBrainsVersion[]> {
const platform = this.getPlatformOption();
const arch = this.distributionArchitecture();
if (core.isDebug()) {
console.time('Retrieving available versions for JBR took'); // eslint-disable-line no-console
}
// need to iterate through all pages to retrieve the list of all versions
// GitHub API doesn't provide way to retrieve the count of pages to iterate so infinity loop
let page_index = 1;
const rawVersions: IJetBrainsRawVersion[] = [];
const bearerToken = process.env.GITHUB_TOKEN;
while (true) {
const requestArguments = `per_page=100&page=${page_index}`;
const requestHeaders: OutgoingHttpHeaders = {};
if (bearerToken) {
requestHeaders['Authorization'] = `Bearer ${bearerToken}`;
}
const rawUrl = `https://api.github.com/repos/JetBrains/JetBrainsRuntime/releases?${requestArguments}`;
if (core.isDebug() && page_index === 1) {
// url is identical except page_index so print it once for debug
core.debug(`Gathering available versions from '${rawUrl}'`);
}
const paginationPageResult = (
await this.http.getJson<IJetBrainsRawVersion[]>(rawUrl, requestHeaders)
).result;
if (!paginationPageResult || paginationPageResult.length === 0) {
// break infinity loop because we have reached end of pagination
break;
}
const paginationPage: IJetBrainsRawVersion[] =
paginationPageResult.filter(version =>
this.stable ? !version.prerelease : version.prerelease
);
if (!paginationPage || paginationPage.length === 0) {
// break infinity loop because we have reached end of pagination
break;
}
rawVersions.push(...paginationPage);
page_index++;
}
if (this.stable) {
// Add versions not available from the API but are downloadable
const hidden = ['11_0_10b1145.115', '11_0_11b1341.60'];
rawVersions.push(
...hidden.map(tag => ({tag_name: tag, name: tag, prerelease: false}))
);
}
const versions0 = rawVersions.map(async v => {
// Release tags look like one of these:
// jbr-release-21.0.3b465.3
// jbr17-b87.7
// jb11_0_11-b87.7
// jbr11_0_15b2043.56
// 11_0_11b1536.2
// 11_0_11-b1522
const tag = v.tag_name;
// Extract version string
const vstring = tag
.replace('jbr-release-', '')
.replace('jbr', '')
.replace('jb', '')
.replace('-', '');
const vsplit = vstring.split('b');
let semver = vsplit[0];
const build = vsplit[1];
// Normalize semver
if (!semver.includes('.') && !semver.includes('_'))
semver = `${semver}.0.0`;
// Construct URL
let type: string;
switch (this.packageType ?? '') {
case 'jre':
type = 'jbr';
break;
case 'jdk+jcef':
type = 'jbrsdk_jcef';
break;
case 'jre+jcef':
type = 'jbr_jcef';
break;
case 'jdk+ft':
type = 'jbrsdk_ft';
break;
case 'jre+ft':
type = 'jbr_ft';
break;
default:
type = 'jbrsdk';
break;
}
let url = `https://cache-redirector.jetbrains.com/intellij-jbr/${type}-${semver}-${platform}-${arch}-b${build}.tar.gz`;
let include = false;
const res = await this.http.head(url);
if (res.message.statusCode === HttpCodes.OK) {
include = true;
} else {
url = `https://cache-redirector.jetbrains.com/intellij-jbr/${type}_nomod-${semver}-${platform}-${arch}-b${build}.tar.gz`;
const res2 = await this.http.head(url);
if (res2.message.statusCode === HttpCodes.OK) {
include = true;
}
}
const version = {
tag_name: tag,
semver: semver.replace(/_/g, '.'),
build: build,
url: url
} as IJetBrainsVersion;
return {
item: version,
include: include
};
});
const versions = await Promise.all(versions0).then(res =>
res.filter(item => item.include).map(item => item.item)
);
if (core.isDebug()) {
core.startGroup('Print information about available versions');
console.timeEnd('Retrieving available versions for JBR took'); // eslint-disable-line no-console
core.debug(`Available versions: [${versions.length}]`);
core.debug(versions.map(item => item.semver).join(', '));
core.endGroup();
}
return versions;
}
private getPlatformOption(): string {
// Jetbrains has own platform names so need to map them
switch (process.platform) {
case 'darwin':
return 'osx';
case 'win32':
return 'windows';
default:
return process.platform;
}
}
}
+14
View File
@@ -0,0 +1,14 @@
// Raw Model from https://api.github.com/repos/JetBrains/JetBrainsRuntime/releases
export interface IJetBrainsRawVersion {
tag_name: string;
name: string;
prerelease: boolean;
}
export interface IJetBrainsVersion {
tag_name: string;
semver: string;
build: string;
url: string;
}
+4 -8
View File
@@ -8,7 +8,8 @@ import semver from 'semver';
import {
extractJdkFile,
getDownloadArchiveExtension,
isVersionSatisfies
isVersionSatisfies,
renameWinArchive
} from '../../util';
import * as core from '@actions/core';
import {ArchitectureOptions, LibericaVersion, OsVersions} from './models';
@@ -35,13 +36,8 @@ export class LibericaDistributions extends JavaBase {
core.info(`Extracting Java archive...`);
const extension = getDownloadArchiveExtension();
if (
process.platform === 'win32' &&
(this.architecture === 'arm64' || this.architecture === 'aarch64')
) {
const javaArchivePathRenamed = `${javaArchivePath}.zip`;
await fs.renameSync(javaArchivePath, javaArchivePathRenamed);
javaArchivePath = javaArchivePathRenamed;
if (process.platform === 'win32') {
javaArchivePath = renameWinArchive(javaArchivePath);
}
const extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
+6 -15
View File
@@ -7,7 +7,8 @@ import {
import {
extractJdkFile,
getDownloadArchiveExtension,
getGitHubHttpHeaders
getGitHubHttpHeaders,
renameWinArchive
} from '../../util';
import * as core from '@actions/core';
import * as tc from '@actions/tool-cache';
@@ -27,22 +28,12 @@ export class MicrosoftDistributions extends JavaBase {
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
);
let javaArchivePath = await tc.downloadTool(javaRelease.url);
// Rename archive to add extension because after downloading
// archive does not contain extension type and it leads to some issues
// on Windows runners without PowerShell Core.
//
// For default PowerShell Windows it should contain extension type to unpack it.
if (
process.platform === 'win32' &&
(this.architecture === 'arm64' || this.architecture === 'aarch64')
) {
const javaArchivePathRenamed = `${javaArchivePath}.zip`;
await fs.renameSync(javaArchivePath, javaArchivePathRenamed);
javaArchivePath = javaArchivePathRenamed;
}
core.info(`Extracting Java archive...`);
const extension = getDownloadArchiveExtension();
if (process.platform === 'win32') {
javaArchivePath = renameWinArchive(javaArchivePath);
}
const extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
const archiveName = fs.readdirSync(extractedJavaPath)[0];
@@ -125,7 +116,7 @@ export class MicrosoftDistributions extends JavaBase {
}
} catch (err) {
core.debug(
`Http request for microsoft-openjdk-versions.json failed with status code: ${response?.statusCode}`
`Http request for microsoft-openjdk-versions.json failed with status code: ${response?.statusCode}. Error: ${err}`
);
return null;
}
@@ -1,4 +1,47 @@
[
{
"version": "25.0.0",
"stable": true,
"release_url": "https://aka.ms/download-jdk",
"files": [
{
"filename": "microsoft-jdk-25.0.0-macos-x64.tar.gz",
"arch": "x64",
"platform": "darwin",
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-25.0.0-macos-x64.tar.gz"
},
{
"filename": "microsoft-jdk-25.0.0-linux-x64.tar.gz",
"arch": "x64",
"platform": "linux",
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-25.0.0-linux-x64.tar.gz"
},
{
"filename": "microsoft-jdk-25.0.0-windows-x64.zip",
"arch": "x64",
"platform": "win32",
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-25.0.0-windows-x64.zip"
},
{
"filename": "microsoft-jdk-25.0.0-macos-aarch64.tar.gz",
"arch": "aarch64",
"platform": "darwin",
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-25.0.0-macos-aarch64.tar.gz"
},
{
"filename": "microsoft-jdk-25.0.0-linux-aarch64.tar.gz",
"arch": "aarch64",
"platform": "linux",
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-25.0.0-linux-aarch64.tar.gz"
},
{
"filename": "microsoft-jdk-25.0.0-windows-aarch64.zip",
"arch": "aarch64",
"platform": "win32",
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-25.0.0-windows-aarch64.zip"
}
]
},
{
"version": "21.0.2",
"stable": true,
+9 -3
View File
@@ -10,7 +10,11 @@ import {
JavaInstallerOptions,
JavaInstallerResults
} from '../base-models';
import {extractJdkFile, getDownloadArchiveExtension} from '../../util';
import {
extractJdkFile,
getDownloadArchiveExtension,
renameWinArchive
} from '../../util';
import {HttpCodes} from '@actions/http-client';
const ORACLE_DL_BASE = 'https://download.oracle.com/java';
@@ -26,11 +30,13 @@ export class OracleDistribution extends JavaBase {
core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
);
const javaArchivePath = await tc.downloadTool(javaRelease.url);
let javaArchivePath = await tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`);
const extension = getDownloadArchiveExtension();
if (process.platform === 'win32') {
javaArchivePath = renameWinArchive(javaArchivePath);
}
const extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
const archiveName = fs.readdirSync(extractedJavaPath)[0];
+10 -11
View File
@@ -8,8 +8,8 @@ import {
convertVersionToSemver,
extractJdkFile,
getDownloadArchiveExtension,
getGitHubHttpHeaders,
isVersionSatisfies
isVersionSatisfies,
renameWinArchive
} from '../../util';
import {JavaBase} from '../base-installer';
import {
@@ -63,13 +63,12 @@ export class SapMachineDistribution extends JavaBase {
const arch = this.distributionArchitecture();
let fetchedReleasesJson = await this.fetchReleasesFromUrl(
'https://sap.github.io/SapMachine/assets/data/sapmachine-releases-all.json'
'https://sapmachine.io/assets/data/sapmachine-releases-all.json'
);
if (!fetchedReleasesJson) {
fetchedReleasesJson = await this.fetchReleasesFromUrl(
'https://api.github.com/repos/SAP/SapMachine/contents/assets/data/sapmachine-releases-all.json?ref=gh-pages',
getGitHubHttpHeaders()
'https://sap.github.io/SapMachine/assets/data/sapmachine-releases-all.json'
);
}
@@ -104,14 +103,14 @@ export class SapMachineDistribution extends JavaBase {
core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
);
const javaArchivePath = await tc.downloadTool(javaRelease.url);
let javaArchivePath = await tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`);
const extractedJavaPath = await extractJdkFile(
javaArchivePath,
getDownloadArchiveExtension()
);
const extension = getDownloadArchiveExtension();
if (process.platform === 'win32') {
javaArchivePath = renameWinArchive(javaArchivePath);
}
const extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
const archiveName = fs.readdirSync(extractedJavaPath)[0];
const archivePath = path.join(extractedJavaPath, archiveName);
+6 -3
View File
@@ -8,7 +8,8 @@ import semver from 'semver';
import {
extractJdkFile,
getDownloadArchiveExtension,
isVersionSatisfies
isVersionSatisfies,
renameWinArchive
} from '../../util';
import * as core from '@actions/core';
import * as tc from '@actions/tool-cache';
@@ -98,11 +99,13 @@ export class SemeruDistribution extends JavaBase {
core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
);
const javaArchivePath = await tc.downloadTool(javaRelease.url);
let javaArchivePath = await tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`);
const extension = getDownloadArchiveExtension();
if (process.platform === 'win32') {
javaArchivePath = renameWinArchive(javaArchivePath);
}
const extractedJavaPath: string = await extractJdkFile(
javaArchivePath,
extension
+6 -3
View File
@@ -15,7 +15,8 @@ import {
import {
extractJdkFile,
getDownloadArchiveExtension,
isVersionSatisfies
isVersionSatisfies,
renameWinArchive
} from '../../util';
export enum TemurinImplementation {
@@ -76,11 +77,13 @@ export class TemurinDistribution extends JavaBase {
core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
);
const javaArchivePath = await tc.downloadTool(javaRelease.url);
let javaArchivePath = await tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`);
const extension = getDownloadArchiveExtension();
if (process.platform === 'win32') {
javaArchivePath = renameWinArchive(javaArchivePath);
}
const extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
const archiveName = fs.readdirSync(extractedJavaPath)[0];
+4 -8
View File
@@ -11,7 +11,8 @@ import {
extractJdkFile,
getDownloadArchiveExtension,
convertVersionToSemver,
isVersionSatisfies
isVersionSatisfies,
renameWinArchive
} from '../../util';
import {
JavaDownloadRelease,
@@ -80,13 +81,8 @@ export class ZuluDistribution extends JavaBase {
core.info(`Extracting Java archive...`);
const extension = getDownloadArchiveExtension();
if (
process.platform === 'win32' &&
(this.architecture === 'arm64' || this.architecture === 'aarch64')
) {
const javaArchivePathRenamed = `${javaArchivePath}.zip`;
await fs.renameSync(javaArchivePath, javaArchivePathRenamed);
javaArchivePath = javaArchivePathRenamed;
if (process.platform === 'win32') {
javaArchivePath = renameWinArchive(javaArchivePath);
}
const extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
+2 -3
View File
@@ -59,9 +59,8 @@ export async function createToolchainsSettings({
// when an alternate m2 location is specified use only that location (no .m2 directory)
// otherwise use the home/.m2/ path
await io.mkdirP(settingsDirectory);
const originalToolchains = await readExistingToolchainsFile(
settingsDirectory
);
const originalToolchains =
await readExistingToolchainsFile(settingsDirectory);
const updatedToolchains = generateToolchainDefinition(
originalToolchains,
jdkInfo.version,
+30 -9
View File
@@ -92,7 +92,13 @@ export function isGhes(): boolean {
const ghUrl = new URL(
process.env['GITHUB_SERVER_URL'] || 'https://github.com'
);
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
const hostname = ghUrl.hostname.trimEnd().toUpperCase();
const isGitHubHost = hostname === 'GITHUB.COM';
const isGitHubEnterpriseCloudHost = hostname.endsWith('.GHE.COM');
const isLocalHost = hostname.endsWith('.LOCALHOST');
return !isGitHubHost && !isGitHubEnterpriseCloudHost && !isLocalHost;
}
export function isCacheFeatureAvailable(): boolean {
@@ -127,21 +133,25 @@ export function getVersionFromFileContent(
const versionFileName = getFileName(versionFile);
if (versionFileName == '.tool-versions') {
javaVersionRegExp =
/^(java\s+)(?:\S*-)?v?(?<version>(\d+)(\.\d+)?(\.\d+)?(\+\d+)?(-ea(\.\d+)?)?)$/m;
/^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;
} else {
javaVersionRegExp = /(?<version>(?<=(^|\s|-))(\d+\S*))(\s|$)/;
}
const fileContent = content.match(javaVersionRegExp)?.groups?.version
const capturedVersion = content.match(javaVersionRegExp)?.groups?.version
? (content.match(javaVersionRegExp)?.groups?.version as string)
: '';
if (!fileContent) {
core.debug(
`Parsed version '${capturedVersion}' from file '${versionFileName}'`
);
if (!capturedVersion) {
return null;
}
core.debug(`Version from file '${fileContent}'`);
const tentativeVersion = avoidOldNotation(fileContent);
const tentativeVersion = avoidOldNotation(capturedVersion);
const rawVersion = tentativeVersion.split('-')[0];
let version = semver.validRange(rawVersion)
@@ -178,8 +188,8 @@ export function convertVersionToSemver(version: number[] | string) {
}
export function getGitHubHttpHeaders(): OutgoingHttpHeaders {
const token = core.getInput('token');
const auth = !token ? undefined : `token ${token}`;
const resolvedToken = core.getInput('token') || process.env.GITHUB_TOKEN;
const auth = !resolvedToken ? undefined : `token ${resolvedToken}`;
const headers: OutgoingHttpHeaders = {
accept: 'application/vnd.github.VERSION.raw'
@@ -190,3 +200,14 @@ export function getGitHubHttpHeaders(): OutgoingHttpHeaders {
}
return headers;
}
// Rename archive to add extension because after downloading
// archive does not contain extension type and it leads to some issues
// on Windows runners without PowerShell Core.
//
// For default PowerShell Windows it should contain extension type to unpack it.
export function renameWinArchive(javaArchivePath: string): string {
const javaArchivePathRenamed = `${javaArchivePath}.zip`;
fs.renameSync(javaArchivePath, javaArchivePathRenamed);
return javaArchivePathRenamed;
}