Merge "v2-preview" branch into "main" (#150)

* actions/setup-java@v2 - Support different distributions (#132)

* Implement support for custom vendors in setup-java

* minor improvements

* minor refactoring

* Add unit tests and e2e tests

* Update documentation for setup-java@v2 release

* minor improvements

* regenerate dist

* fix comments

* resolve comments

* resolve comments

* fix tests

* Update README.md

Co-authored-by: George Adams <george.adams@microsoft.com>

* Apply suggestions from code review

Co-authored-by: Konrad Pabjan <konradpabjan@github.com>

* fix minor nitpicks

* handle 4th digit

* pull latest main

* Update README.md

* rename adoptium to adopt

* rename adoptium to adopt

* rename adoptium to adopt

* Update README.md

* make java-version and distribution required for action

* update readme

* fix tests

* fix e2e tests

Co-authored-by: George Adams <george.adams@microsoft.com>
Co-authored-by: Konrad Pabjan <konradpabjan@github.com>

* Add "overwrite-settings" input parameter (#136)

* add overwrite-settings parameter

* fix e2e tests

* print debug

* fix e2e tests

* add comment

* remove comment

* Add "Contents/Home" postfix on macOS if provider creates it (#139)

* Update e2e-versions.yml

* Update e2e-versions.yml

* implement fix

* Update e2e-versions.yml

* Update installer.ts

* fix filter logic

* Update e2e-versions.yml

* remove extra logic

* Update e2e-versions.yml

* Add check-latest flag (#141)

* add changes for check-latest

* run prerelease script

* resolving comments

* fixing tests

* fix spelling

* improve core.info messages

* run format

* run prerelease

* change version to fix test

* resolve comment for check-latest

* Update README.md

* added hosted tool cache section

* Apply suggestions from code review

Co-authored-by: Maxim Lobanov <v-malob@microsoft.com>
Co-authored-by: Konrad Pabjan <konradpabjan@github.com>

* Avoid "+" sign in Java path in v2-preview (#145)

* try to handle _ versions

* more logs

* more debug

* test 1

* more fixes

* fix typo

* Update e2e-versions.yml

* add unit-tests

* remove debug info from tests

* debug pre-cached versions

* change e2e tests to ubuntu-latest

* update npm licenses

Co-authored-by: George Adams <george.adams@microsoft.com>
Co-authored-by: Konrad Pabjan <konradpabjan@github.com>
Co-authored-by: Dmitry Shibanov <dmitry-shibanov@github.com>
This commit is contained in:
Maxim Lobanov 2021-04-05 13:02:27 +03:00 committed by GitHub
parent ebb424f2cb
commit b53500dabc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
67 changed files with 40562 additions and 22007 deletions

34
.github/workflows/build.yml vendored Executable file

@ -0,0 +1,34 @@
name: Build Action
on:
push:
branches:
- main
- releases/*
- v2-preview
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v2
- name: Setup Node.JS 12
uses: actions/setup-node@v2
with:
node-version: 12.x
- run: npm ci
- run: npm run build
- run: npm run format-check
- run: npm test
- name: Verify no unstaged changes
if: runner.os != 'windows'
run: bash __tests__/verify-no-unstaged-changes.sh

87
.github/workflows/e2e-local-file.yml vendored Normal file

@ -0,0 +1,87 @@
name: Validate local file
on:
push:
branches:
- main
- releases/*
- v2-preview
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
setup-java-local-file-adopt:
name: Validate installation from local file Adopt
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Download Adopt OpenJDK file
run: |
if ($IsLinux) {
$downloadUrl = "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.10_9.tar.gz"
$localFilename = "java_package.tar.gz"
} elseif ($IsMacOS) {
$downloadUrl = "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_mac_hotspot_11.0.10_9.tar.gz"
$localFilename = "java_package.tar.gz"
} elseif ($IsWindows) {
$downloadUrl = "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_windows_hotspot_11.0.10_9.zip"
$localFilename = "java_package.zip"
}
echo "LocalFilename=$localFilename" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
(New-Object System.Net.WebClient).DownloadFile($downloadUrl, "$env:RUNNER_TEMP/$localFilename")
shell: pwsh
- name: setup-java
uses: ./
id: setup-java
with:
distribution: 'jdkfile'
jdkFile: ${{ runner.temp }}/${{ env.LocalFilename }}
java-version: '11.0.0-ea'
architecture: x64
- name: Verify Java version
run: bash __tests__/verify-java.sh "11.0.10" "${{ steps.setup-java.outputs.path }}"
shell: bash
setup-java-local-file-zulu:
name: Validate installation from local file Zulu
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Download Zulu OpenJDK file
run: |
if ($IsLinux) {
$downloadUrl = "https://cdn.azul.com/zulu/bin/zulu11.2.3-jdk11.0.1-linux_x64.tar.gz"
$localFilename = "java_package.tar.gz"
} elseif ($IsMacOS) {
$downloadUrl = "https://cdn.azul.com/zulu/bin/zulu11.2.3-jdk11.0.1-macosx_x64.tar.gz"
$localFilename = "java_package.tar.gz"
} elseif ($IsWindows) {
$downloadUrl = "https://cdn.azul.com/zulu/bin/zulu11.45.27-ca-jdk11.0.10-win_x64.zip"
$localFilename = "java_package.zip"
}
echo "LocalFilename=$localFilename" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
(New-Object System.Net.WebClient).DownloadFile($downloadUrl, "$env:RUNNER_TEMP/$localFilename")
shell: pwsh
- name: setup-java
uses: ./
id: setup-java
with:
distribution: 'jdkfile'
jdkFile: ${{ runner.temp }}/${{ env.LocalFilename }}
java-version: '11.0.0-ea'
architecture: x64
- name: Verify Java version
run: bash __tests__/verify-java.sh "11.0" "${{ steps.setup-java.outputs.path }}"
shell: bash

153
.github/workflows/e2e-publishing.yml vendored Normal file

@ -0,0 +1,153 @@
name: Validate publishing functionality
on:
push:
branches:
- main
- releases/*
- v2-preview
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
defaults:
run:
shell: pwsh
jobs:
setup-java-publishing:
name: Validate settings.xml
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: setup-java
uses: ./
id: setup-java
with:
distribution: 'adopt'
java-version: '11'
server-id: maven
server-username: MAVEN_USERNAME
server-password: MAVEN_CENTRAL_TOKEN
gpg-passphrase: MAVEN_GPG_PASSPHRASE
- name: Validate settings.xml
run: |
$xmlPath = Join-Path $HOME ".m2" "settings.xml"
Get-Content $xmlPath | ForEach-Object { Write-Host $_ }
[xml]$xml = Get-Content $xmlPath
$servers = $xml.settings.servers.server
if (($servers[0].id -ne 'maven') -or ($servers[0].username -ne '${env.MAVEN_USERNAME}') -or ($servers[0].password -ne '${env.MAVEN_CENTRAL_TOKEN}')) {
throw "Generated XML file is incorrect"
}
if (($servers[1].id -ne 'gpg.passphrase') -or ($servers[1].passphrase -ne '${env.MAVEN_GPG_PASSPHRASE}')) {
throw "Generated XML file is incorrect"
}
test-publishing-overwrite:
name: settings.xml is overwritten if flag is true
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Create fake settings.xml
run: |
$xmlDirectory = Join-Path $HOME ".m2"
$xmlPath = Join-Path $xmlDirectory "settings.xml"
New-Item -Path $xmlDirectory -ItemType Directory
Set-Content -Path $xmlPath -Value "Fake_XML"
- name: setup-java
uses: ./
id: setup-java
with:
distribution: 'adopt'
java-version: '11'
server-id: maven
server-username: MAVEN_USERNAME
server-password: MAVEN_CENTRAL_TOKEN
gpg-passphrase: MAVEN_GPG_PASSPHRASE
- name: Validate settings.xml is overwritten
run: |
$xmlPath = Join-Path $HOME ".m2" "settings.xml"
Get-Content $xmlPath | ForEach-Object { Write-Host $_ }
$content = Get-Content $xmlPath -Raw
if ($content -notlike '*maven*') {
throw "settings.xml file is not overwritten"
}
test-publishing-skip-overwrite:
name: settings.xml is not overwritten if flag is false
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Create fake settings.xml
run: |
$xmlDirectory = Join-Path $HOME ".m2"
$xmlPath = Join-Path $xmlDirectory "settings.xml"
New-Item -Path $xmlDirectory -ItemType Directory
Set-Content -Path $xmlPath -Value "Fake_XML"
- name: setup-java
uses: ./
id: setup-java
with:
distribution: 'adopt'
java-version: '11'
server-id: maven
server-username: MAVEN_USERNAME
server-password: MAVEN_CENTRAL_TOKEN
overwrite-settings: false
gpg-passphrase: MAVEN_GPG_PASSPHRASE
- name: Validate that settings.xml is not overwritten
run: |
$xmlPath = Join-Path $HOME ".m2" "settings.xml"
$content = Get-Content -Path $xmlPath -Raw
Write-Host $content
if ($content -notlike "*Fake_XML*") {
throw "settings.xml file was overwritten but it should not be"
}
test-publishing-custom-location:
name: settings.xml in custom location
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: setup-java
uses: ./
id: setup-java
with:
distribution: 'adopt'
java-version: '11'
server-id: maven
server-username: MAVEN_USERNAME
server-password: MAVEN_CENTRAL_TOKEN
gpg-passphrase: MAVEN_GPG_PASSPHRASE
settings-path: ${{ runner.temp }}
- name: Validate settings.xml location
run: |
$path = Join-Path $env:RUNNER_TEMP "settings.xml"
if (-not (Test-Path $path)) {
throw "settings.xml file is not found in expected location"
}

198
.github/workflows/e2e-versions.yml vendored Normal file

@ -0,0 +1,198 @@
name: Validate Java e2e
on:
push:
branches:
- main
- releases/*
- v2-preview
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
setup-java-major-versions:
name: ${{ matrix.distribution }} ${{ matrix.version }} (jdk-x64) - ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['adopt', 'zulu']
version: ['8', '11', '15']
steps:
- name: Checkout
uses: actions/checkout@v2
- name: setup-java
uses: ./
id: setup-java
with:
java-version: ${{ matrix.version }}
distribution: ${{ matrix.distribution }}
- name: Verify Java
run: bash __tests__/verify-java.sh "${{ matrix.version }}" "${{ steps.setup-java.outputs.path }}"
shell: bash
setup-java-major-minor-versions:
name: ${{ matrix.distribution }} ${{ matrix.version }} (jdk-x64) - ${{ matrix.os }}
needs: setup-java-major-versions
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['adopt', 'zulu']
version:
- '11.0'
- '8.0.282'
- '11.0.2+7'
include:
- distribution: 'adopt'
version: '12.0.2+10.1'
os: macos-latest
- distribution: 'adopt'
version: '12.0.2+10.1'
os: windows-latest
- distribution: 'adopt'
version: '12.0.2+10.1'
os: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: setup-java
uses: ./
id: setup-java
with:
java-version: ${{ matrix.version }}
distribution: ${{ matrix.distribution }}
- name: Verify Java
run: bash __tests__/verify-java.sh "${{ matrix.version }}" "${{ steps.setup-java.outputs.path }}"
shell: bash
setup-java-check-latest:
name: ${{ matrix.distribution }} ${{ matrix.version }} - check-latest flag - ${{ matrix.os }}
needs: setup-java-major-versions
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['adopt', 'zulu']
steps:
- name: Checkout
uses: actions/checkout@v2
- name: setup-java
uses: ./
id: setup-java
with:
distribution: ${{ matrix.distribution }}
java-version: 11
check-latest: true
- name: Verify Java
run: bash __tests__/verify-java.sh "11" "${{ steps.setup-java.outputs.path }}"
shell: bash
setup-java-ea-versions-zulu:
name: zulu ${{ matrix.version }} (jdk-x64) - ${{ matrix.os }}
needs: setup-java-major-minor-versions
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
version: ['17-ea', '15.0.0-ea.14']
steps:
- name: Checkout
uses: actions/checkout@v2
- name: setup-java
uses: ./
id: setup-java
with:
java-version: ${{ matrix.version }}
distribution: zulu
- name: Verify Java
run: bash __tests__/verify-java.sh "${{ matrix.version }}" "${{ steps.setup-java.outputs.path }}"
shell: bash
setup-java-ea-versions-adopt:
name: adopt ${{ matrix.version }} (jdk-x64) - ${{ matrix.os }}
needs: setup-java-major-minor-versions
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
version: ['17-ea', '15.0.0-ea.14.1.202003160455']
steps:
- name: Checkout
uses: actions/checkout@v2
- name: setup-java
uses: ./
id: setup-java
with:
java-version: ${{ matrix.version }}
distribution: adopt
- name: Verify Java
run: bash __tests__/verify-java.sh "${{ matrix.version }}" "${{ steps.setup-java.outputs.path }}"
shell: bash
setup-java-custom-package-type:
name: ${{ matrix.distribution }} ${{ matrix.version }} (${{ matrix.java-package }}-x64) - ${{ matrix.os }}
needs: setup-java-major-minor-versions
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['adopt', 'zulu']
java-package: ['jre']
version:
- '15.0'
include:
- distribution: 'zulu'
java-package: jre+fx
version: '8'
os: ubuntu-latest
- distribution: 'zulu'
java-package: jdk+fx
version: '8.0.242'
os: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: setup-java
uses: ./
id: setup-java
with:
java-version: ${{ matrix.version }}
java-package: ${{ matrix.java-package }}
distribution: ${{ matrix.distribution }}
- name: Verify Java
run: bash __tests__/verify-java.sh "${{ matrix.version }}" "${{ steps.setup-java.outputs.path }}"
shell: bash
setup-java-custom-architecture:
name: ${{ matrix.distribution }} ${{ matrix.version }} (jdk-x86) - ${{ matrix.os }}
needs: setup-java-major-minor-versions
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
# Only Zulu provides x86 arch for now and only for windows / ubuntu
os: [windows-latest, ubuntu-latest]
distribution: ['zulu']
version: ['11']
steps:
- name: Checkout
uses: actions/checkout@v2
- name: setup-java
uses: ./
id: setup-java
with:
distribution: ${{ matrix.distribution }}
java-version: ${{ matrix.version }}
architecture: x86
- name: Verify Java
run: bash __tests__/verify-java.sh "${{ matrix.version }}" "${{ steps.setup-java.outputs.path }}"
shell: bash

@ -1,88 +0,0 @@
name: Main workflow
on: [push, pull_request]
jobs:
build:
runs-on: ${{ matrix.operating-system }}
strategy:
matrix:
operating-system: [ubuntu-latest, windows-latest]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Node.js 12
uses: actions/setup-node@v1
with:
node-version: 12.x
- name: npm install
run: npm install
- name: Lint
run: npm run format-check
- name: npm test
run: npm test
test:
runs-on: ${{ matrix.operating-system }}
strategy:
matrix:
operating-system: [ubuntu-latest, windows-latest]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Clear tool cache
if: runner.os != 'windows'
run: mv "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old"
- name: Clear tool cache (Windows)
if: runner.os == 'windows'
run: move "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old"
- name: Setup Java 13
id: setup-java
uses: ./
with:
java-version: 13.0.2
- name: Verify Java 13
if: runner.os != 'windows'
run: __tests__/verify-java.sh 13.0.2 "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}"
- name: Verify Java 13 (Windows)
if: runner.os == 'windows'
run: __tests__/verify-java.ps1 13.0.2 "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}"
test-proxy:
runs-on: ubuntu-latest
container:
image: ubuntu:latest
options: --dns 127.0.0.1
services:
squid-proxy:
image: datadog/squid:latest
ports:
- 3128:3128
env:
https_proxy: http://squid-proxy:3128
steps:
- uses: actions/checkout@v2
- name: Clear tool cache
run: rm -rf $RUNNER_TOOL_CACHE/*
- name: Setup Java 13
id: setup-java
uses: ./
with:
java-version: 13.0.2
- name: Verify Java 13
run: __tests__/verify-java.sh 13.0.2 "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}"
test-bypass-proxy:
runs-on: ubuntu-latest
env:
https_proxy: http://no-such-proxy:3128
no_proxy: github.com,static.azul.com
steps:
- uses: actions/checkout@v2
- name: Clear tool cache
run: rm -rf $RUNNER_TOOL_CACHE/*
- name: Setup Java 13
id: setup-java
uses: ./
with:
java-version: 13.0.2
- name: Verify Java 13
run: __tests__/verify-java.sh 13.0.2 "${{ steps.setup-java.outputs.path }}" "${{ steps.setup-java.outputs.version }}"

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
.licenses/npm/@oozcitak/infra.dep.yml generated Normal file

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
.licenses/npm/@oozcitak/util.dep.yml generated Normal file

Binary file not shown.

BIN
.licenses/npm/@types/node.dep.yml generated Normal file

Binary file not shown.

BIN
.licenses/npm/argparse.dep.yml generated Normal file

Binary file not shown.

BIN
.licenses/npm/esprima.dep.yml generated Normal file

Binary file not shown.

BIN
.licenses/npm/js-yaml.dep.yml generated Normal file

Binary file not shown.

BIN
.licenses/npm/lru-cache.dep.yml generated Normal file

Binary file not shown.

BIN
.licenses/npm/semver-7.3.4.dep.yml generated Normal file

Binary file not shown.

BIN
.licenses/npm/sprintf-js.dep.yml generated Normal file

Binary file not shown.

Binary file not shown.

BIN
.licenses/npm/yallist.dep.yml generated Normal file

Binary file not shown.

@ -1,11 +1,11 @@
{
"printWidth": 80,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "none",
"bracketSpacing": false,
"bracketSpacing": true,
"arrowParens": "avoid",
"parser": "typescript"
}

288
README.md

@ -4,252 +4,114 @@
<a href="https://github.com/actions/setup-java"><img alt="GitHub Actions status" src="https://github.com/actions/setup-java/workflows/Main%20workflow/badge.svg"></a>
</p>
This action sets up a java environment for use in actions by:
This action provides the following functionality for GitHub Actions runners:
- Downloading and setting up a requested version of Java. See [Usage](#Usage) for a list of supported distributions
- Extracting and caching custom version of Java from a local file
- Configuring runner for publishing using Apache Maven
- Configuring runner for publishing using Gradle
- Configuring runner for using GPG private key
- Registering problem matchers for error output
- optionally downloading and caching a requested version of java by version and adding to PATH. Default downloads are populated from the [Zulu Community distribution of OpenJDK](http://static.azul.com/zulu/bin/)
- registering problem matchers for error output
## V2 vs V1
- V2 supports custom distributions and provides support for Zulu OpenJDK and Adopt OpenJDK out of the box. V1 supports only Zulu OpenJDK
- V2 requires you to specify distribution along with the version. V1 defaults to Zulu OpenJDK, only version input is required. Follow [the migration guide](docs/switching-to-v2.md) to switch from V1 to V2
# Usage
## Usage
Inputs `java-version` and `distribution` are mandatory. See [Supported distributions](../README.md#Supported-distributions) section for a list of available options.
See [action.yml](action.yml)
## Basic
### Basic
**Adopt OpenJDK**
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
- uses: actions/setup-java@v2-preview
with:
java-version: '9.0.4' # The JDK version to make available on the path.
java-package: jdk # (jre, jdk, or jdk+fx) - defaults to jdk
architecture: x64 # (x64 or x86) - defaults to x64
distribution: 'adopt' # See 'Supported distributions' for available options
java-version: '11'
- run: java -cp java HelloWorldApp
```
Examples of version specifications that the java-version parameter will accept:
- A major Java version
e.g. ```6, 7, 8, 9, 10, 11, 12, 13, ...```
- A semver Java version specification
e.g. ```8.0.232, 7.0.181, 11.0.4```
e.g. ```8.0.x, >11.0.3, >=13.0.1, <8.0.212```
- An early access (EA) Java version
e.g. ```14-ea, 15-ea```
e.g. ```14.0.0-ea, 15.0.0-ea```
e.g. ```14.0.0-ea.28, 15.0.0-ea.2``` (syntax for specifying an EA build number)
Note that, per semver rules, EA builds will be matched by explicit EA version specifications.
- 1.x syntax
e.g. ```1.8``` (same as ```8```)
e.g. ```1.8.0.212``` (same as ```8.0.212```)
## Local file
**Zulu OpenJDK**
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
- uses: actions/setup-java@v2-preview
with:
java-version: '4.0.0'
architecture: x64
jdkFile: <path to jdkFile> # Optional - jdkFile to install java from. Useful for versions not found on Zulu Community CDN
distribution: 'zulu' # See 'Supported distributions' for available options
java-version: '11'
- run: java -cp java HelloWorldApp
```
## Matrix Testing
#### Supported version syntax
The `java-version` input supports an exact version or a version range using [SemVer](https://semver.org/) notation:
- major versions: `8`, `11`, `15`
- more specific versions: `11.0`, `11.0.4`, `8.0.232`, `8.0.282+8`
- early access (EA) versions: `15-ea`, `15.0.0-ea`, `15.0.0-ea.2`, `15.0.0+2-ea`
#### Supported distributions
Currently, the following distributions are supported:
| Keyword | Distribution | Official site | License |
|-|-|-|-|
| `zulu` | Zulu OpenJDK | [Link](https://www.azul.com/downloads/zulu-community/?package=jdk) | [Link](https://www.azul.com/products/zulu-and-zulu-enterprise/zulu-terms-of-use/) |
| `adopt` | Adopt OpenJDK | [Link](https://adoptopenjdk.net/) | [Link](https://adoptopenjdk.net/about.html)
**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.
### Check latest
In the basic examples above, the `check-latest` flag defaults to `false`. When set to `false`, the action tries to first resolve a version of Java from the local tool cache on the runner. If unable to find a specific version in the cache, the action will download a version of Java. Use the default or set `check-latest` to `false` if you prefer a faster more consistent setup experience that prioritizes trying to use the cached versions at the expense of newer versions sometimes being available for download.
If `check-latest` is set to `true`, the action first checks if the cached version is the latest one. If the locally cached version is not the most up-to-date, the latest version of Java will be downloaded. Set `check-latest` to `true` if you want the most up-to-date version of Java to always be used. Setting `check-latest` to `true` has performance implications as downloading versions of Java is slower than using cached versions.
For Java distributions that are not cached on Hosted images, `check-latest` always behaves as `true` and downloads Java on-flight. Check out [Hosted Tool Cache](docs/advanced-usage.md#Hosted-Tool-Cache) for more details about pre-cached Java versions.
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v2-preview
with:
distribution: 'adopt'
java-version: '11'
check-latest: true
- run: java -cp java HelloWorldApp
```
### Testing against different Java versions
```yaml
jobs:
build:
runs-on: ubuntu-16.04
runs-on: ubuntu-20.04
strategy:
matrix:
# test against latest update of each major Java version, as well as specific updates of LTS versions:
java: [ 1.6, 6.0.83, 7, 7.0.181, 8, 8.0.192, 9.0.x, 10, 11.0.x, 11.0.3, 12, 13 ]
name: Java ${{ matrix.java }} sample
java: [ '8', '11', '13', '15' ]
name: Java ${{ matrix.Java }} sample
steps:
- uses: actions/checkout@v2
- name: Setup java
uses: actions/setup-java@v1
uses: actions/setup-java@v2-preview
with:
distribution: '<distribution>'
java-version: ${{ matrix.java }}
- run: java -cp java HelloWorldApp
```
## Publishing using Apache Maven
### Advanced
- [Selecting a Java distribution](docs/advanced-usage.md#Selecting-a-Java-distribution)
- [Adopt](docs/advanced-usage.md#Adopt)
- [Zulu](docs/advanced-usage.md#Zulu)
- [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)
- [Testing against different Java distributions](docs/advanced-usage.md#Testing-against-different-Java-distributions)
- [Testing against different platforms](docs/advanced-usage.md#Testing-against-different-platforms)
- [Publishing using Apache Maven](docs/advanced-usage.md#Publishing-using-Apache-Maven)
- [Publishing using Gradle](docs/advanced-usage.md#Publishing-using-Gradle)
- [Hosted Tool Cache](docs/advanced-usage.md#Hosted-Tool-Cache)
### Extra setup for pom.xml:
The Maven GPG Plugin configuration in the pom.xml file should contain the following structure to avoid possible issues like `Inappropriate ioctl for device` or `gpg: signing failed: No such file or directory`:
```xml
<configuration>
<!-- Prevent gpg from using pinentry programs -->
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
```
GPG 2.1 requires `--pinentry-mode` to be set to `loopback` in order to pick up the `gpg.passphrase` value defined in Maven `settings.xml`.
### Yaml example:
```yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Publish to GitHub Packages Apache Maven
run: mvn deploy
env:
GITHUB_TOKEN: ${{ github.token }} # GITHUB_TOKEN is the default env for the password
- name: Set up Apache Maven Central
uses: actions/setup-java@v1
with: # running setup-java again overwrites the settings.xml
java-version: 1.8
server-id: maven # Value of the distributionManagement/repository/id field of the pom.xml
server-username: MAVEN_USERNAME # env variable for username in deploy
server-password: MAVEN_CENTRAL_TOKEN # env variable for token in deploy
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import
gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase
- name: Publish to Apache Maven Central
run: mvn deploy
env:
MAVEN_USERNAME: maven_username123
MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
```
The two `settings.xml` files created from the above example look like the following.
`settings.xml` file created for the first deploy to GitHub Packages
```xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>github</id>
<username>${env.GITHUB_ACTOR}</username>
<password>${env.GITHUB_TOKEN}</password>
</server>
<server>
<id>gpg.passphrase</id>
<passphrase>${env.GPG_PASSPHRASE}</passphrase>
</server>
</servers>
</settings>
```
`settings.xml` file created for the second deploy to Apache Maven Central
```xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>maven</id>
<username>${env.MAVEN_USERNAME}</username>
<password>${env.MAVEN_CENTRAL_TOKEN}</password>
</server>
<server>
<id>gpg.passphrase</id>
<passphrase>${env.MAVEN_GPG_PASSPHRASE}</passphrase>
</server>
</servers>
</settings>
```
***NOTE: The `settings.xml` file is created in the Actions $HOME/.m2 directory. If you have an existing `settings.xml` file at that location, it will be overwritten. See below for using the `settings-path` to change your `settings.xml` file location.***
### GPG
If `gpg-private-key` input is provided, the private key will be written to a file in the runner's temp directory, the private key file will be imported into the GPG keychain, and then the file will be promptly removed before proceeding with the rest of the setup process. A cleanup step will remove the imported private key from the GPG keychain after the job completes regardless of the job status. This ensures that the private key is no longer accessible on self-hosted runners and cannot "leak" between jobs (hosted runners are always clean instances).
**GPG key should be exported by: `gpg --armor --export-secret-keys YOUR_ID`**
See the help docs on [Publishing a Package](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-apache-maven-for-use-with-github-packages#publishing-a-package) for more information on the `pom.xml` file.
## Publishing using Gradle
```yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
- name: Build with Gradle
run: gradle build
- name: Publish to GitHub Packages
run: gradle publish
env:
USERNAME: ${{ github.actor }}
PASSWORD: ${{ secrets.GITHUB_TOKEN }}
```
***NOTE: The `USERNAME` and `PASSWORD` need to correspond to the credentials environment variables used in the publishing section of your `build.gradle`.***
See the help docs on [Publishing a Package with Gradle](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-gradle-for-use-with-github-packages#example-using-gradle-groovy-for-a-single-package-in-a-repository) for more information on the `build.gradle` configuration file.
## Apache Maven with a settings path
When using an Actions self-hosted runner with multiple shared runners the default `$HOME` directory can be shared by a number runners at the same time which could overwrite existing settings file. Setting the `settings-path` variable allows you to choose a unique location for your settings file.
```yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8 for Shared Runner
uses: actions/setup-java@v1
with:
java-version: 1.8
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
settings-path: ${{ github.workspace }} # location for the settings.xml file
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Publish to GitHub Packages Apache Maven
run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml
env:
GITHUB_TOKEN: ${{ github.token }}
```
# License
## License
The scripts and documentation in this project are released under the [MIT License](LICENSE)
# Contributions
## Contributions
Contributions are welcome! See [Contributor's Guide](docs/contributors.md)

@ -1,14 +1,7 @@
import io = require('@actions/io');
import fs = require('fs');
import os = require('os');
import path = require('path');
// make the os.homedir() call be local to the tests
jest.doMock('os', () => {
return {
homedir: jest.fn(() => __dirname)
};
});
import os from 'os';
import * as auth from '../src/auth';
@ -16,8 +9,12 @@ const m2Dir = path.join(__dirname, auth.M2_DIR);
const settingsFile = path.join(m2Dir, auth.SETTINGS_FILE);
describe('auth tests', () => {
let spyOSHomedir: jest.SpyInstance;
beforeEach(async () => {
await io.rmRF(m2Dir);
spyOSHomedir = jest.spyOn(os, 'homedir');
spyOSHomedir.mockReturnValue(__dirname);
}, 300000);
afterAll(async () => {
@ -26,6 +23,9 @@ describe('auth tests', () => {
} catch {
console.log('Failed to remove test directories');
}
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
}, 100000);
it('creates settings.xml in alternate locations', async () => {
@ -35,10 +35,9 @@ describe('auth tests', () => {
const altHome = path.join(__dirname, 'runner', 'settings');
const altSettingsFile = path.join(altHome, auth.SETTINGS_FILE);
process.env[`INPUT_SETTINGS-PATH`] = altHome;
await io.rmRF(altHome); // ensure it doesn't already exist
await auth.configAuthentication(id, username, password);
await auth.createAuthenticationSettings(id, username, password, altHome, true);
expect(fs.existsSync(m2Dir)).toBe(false);
expect(fs.existsSync(settingsFile)).toBe(false);
@ -49,7 +48,6 @@ describe('auth tests', () => {
auth.generate(id, username, password)
);
delete process.env[`INPUT_SETTINGS-PATH`];
await io.rmRF(altHome);
}, 100000);
@ -58,13 +56,11 @@ describe('auth tests', () => {
const username = 'UNAME';
const password = 'TOKEN';
await auth.configAuthentication(id, username, password);
await auth.createAuthenticationSettings(id, username, password, m2Dir, true);
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
auth.generate(id, username, password)
);
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(auth.generate(id, username, password));
}, 100000);
it('creates settings.xml with additional configuration', async () => {
@ -73,7 +69,7 @@ describe('auth tests', () => {
const password = 'TOKEN';
const gpgPassphrase = 'GPG';
await auth.configAuthentication(id, username, password, gpgPassphrase);
await auth.createAuthenticationSettings(id, username, password, m2Dir, true, gpgPassphrase);
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
@ -92,13 +88,28 @@ describe('auth tests', () => {
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
await auth.configAuthentication(id, username, password);
await auth.createAuthenticationSettings(id, username, password, m2Dir, true);
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
auth.generate(id, username, password)
);
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(auth.generate(id, username, password));
}, 100000);
it('does not overwrite existing settings.xml files', async () => {
const id = 'packages';
const username = 'USERNAME';
const password = 'PASSWORD';
fs.mkdirSync(m2Dir, { recursive: true });
fs.writeFileSync(settingsFile, 'FAKE FILE');
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
await auth.createAuthenticationSettings(id, username, password, m2Dir, false);
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual('FAKE FILE');
}, 100000);
it('generates valid settings.xml with minimal configuration', () => {
@ -143,8 +154,6 @@ describe('auth tests', () => {
</servers>
</settings>`;
expect(auth.generate(id, username, password, gpgPassphrase)).toEqual(
expectedSettings
);
expect(auth.generate(id, username, password, gpgPassphrase)).toEqual(expectedSettings);
});
});

909
__tests__/data/adopt.json Normal file

@ -0,0 +1,909 @@
[
{
"binaries": [
{
"architecture": "x64",
"download_count": 74181,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "09b7e6ab5d5eb4b73813f4caa793a0b616d33794a17988fa6a6b7c972e8f3dd3",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk-14.0.2%2B12/OpenJDK14U-jdk_x64_mac_hotspot_14.0.2_12.tar.gz.sha256.txt",
"download_count": 23872,
"link": "https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk-14.0.2%2B12/OpenJDK14U-jdk_x64_mac_hotspot_14.0.2_12.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk-14.0.2%2B12/OpenJDK14U-jdk_x64_mac_hotspot_14.0.2_12.tar.gz.json",
"name": "OpenJDK14U-jdk_x64_mac_hotspot_14.0.2_12.tar.gz",
"size": 195705010
},
"project": "jdk",
"scm_ref": "jdk-14.0.2+12_adopt",
"updated_at": "2020-07-16T08:55:45Z"
}
],
"download_count": 477080,
"id": "MDc6UmVsZWFzZTI4NjIyMDc4.+ve8KojpqJUpsA==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/tag/jdk-14.0.2%2B12",
"release_name": "jdk-14.0.2+12",
"release_type": "ga",
"timestamp": "2020-07-16T08:54:16Z",
"updated_at": "2020-07-16T08:54:16Z",
"vendor": "adoptopenjdk",
"version_data": {
"build": 12,
"major": 14,
"minor": 0,
"openjdk_version": "14.0.2+12",
"security": 2,
"semver": "14.0.2+12"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 58023,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "b11cb192312530bcd84607631203d0c1727e672af12813078e6b525e3cce862d",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk-14.0.1%2B7/OpenJDK14U-jdk_x64_mac_hotspot_14.0.1_7.tar.gz.sha256.txt",
"download_count": 25276,
"link": "https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk-14.0.1%2B7/OpenJDK14U-jdk_x64_mac_hotspot_14.0.1_7.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk-14.0.1%2B7/OpenJDK14U-jdk_x64_mac_hotspot_14.0.1_7.tar.gz.json",
"name": "OpenJDK14U-jdk_x64_mac_hotspot_14.0.1_7.tar.gz",
"size": 195769653
},
"project": "jdk",
"scm_ref": "jdk-14.0.1+7_adopt",
"updated_at": "2020-04-20T12:54:23Z"
}
],
"download_count": 198607,
"id": "MDc6UmVsZWFzZTI1Njc4MzEw.z3NqYG25PFlG+Q==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/tag/jdk-14.0.1%2B7",
"release_name": "jdk-14.0.1+7",
"release_type": "ga",
"timestamp": "2020-04-20T12:52:51Z",
"updated_at": "2020-04-20T12:52:51Z",
"vendor": "adoptopenjdk",
"version_data": {
"adopt_build_number": 1,
"build": 7,
"major": 14,
"minor": 0,
"openjdk_version": "14.0.1+7",
"security": 1,
"semver": "14.0.1+7.1"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 30069,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "d358a7ff03905282348c6c80562a4da2e04eb377b60ad2152be4c90f8d580b7f",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15.0.2%2B7/OpenJDK15U-jdk_x64_mac_hotspot_15.0.2_7.tar.gz.sha256.txt",
"download_count": 3718,
"link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15.0.2%2B7/OpenJDK15U-jdk_x64_mac_hotspot_15.0.2_7.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15.0.2%2B7/OpenJDK15U-jdk_x64_mac_hotspot_15.0.2_7.tar.gz.json",
"name": "OpenJDK15U-jdk_x64_mac_hotspot_15.0.2_7.tar.gz",
"size": 195232978
},
"project": "jdk",
"scm_ref": "jdk-15.0.2+7_adopt",
"updated_at": "2021-01-22T17:33:20Z"
}
],
"download_count": 124226,
"id": "MDc6UmVsZWFzZTM2NzgwOTAw.X2+6VqPND3E8CA==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/tag/jdk-15.0.2%2B7",
"release_name": "jdk-15.0.2+7",
"release_type": "ga",
"timestamp": "2021-01-22T17:31:37Z",
"updated_at": "2021-01-22T17:31:37Z",
"vendor": "adoptopenjdk",
"version_data": {
"build": 7,
"major": 15,
"minor": 0,
"openjdk_version": "15.0.2+7",
"security": 2,
"semver": "15.0.2+7"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 24542,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "b8c2e2ad31f3d6676ea665d9505b06df15e23741847556612b40e3ee329fc046",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15.0.1%2B9.1/OpenJDK15U-jdk_x64_mac_hotspot_15.0.1_9.tar.gz.sha256.txt",
"download_count": 3274,
"link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15.0.1%2B9.1/OpenJDK15U-jdk_x64_mac_hotspot_15.0.1_9.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15.0.1%2B9.1/OpenJDK15U-jdk_x64_mac_hotspot_15.0.1_9.tar.gz.json",
"name": "OpenJDK15U-jdk_x64_mac_hotspot_15.0.1_9.tar.gz",
"size": 195872839
},
"project": "jdk",
"scm_ref": "jdk-15.0.1+9_adopt",
"updated_at": "2020-12-01T16:57:47Z"
}
],
"download_count": 25378,
"id": "MDc6UmVsZWFzZTM0NjQ2MDU4.Yj2XZf+VBGAPtw==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/tag/jdk-15.0.1%2B9.1",
"release_name": "jdk-15.0.1+9.1",
"release_type": "ga",
"timestamp": "2020-12-01T16:57:26Z",
"updated_at": "2020-12-01T16:57:26Z",
"vendor": "adoptopenjdk",
"version_data": {
"adopt_build_number": 1,
"build": 9,
"major": 15,
"minor": 0,
"openjdk_version": "15.0.1+9",
"security": 1,
"semver": "15.0.1+9.1"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 21675,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "d32f9429c4992cef7be559a15c542011503d6bc38c89379800cd209a9d7ec539",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15.0.1%2B9/OpenJDK15U-jdk_x64_mac_hotspot_15.0.1_9.tar.gz.sha256.txt",
"download_count": 11935,
"link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15.0.1%2B9/OpenJDK15U-jdk_x64_mac_hotspot_15.0.1_9.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15.0.1%2B9/OpenJDK15U-jdk_x64_mac_hotspot_15.0.1_9.tar.gz.json",
"name": "OpenJDK15U-jdk_x64_mac_hotspot_15.0.1_9.tar.gz",
"size": 195773522
},
"project": "jdk",
"scm_ref": "jdk-15.0.1+9_adopt",
"updated_at": "2020-10-23T20:48:09Z"
}
],
"download_count": 308690,
"id": "MDc6UmVsZWFzZTMyOTk4MTUx.3oazo3YGfHhF3w==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/tag/jdk-15.0.1%2B9",
"release_name": "jdk-15.0.1+9",
"release_type": "ga",
"timestamp": "2020-10-23T20:46:22Z",
"updated_at": "2020-10-23T20:46:22Z",
"vendor": "adoptopenjdk",
"version_data": {
"build": 9,
"major": 15,
"minor": 0,
"openjdk_version": "15.0.1+9",
"security": 1,
"semver": "15.0.1+9"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 51254,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "bd1fc774232e2dfee93056a01f5765bd92ffb19d68dd548c233a82bb5c162be4",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15%2B36/OpenJDK15U-jdk_x64_mac_hotspot_15_36.tar.gz.sha256.txt",
"download_count": 5325,
"link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15%2B36/OpenJDK15U-jdk_x64_mac_hotspot_15_36.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15%2B36/OpenJDK15U-jdk_x64_mac_hotspot_15_36.tar.gz.json",
"name": "OpenJDK15U-jdk_x64_mac_hotspot_15_36.tar.gz",
"size": 195853361
},
"project": "jdk",
"scm_ref": "jdk-15+36_adopt",
"updated_at": "2020-09-17T07:43:54Z"
}
],
"download_count": 157313,
"id": "MDc6UmVsZWFzZTMxNDUwMjA0.eYpt0EBEjldfEQ==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/tag/jdk-15%2B36",
"release_name": "jdk-15+36",
"release_type": "ga",
"timestamp": "2020-09-17T07:42:21Z",
"updated_at": "2020-09-17T07:42:21Z",
"vendor": "adoptopenjdk",
"version_data": {
"build": 36,
"major": 15,
"minor": 0,
"openjdk_version": "15+36",
"security": 0,
"semver": "15.0.0+36"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 27428,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "aabc3aebb0abf1ba64d9bd5796d0c7eb7239983f6e4c0f015b5b88be5616e4bd",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk-14%2B36/OpenJDK14U-jdk_x64_mac_hotspot_14_36.tar.gz.sha256.txt",
"download_count": 19544,
"link": "https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk-14%2B36/OpenJDK14U-jdk_x64_mac_hotspot_14_36.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk-14%2B36/OpenJDK14U-jdk_x64_mac_hotspot_14_36.tar.gz.json",
"name": "OpenJDK14U-jdk_x64_mac_hotspot_14_36.tar.gz",
"size": 201087797
},
"project": "jdk",
"scm_ref": "jdk-14+36_adopt",
"updated_at": "2020-03-18T12:13:05Z"
}
],
"download_count": 364816,
"id": "MDc6UmVsZWFzZTI0NjMxMDAy.AY7rtvmrnWWlIg==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/tag/jdk-14%2B36",
"release_name": "jdk-14+36",
"release_type": "ga",
"timestamp": "2020-03-18T12:11:08Z",
"updated_at": "2020-03-18T12:11:08Z",
"vendor": "adoptopenjdk",
"version_data": {
"adopt_build_number": 1,
"build": 36,
"major": 14,
"minor": 0,
"openjdk_version": "14+36",
"security": 0,
"semver": "14.0.0+36.1"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 63201,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "0ddb24efdf5aab541898d19b7667b149a1a64a8bd039b708fc58ee0284fa7e07",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk13-binaries/releases/download/jdk-13.0.2%2B8/OpenJDK13U-jdk_x64_mac_hotspot_13.0.2_8.tar.gz.sha256.txt",
"download_count": 32531,
"link": "https://github.com/AdoptOpenJDK/openjdk13-binaries/releases/download/jdk-13.0.2%2B8/OpenJDK13U-jdk_x64_mac_hotspot_13.0.2_8.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk13-binaries/releases/download/jdk-13.0.2%2B8/OpenJDK13U-jdk_x64_mac_hotspot_13.0.2_8.tar.gz.json",
"name": "OpenJDK13U-jdk_x64_mac_hotspot_13.0.2_8.tar.gz",
"size": 198206427
},
"project": "jdk",
"scm_ref": "jdk-13.0.2+8_adopt",
"updated_at": "2020-01-20T16:46:24Z"
}
],
"download_count": 349677,
"id": "MDc6UmVsZWFzZTIyOTgxNTM1.gtZYwGfBgkb3Gg==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk13-binaries/releases/tag/jdk-13.0.2%2B8",
"release_name": "jdk-13.0.2+8",
"release_type": "ga",
"timestamp": "2020-01-20T16:42:35Z",
"updated_at": "2020-01-20T16:42:35Z",
"vendor": "adoptopenjdk",
"version_data": {
"adopt_build_number": 1,
"build": 8,
"major": 13,
"minor": 0,
"openjdk_version": "13.0.2+8",
"security": 2,
"semver": "13.0.2+8.1"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 41508,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "9c82de98ce9bc2353bcf314d85366c9a2c572db034e10a71aa47e804e13748c1",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk13-binaries/releases/download/jdk-13.0.1%2B9/OpenJDK13U-jdk_x64_mac_hotspot_13.0.1_9.tar.gz.sha256.txt",
"download_count": 32262,
"link": "https://github.com/AdoptOpenJDK/openjdk13-binaries/releases/download/jdk-13.0.1%2B9/OpenJDK13U-jdk_x64_mac_hotspot_13.0.1_9.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk13-binaries/releases/download/jdk-13.0.1%2B9/OpenJDK13U-jdk_x64_mac_hotspot_13.0.1_9.tar.gz.json",
"name": "OpenJDK13U-jdk_x64_mac_hotspot_13.0.1_9.tar.gz",
"size": 198205689
},
"project": "jdk",
"scm_ref": "jdk-13.0.1+9_adopt",
"updated_at": "2019-10-26T14:44:27Z"
}
],
"download_count": 680021,
"id": "MDc6UmVsZWFzZTIwOTk4NDA0.srlG2TmLho/j0w==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk13-binaries/releases/tag/jdk-13.0.1%2B9",
"release_name": "jdk-13.0.1+9",
"release_type": "ga",
"timestamp": "2019-10-26T14:43:52Z",
"updated_at": "2019-10-26T14:43:52Z",
"vendor": "adoptopenjdk",
"version_data": {
"adopt_build_number": 1,
"build": 9,
"major": 13,
"minor": 0,
"openjdk_version": "13.0.1+9",
"security": 1,
"semver": "13.0.1+9.1"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 37738,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "f948be96daba250b6695e22cb51372d2ba3060e4d778dd09c89548889783099f",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk13-binaries/releases/download/jdk-13%2B33/OpenJDK13U-jdk_x64_mac_hotspot_13_33.tar.gz.sha256.txt",
"download_count": 37738,
"link": "https://github.com/AdoptOpenJDK/openjdk13-binaries/releases/download/jdk-13%2B33/OpenJDK13U-jdk_x64_mac_hotspot_13_33.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk13-binaries/releases/download/jdk-13%2B33/OpenJDK13U-jdk_x64_mac_hotspot_13_33.tar.gz.json",
"name": "OpenJDK13U-jdk_x64_mac_hotspot_13_33.tar.gz",
"size": 198189530
},
"project": "jdk",
"scm_ref": "jdk-13+33_adopt",
"updated_at": "2019-09-19T10:20:21Z"
}
],
"download_count": 226200,
"id": "MDc6UmVsZWFzZTIwMTA0MTUy.trK7qCbNtlMWFw==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk13-binaries/releases/tag/jdk-13%2B33",
"release_name": "jdk-13+33",
"release_type": "ga",
"timestamp": "2019-09-19T10:19:58Z",
"updated_at": "2019-09-19T10:19:58Z",
"vendor": "adoptopenjdk",
"version_data": {
"adopt_build_number": 1,
"build": 33,
"major": 13,
"minor": 0,
"openjdk_version": "13+33",
"security": 0,
"semver": "13.0.0+33.1"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 24493,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "9919eee037554d40c7d2f219bbd654f2bf119e16a2f4d284d8dedaf525ee59e6",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.2%2B10/OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz.sha256.txt",
"download_count": 22907,
"link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.2%2B10/OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.2%2B10/OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz.json",
"name": "OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz",
"size": 198392994
},
"project": "jdk",
"scm_ref": "jdk-12.0.2+10_adopt",
"updated_at": "2019-07-18T20:27:24Z"
}
],
"download_count": 396318,
"id": "MDc6UmVsZWFzZTE4NzE2Mzk5.S/VUFSgnrVIv8A==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/tag/jdk-12.0.2%2B10",
"release_name": "jdk-12.0.2+10",
"release_type": "ga",
"timestamp": "2019-07-18T20:26:29Z",
"updated_at": "2019-07-18T20:26:29Z",
"vendor": "adoptopenjdk",
"version_data": {
"adopt_build_number": 1,
"build": 10,
"major": 12,
"minor": 0,
"openjdk_version": "12.0.2+10",
"security": 2,
"semver": "12.0.2+10.1"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 5539,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "7acd697e816491d31b24d0ae1867fd63060aa738cfa388757946ae312a60b4f2",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.2%2B10.3/OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz.sha256.txt",
"download_count": 5539,
"link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.2%2B10.3/OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.2%2B10.3/OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz.json",
"name": "OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz",
"size": 198429049
},
"project": "jdk",
"scm_ref": "jdk-12.0.2+10_adopt",
"updated_at": "2019-09-19T17:17:37Z"
}
],
"download_count": 5879,
"id": "MDc6UmVsZWFzZTIwMTE2ODQ3.QGQl8Nj1qkma4Q==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/tag/jdk-12.0.2%2B10.3",
"release_name": "jdk-12.0.2+10.3",
"release_type": "ga",
"timestamp": "2019-09-19T17:17:26Z",
"updated_at": "2019-12-06T15:10:37Z",
"vendor": "adoptopenjdk",
"version_data": {
"adopt_build_number": 3,
"build": 10,
"major": 12,
"minor": 0,
"openjdk_version": "12.0.2+10",
"security": 2,
"semver": "12.0.2+10.3"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 22794,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "2c1a46c0fab6d4bdbc443f23c3f6a313c2de47fbbd9c16b5c1133a88f6c1ab8f",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.2%2B10.2/OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz.sha256.txt",
"download_count": 637,
"link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.2%2B10.2/OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.2%2B10.2/OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz.json",
"name": "OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz",
"size": 198862174
},
"project": "jdk",
"scm_ref": "jdk-12.0.2+10_adopt",
"updated_at": "2019-08-06T10:41:10Z"
}
],
"download_count": 23563,
"id": "MDc6UmVsZWFzZTE5MTAzMTI3.in65dKG+veAxOg==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/tag/jdk-12.0.2%2B10.2",
"release_name": "jdk-12.0.2+10.2",
"release_type": "ga",
"timestamp": "2019-08-06T10:40:44Z",
"updated_at": "2019-08-06T10:40:44Z",
"vendor": "adoptopenjdk",
"version_data": {
"adopt_build_number": 2,
"build": 10,
"major": 12,
"minor": 0,
"openjdk_version": "12.0.2+10",
"security": 2,
"semver": "12.0.2+10.2"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 24493,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "9919eee037554d40c7d2f219bbd654f2bf119e16a2f4d284d8dedaf525ee59e6",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.2%2B10/OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz.sha256.txt",
"download_count": 22907,
"link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.2%2B10/OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.2%2B10/OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz.json",
"name": "OpenJDK12U-jdk_x64_mac_hotspot_12.0.2_10.tar.gz",
"size": 198392994
},
"project": "jdk",
"scm_ref": "jdk-12.0.2+9_adopt",
"updated_at": "2019-07-18T20:27:24Z"
}
],
"download_count": 396318,
"id": "MDc6UmVsZWFzZTE4NzE2Mzk5.S/VUFSgnrVIv8A==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/tag/jdk-12.0.2%2B10",
"release_name": "jdk-12.0.2+9",
"release_type": "ga",
"timestamp": "2019-07-18T20:26:29Z",
"updated_at": "2019-07-18T20:26:29Z",
"vendor": "adoptopenjdk",
"version_data": {
"adopt_build_number": 1,
"build": 10,
"major": 12,
"minor": 0,
"openjdk_version": "12.0.2+9",
"security": 2,
"semver": "12.0.2+9.1"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 39519,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "dcb2ab681247298eda018df24166ba01674127083fb02892acf087e6181d8c56",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.1%2B12/OpenJDK12U-jdk_x64_mac_hotspot_12.0.1_12.tar.gz.sha256.txt",
"download_count": 33306,
"link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.1%2B12/OpenJDK12U-jdk_x64_mac_hotspot_12.0.1_12.tar.gz",
"name": "OpenJDK12U-jdk_x64_mac_hotspot_12.0.1_12.tar.gz",
"size": 198112975
},
"project": "jdk",
"updated_at": "2019-04-21T15:12:34Z"
}
],
"download_count": 1038669,
"id": "MDc6UmVsZWFzZTE2ODg3NDU3",
"release_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/tag/jdk-12.0.1%2B12",
"release_name": "jdk-12.0.1+12",
"release_type": "ga",
"timestamp": "2019-04-21T15:11:56Z",
"updated_at": "2019-04-21T15:11:56Z",
"vendor": "adoptopenjdk",
"version_data": {
"build": 12,
"major": 12,
"minor": 0,
"openjdk_version": "12.0.1+12",
"security": 1,
"semver": "12.0.1+12"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 3136,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "985036459d4ef0867a3fe83b0bf87877d8e66a121c7b9c145bb97bd921aaf3f1",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12%2B33/OpenJDK12U-jdk_x64_mac_hotspot_12_33.tar.gz.sha256.txt",
"download_count": 1905,
"link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12%2B33/OpenJDK12U-jdk_x64_mac_hotspot_12_33.tar.gz",
"name": "OpenJDK12U-jdk_x64_mac_hotspot_12_33.tar.gz",
"size": 198099074
},
"project": "jdk",
"updated_at": "2019-03-22T12:09:13Z"
}
],
"download_count": 757289,
"id": "MDc6UmVsZWFzZTE2MjgyMjM2",
"release_link": "https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/tag/jdk-12%2B33",
"release_name": "jdk-12+33",
"release_type": "ga",
"timestamp": "2019-03-22T12:08:43Z",
"updated_at": "2019-03-22T12:08:43Z",
"vendor": "adoptopenjdk",
"version_data": {
"build": 33,
"major": 12,
"minor": 0,
"openjdk_version": "12+33",
"security": 0,
"semver": "12.0.0+33"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 75576,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "ee7c98c9d79689aca6e717965747b8bf4eec5413e89d5444cc2bd6dbd59e3811",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_mac_hotspot_11.0.10_9.tar.gz.sha256.txt",
"download_count": 17426,
"link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_mac_hotspot_11.0.10_9.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_mac_hotspot_11.0.10_9.tar.gz.json",
"name": "OpenJDK11U-jdk_x64_mac_hotspot_11.0.10_9.tar.gz",
"size": 186160219
},
"project": "jdk",
"scm_ref": "jdk-11.0.10+9_adopt",
"updated_at": "2021-01-22T14:16:47Z"
}
],
"download_count": 636180,
"id": "MDc6UmVsZWFzZTM2NzcwNDUy.hAVJRiZZTufG+w==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/tag/jdk-11.0.10%2B9",
"release_name": "jdk-11.0.10+9",
"release_type": "ga",
"timestamp": "2021-01-22T14:15:12Z",
"updated_at": "2021-01-22T14:15:12Z",
"vendor": "adoptopenjdk",
"version_data": {
"build": 9,
"major": 11,
"minor": 0,
"openjdk_version": "11.0.10+9",
"security": 10,
"semver": "11.0.10+9"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 108441,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "96bc469f9b02a3b84382a0685b0bd7935e1ad1bd82a0aab9befb5b42a17cbd77",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.9.1%2B1/OpenJDK11U-jdk_x64_mac_hotspot_11.0.9.1_1.tar.gz.sha256.txt",
"download_count": 22211,
"link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.9.1%2B1/OpenJDK11U-jdk_x64_mac_hotspot_11.0.9.1_1.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.9.1%2B1/OpenJDK11U-jdk_x64_mac_hotspot_11.0.9.1_1.tar.gz.json",
"name": "OpenJDK11U-jdk_x64_mac_hotspot_11.0.9.1_1.tar.gz",
"size": 185368626
},
"project": "jdk",
"scm_ref": "jdk-11.0.9.1+1_adopt",
"updated_at": "2020-11-12T14:10:45Z"
}
],
"download_count": 815676,
"id": "MDc6UmVsZWFzZTMzODU4MDE1.94IbKUd3vvhzsA==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/tag/jdk-11.0.9.1%2B1",
"release_name": "jdk-11.0.9.1+1",
"release_type": "ga",
"timestamp": "2020-11-12T14:08:55Z",
"updated_at": "2020-11-12T14:08:55Z",
"vendor": "adoptopenjdk",
"version_data": {
"build": 1,
"major": 11,
"minor": 0,
"openjdk_version": "11.0.9.1+1",
"patch": 1,
"security": 9,
"semver": "11.0.9+101"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 45450,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "7b21961ffb2649e572721a0dfad64169b490e987937b661cb4e13a594c21e764",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.9%2B11.1/OpenJDK11U-jdk_x64_mac_hotspot_11.0.9_11.tar.gz.sha256.txt",
"download_count": 11117,
"link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.9%2B11.1/OpenJDK11U-jdk_x64_mac_hotspot_11.0.9_11.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.9%2B11.1/OpenJDK11U-jdk_x64_mac_hotspot_11.0.9_11.tar.gz.json",
"name": "OpenJDK11U-jdk_x64_mac_hotspot_11.0.9_11.tar.gz",
"size": 186006796
},
"project": "jdk",
"scm_ref": "jdk-11.0.9+11_adopt",
"updated_at": "2020-10-25T14:43:54Z"
}
],
"download_count": 423635,
"id": "MDc6UmVsZWFzZTMzMDI4MDcz.dRvNNRwJCgY3Xw==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/tag/jdk-11.0.9%2B11.1",
"release_name": "jdk-11.0.9+11.1",
"release_type": "ga",
"timestamp": "2020-10-25T13:31:15Z",
"updated_at": "2020-10-25T13:31:15Z",
"vendor": "adoptopenjdk",
"version_data": {
"adopt_build_number": 1,
"build": 11,
"major": 11,
"minor": 0,
"openjdk_version": "11.0.9+11",
"security": 9,
"semver": "11.0.9+11.1"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 2456,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "e84b00d74f08f059829bbf121c8423dc37ff65135968c1fcda5839600be4f542",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.9%2B11/OpenJDK11U-jdk_x64_mac_hotspot_11.0.9_11.tar.gz.sha256.txt",
"download_count": 1046,
"link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.9%2B11/OpenJDK11U-jdk_x64_mac_hotspot_11.0.9_11.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.9%2B11/OpenJDK11U-jdk_x64_mac_hotspot_11.0.9_11.tar.gz.json",
"name": "OpenJDK11U-jdk_x64_mac_hotspot_11.0.9_11.tar.gz",
"size": 185532704
},
"project": "jdk",
"scm_ref": "jdk-11.0.9+11_adopt",
"updated_at": "2020-10-25T13:28:33Z"
}
],
"download_count": 359580,
"id": "MDc6UmVsZWFzZTMyOTk4MzM5.6h9TT9pzYTK2Kg==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/tag/jdk-11.0.9%2B11",
"release_name": "jdk-11.0.9+11",
"release_type": "ga",
"timestamp": "2020-10-23T20:52:14Z",
"updated_at": "2020-10-23T20:52:14Z",
"vendor": "adoptopenjdk",
"version_data": {
"build": 11,
"major": 11,
"minor": 0,
"openjdk_version": "11.0.9+11",
"security": 9,
"semver": "11.0.9+11"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 149393,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "4a8dadd58cdc32c7e59978971d56aec610be7ee0ddf0dc1d137bb8b78456499f",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.8%2B10/OpenJDK11U-jdk_x64_mac_hotspot_11.0.8_10.tar.gz.sha256.txt",
"download_count": 40158,
"link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.8%2B10/OpenJDK11U-jdk_x64_mac_hotspot_11.0.8_10.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.8%2B10/OpenJDK11U-jdk_x64_mac_hotspot_11.0.8_10.tar.gz.json",
"name": "OpenJDK11U-jdk_x64_mac_hotspot_11.0.8_10.tar.gz",
"size": 185054456
},
"project": "jdk",
"scm_ref": "jdk-11.0.8+10_adopt",
"updated_at": "2020-07-15T14:30:51Z"
}
],
"download_count": 1968658,
"id": "MDc6UmVsZWFzZTI4NTg5Nzcz.pCNBA7G9E1o7pw==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/tag/jdk-11.0.8%2B10",
"release_name": "jdk-11.0.8+10",
"release_type": "ga",
"timestamp": "2020-07-15T14:29:27Z",
"updated_at": "2020-07-15T14:29:27Z",
"vendor": "adoptopenjdk",
"version_data": {
"build": 10,
"major": 11,
"minor": 0,
"openjdk_version": "11.0.8+10",
"security": 8,
"semver": "11.0.8+10"
}
},
{
"binaries": [],
"download_count": 1968658,
"id": "MDc6UmVsZWFzZTI4NTg5Nzcz.pCNBA7G9E1o7pw==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/tag/jdk-11.0.8%2B10",
"release_name": "jdk-11.0.8+10",
"release_type": "ga",
"timestamp": "2020-07-15T14:29:27Z",
"updated_at": "2020-07-15T14:29:27Z",
"vendor": "adoptopenjdk",
"version_data": {
"build": 10,
"major": 9,
"minor": 0,
"openjdk_version": "9.0.8+10",
"security": 8,
"semver": "9.0.8+10"
}
},
{
"binaries": [
{
"architecture": "x64",
"download_count": 149393,
"heap_size": "normal",
"image_type": "jdk",
"jvm_impl": "hotspot",
"os": "mac",
"package": {
"checksum": "4a8dadd58cdc32c7e59978971d56aec610be7ee0ddf0dc1d137bb8b78456499f",
"checksum_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.8%2B10/OpenJDK11U-jdk_x64_mac_hotspot_11.0.8_10.tar.gz.sha256.txt",
"download_count": 40158,
"link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.8%2B10/OpenJDK11U-jdk_x64_mac_hotspot_11.0.8_10.tar.gz",
"metadata_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.8%2B10/OpenJDK11U-jdk_x64_mac_hotspot_11.0.8_10.tar.gz.json",
"name": "OpenJDK11U-jdk_x64_mac_hotspot_11.0.8_10.tar.gz",
"size": 185054456
},
"project": "jdk",
"scm_ref": "jdk-11.0.8+10_adopt",
"updated_at": "2020-07-15T14:30:51Z"
}
],
"download_count": 1968658,
"id": "MDc6UmVsZWFzZTI4NTg5Nzcz.pCNBA7G9E1o7pw==",
"release_link": "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/tag/jdk-11.0.8%2B10",
"release_name": "jdk-11.0.8+10",
"release_type": "ga",
"timestamp": "2020-07-15T14:29:27Z",
"updated_at": "2020-07-15T14:29:27Z",
"vendor": "adoptopenjdk",
"version_data": {
"build": 10,
"major": 9,
"minor": 0,
"openjdk_version": "9.0.8+10",
"security": 8,
"semver": "9.0.7+10"
}
}
]

@ -0,0 +1,247 @@
[
{
"id": 10996,
"url": "https://cdn.azul.com/zulu/bin/zulu1.8.0_05-8.1.0.10-macosx.tar.gz",
"name": "zulu1.8.0_05-8.1.0.10-macosx.tar.gz",
"zulu_version": [8, 1, 0, 10],
"jdk_version": [8, 0, 5, 13]
},
{
"id": 10997,
"url": "https://cdn.azul.com/zulu/bin/zulu1.8.0_11-8.2.0.1-macosx.tar.gz",
"name": "zulu1.8.0_11-8.2.0.1-macosx.tar.gz",
"zulu_version": [8, 2, 0, 1],
"jdk_version": [8, 0, 11, 12]
},
{
"id": 10346,
"url": "https://cdn.azul.com/zulu/bin/zulu8.21.0.1-jdk8.0.131-macosx_x64.tar.gz",
"name": "zulu8.21.0.1-jdk8.0.131-macosx_x64.tar.gz",
"zulu_version": [8, 21, 0, 1],
"jdk_version": [8, 0, 131, 11]
},
{
"id": 10362,
"url": "https://cdn.azul.com/zulu/bin/zulu8.23.0.3-jdk8.0.144-macosx_x64.tar.gz",
"name": "zulu8.23.0.3-jdk8.0.144-macosx_x64.tar.gz",
"zulu_version": [8, 23, 0, 3],
"jdk_version": [8, 0, 144, 1]
},
{
"id": 10399,
"url": "https://cdn.azul.com/zulu/bin/zulu8.25.0.1-jdk8.0.152-macosx_x64.tar.gz",
"name": "zulu8.25.0.1-jdk8.0.152-macosx_x64.tar.gz",
"zulu_version": [8, 25, 0, 1],
"jdk_version": [8, 0, 152, 16]
},
{
"id": 11355,
"url": "https://cdn.azul.com/zulu/bin/zulu8.46.0.19-ca-jdk8.0.252-macosx_x64.tar.gz",
"name": "zulu8.46.0.19-ca-jdk8.0.252-macosx_x64.tar.gz",
"zulu_version": [8, 46, 0, 19],
"jdk_version": [8, 0, 252, 14]
},
{
"id": 11481,
"url": "https://cdn.azul.com/zulu/bin/zulu8.48.0.47-ca-jdk8.0.262-macosx_x64.tar.gz",
"name": "zulu8.48.0.47-ca-jdk8.0.262-macosx_x64.tar.gz",
"zulu_version": [8, 48, 0, 47],
"jdk_version": [8, 0, 262, 17]
},
{
"id": 11622,
"url": "https://cdn.azul.com/zulu/bin/zulu8.48.0.51-ca-jdk8.0.262-macosx_x64.tar.gz",
"name": "zulu8.48.0.51-ca-jdk8.0.262-macosx_x64.tar.gz",
"zulu_version": [8, 48, 0, 51],
"jdk_version": [8, 0, 262, 19]
},
{
"id": 11535,
"url": "https://cdn.azul.com/zulu/bin/zulu8.48.0.49-ca-jdk8.0.262-macosx_x64.tar.gz",
"name": "zulu8.48.0.49-ca-jdk8.0.262-macosx_x64.tar.gz",
"zulu_version": [8, 48, 0, 49],
"jdk_version": [8, 0, 262, 18]
},
{
"id": 12424,
"url": "https://cdn.azul.com/zulu/bin/zulu8.52.0.23-ca-jdk8.0.282-macosx_x64.tar.gz",
"name": "zulu8.52.0.23-ca-jdk8.0.282-macosx_x64.tar.gz",
"zulu_version": [8, 52, 0, 23],
"jdk_version": [8, 0, 282, 8]
},
{
"id": 10383,
"url": "https://cdn.azul.com/zulu/bin/zulu9.0.0.15-jdk9.0.0-macosx_x64.tar.gz",
"name": "zulu9.0.0.15-jdk9.0.0-macosx_x64.tar.gz",
"zulu_version": [9, 0, 0, 15],
"jdk_version": [9, 0, 0, 0]
},
{
"id": 10413,
"url": "https://cdn.azul.com/zulu/bin/zulu9.0.1.3-jdk9.0.1-macosx_x64.tar.gz",
"name": "zulu9.0.1.3-jdk9.0.1-macosx_x64.tar.gz",
"zulu_version": [9, 0, 1, 3],
"jdk_version": [9, 0, 1, 0]
},
{
"id": 10503,
"url": "https://cdn.azul.com/zulu/bin/zulu10.2+3-jdk10.0.1-macosx_x64.tar.gz",
"name": "zulu10.2+3-jdk10.0.1-macosx_x64.tar.gz",
"zulu_version": [10, 2, 3, 0],
"jdk_version": [10, 0, 1, 9]
},
{
"id": 10541,
"url": "https://cdn.azul.com/zulu/bin/zulu10.3+5-jdk10.0.2-macosx_x64.tar.gz",
"name": "zulu10.3+5-jdk10.0.2-macosx_x64.tar.gz",
"zulu_version": [10, 3, 5, 0],
"jdk_version": [10, 0, 2, 13]
},
{
"id": 10576,
"url": "https://cdn.azul.com/zulu/bin/zulu11.2.3-jdk11.0.1-macosx_x64.tar.gz",
"name": "zulu11.2.3-jdk11.0.1-macosx_x64.tar.gz",
"zulu_version": [11, 2, 3, 0],
"jdk_version": [11, 0, 1, 13]
},
{
"id": 10604,
"url": "https://cdn.azul.com/zulu/bin/zulu11.29.3-ca-jdk11.0.2-macosx_x64.tar.gz",
"name": "zulu11.29.3-ca-jdk11.0.2-macosx_x64.tar.gz",
"zulu_version": [11, 29, 3, 0],
"jdk_version": [11, 0, 2, 7]
},
{
"id": 10687,
"url": "https://cdn.azul.com/zulu/bin/zulu11.31.11-ca-jdk11.0.3-macosx_x64.tar.gz",
"name": "zulu11.31.11-ca-jdk11.0.3-macosx_x64.tar.gz",
"zulu_version": [11, 31, 11, 0],
"jdk_version": [11, 0, 3, 7]
},
{
"id": 10856,
"url": "https://cdn.azul.com/zulu/bin/zulu11.35.13-ca-jdk11.0.5-macosx_x64.tar.gz",
"name": "zulu11.35.13-ca-jdk11.0.5-macosx_x64.tar.gz",
"zulu_version": [11, 35, 13, 0],
"jdk_version": [11, 0, 5, 10]
},
{
"id": 10933,
"url": "https://cdn.azul.com/zulu/bin/zulu11.35.15-ca-jdk11.0.5-macosx_x64.tar.gz",
"name": "zulu11.35.15-ca-jdk11.0.5-macosx_x64.tar.gz",
"zulu_version": [11, 35, 15, 0],
"jdk_version": [11, 0, 5, 10]
},
{
"id": 10933,
"url": "https://cdn.azul.com/zulu/bin/zulu11.35.11-ca-jdk11.0.5-macosx_x64.tar.gz",
"name": "zulu11.35.15-ca-jdk11.0.5-macosx_x64.tar.gz",
"zulu_version": [11, 35, 11, 0],
"jdk_version": [11, 0, 5, 10]
},
{
"id": 12397,
"url": "https://cdn.azul.com/zulu/bin/zulu11.45.27-ca-jdk11.0.10-macosx_x64.tar.gz",
"name": "zulu11.45.27-ca-jdk11.0.10-macosx_x64.tar.gz",
"zulu_version": [11, 45, 27, 0],
"jdk_version": [11, 0, 10, 9]
},
{
"id": 10667,
"url": "https://cdn.azul.com/zulu/bin/zulu12.1.3-ca-jdk12.0.0-macosx_x64.tar.gz",
"name": "zulu12.1.3-ca-jdk12.0.0-macosx_x64.tar.gz",
"zulu_version": [12, 1, 3, 0],
"jdk_version": [12, 0, 0, 33]
},
{
"id": 10710,
"url": "https://cdn.azul.com/zulu/bin/zulu12.2.3-ca-jdk12.0.1-macosx_x64.tar.gz",
"name": "zulu12.2.3-ca-jdk12.0.1-macosx_x64.tar.gz",
"zulu_version": [12, 2, 3, 0],
"jdk_version": [12, 0, 1, 12]
},
{
"id": 10780,
"url": "https://cdn.azul.com/zulu/bin/zulu12.3.11-ca-jdk12.0.2-macosx_x64.tar.gz",
"name": "zulu12.3.11-ca-jdk12.0.2-macosx_x64.tar.gz",
"zulu_version": [12, 3, 11, 0],
"jdk_version": [12, 0, 2, 3]
},
{
"id": 10846,
"url": "https://cdn.azul.com/zulu/bin/zulu13.27.9-ca-jdk13.0.0-macosx_x64.tar.gz",
"name": "zulu13.27.9-ca-jdk13.0.0-macosx_x64.tar.gz",
"zulu_version": [13, 27, 9, 0],
"jdk_version": [13, 0, 0, 33]
},
{
"id": 10888,
"url": "https://cdn.azul.com/zulu/bin/zulu13.28.11-ca-jdk13.0.1-macosx_x64.tar.gz",
"name": "zulu13.28.11-ca-jdk13.0.1-macosx_x64.tar.gz",
"zulu_version": [13, 28, 11, 0],
"jdk_version": [13, 0, 1, 10]
},
{
"id": 11073,
"url": "https://cdn.azul.com/zulu/bin/zulu13.29.9-ca-jdk13.0.2-macosx_x64.tar.gz",
"name": "zulu13.29.9-ca-jdk13.0.2-macosx_x64.tar.gz",
"zulu_version": [13, 29, 9, 0],
"jdk_version": [13, 0, 2, 6]
},
{
"id": 12408,
"url": "https://cdn.azul.com/zulu/bin/zulu13.37.21-ca-jdk13.0.6-macosx_x64.tar.gz",
"name": "zulu13.37.21-ca-jdk13.0.6-macosx_x64.tar.gz",
"zulu_version": [13, 37, 21, 0],
"jdk_version": [13, 0, 6, 5]
},
{
"id": 11236,
"url": "https://cdn.azul.com/zulu/bin/zulu14.27.1-ca-jdk14.0.0-macosx_x64.tar.gz",
"name": "zulu14.27.1-ca-jdk14.0.0-macosx_x64.tar.gz",
"zulu_version": [14, 27, 1, 0],
"jdk_version": [14, 0, 0, 36]
},
{
"id": 11349,
"url": "https://cdn.azul.com/zulu/bin/zulu14.28.21-ca-jdk14.0.1-macosx_x64.tar.gz",
"name": "zulu14.28.21-ca-jdk14.0.1-macosx_x64.tar.gz",
"zulu_version": [14, 28, 21, 0],
"jdk_version": [14, 0, 1, 8]
},
{
"id": 11513,
"url": "https://cdn.azul.com/zulu/bin/zulu14.29.23-ca-jdk14.0.2-macosx_x64.tar.gz",
"name": "zulu14.29.23-ca-jdk14.0.2-macosx_x64.tar.gz",
"zulu_version": [14, 29, 23, 0],
"jdk_version": [14, 0, 2, 12]
},
{
"id": 11780,
"url": "https://cdn.azul.com/zulu/bin/zulu15.27.17-ca-jdk15.0.0-macosx_x64.tar.gz",
"name": "zulu15.27.17-ca-jdk15.0.0-macosx_x64.tar.gz",
"zulu_version": [15, 27, 17, 0],
"jdk_version": [15, 0, 0, 36]
},
{
"id": 11924,
"url": "https://cdn.azul.com/zulu/bin/zulu15.28.13-ca-jdk15.0.1-macosx_x64.tar.gz",
"name": "zulu15.28.13-ca-jdk15.0.1-macosx_x64.tar.gz",
"zulu_version": [15, 28, 13, 0],
"jdk_version": [15, 0, 1, 8]
},
{
"id": 12101,
"url": "https://cdn.azul.com/zulu/bin/zulu15.28.51-ca-jdk15.0.1-macosx_x64.tar.gz",
"name": "zulu15.28.51-ca-jdk15.0.1-macosx_x64.tar.gz",
"zulu_version": [15, 28, 51, 0],
"jdk_version": [15, 0, 1, 9]
},
{
"id": 12445,
"url": "https://cdn.azul.com/zulu/bin/zulu15.29.15-ca-jdk15.0.2-macosx_x64.tar.gz",
"name": "zulu15.29.15-ca-jdk15.0.2-macosx_x64.tar.gz",
"zulu_version": [15, 29, 15, 0],
"jdk_version": [15, 0, 2, 7]
}
]

@ -0,0 +1,154 @@
import { HttpClient } from '@actions/http-client';
import * as semver from 'semver';
import { AdoptDistribution } from '../../src/distributions/adopt/installer';
import { JavaInstallerOptions } from '../../src/distributions/base-models';
let manifestData = require('../data/adopt.json') as [];
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.each([
[
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false },
'os=mac&architecture=x64&image_type=jdk&release_type=ga&page_size=20&page=0'
],
[
{ version: '11', architecture: 'x86', packageType: 'jdk', checkLatest: false },
'os=mac&architecture=x86&image_type=jdk&release_type=ga&page_size=20&page=0'
],
[
{ version: '11', architecture: 'x64', packageType: 'jre', checkLatest: false },
'os=mac&architecture=x64&image_type=jre&release_type=ga&page_size=20&page=0'
],
[
{ version: '11-ea', architecture: 'x64', packageType: 'jdk', checkLatest: false },
'os=mac&architecture=x64&image_type=jdk&release_type=ea&page_size=20&page=0'
]
])(
'build correct url for %s',
async (installerOptions: JavaInstallerOptions, expectedParameters) => {
const distribution = new AdoptDistribution(installerOptions);
const baseUrl = 'https://api.adoptopenjdk.net/v3/assets/version/%5B1.0,100.0%5D';
const expectedUrl = `${baseUrl}?project=jdk&vendor=adoptopenjdk&heap_size=normal&jvm_impl=hotspot&sort_method=DEFAULT&sort_order=DESC&${expectedParameters}`;
distribution['getPlatformOption'] = () => 'mac';
await distribution['getAvailableVersions']();
expect(spyHttpClient.mock.calls).toHaveLength(1);
expect(spyHttpClient.mock.calls[0][0]).toBe(expectedUrl);
}
);
it('load available versions', async () => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
spyHttpClient
.mockReturnValueOnce({
statusCode: 200,
headers: {},
result: manifestData
})
.mockReturnValueOnce({
statusCode: 200,
headers: {},
result: manifestData
})
.mockReturnValueOnce({
statusCode: 200,
headers: {},
result: []
});
const distribution = new AdoptDistribution({
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
const availableVersions = await distribution['getAvailableVersions']();
expect(availableVersions).not.toBeNull();
expect(availableVersions.length).toBe(manifestData.length * 2);
});
});
describe('findPackageForDownload', () => {
it.each([
['9', '9.0.7+10'],
['15', '15.0.2+7'],
['15.0', '15.0.2+7'],
['15.0.2', '15.0.2+7'],
['15.0.1', '15.0.1+9.1'],
['11.x', '11.0.10+9'],
['x', '15.0.2+7'],
['12', '12.0.2+10.3'], // make sure that '12.0.2+10.1', '12.0.2+10.3', '12.0.2+10.2' are sorted correctly
['12.0.2+10.1', '12.0.2+10.1'],
['15.0.1+9', '15.0.1+9'],
['15.0.1+9.1', '15.0.1+9.1']
])('version is resolved correctly %s -> %s', async (input, expected) => {
const distribution = new AdoptDistribution({
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
distribution['getAvailableVersions'] = async () => manifestData;
const resolvedVersion = await distribution['findPackageForDownload'](input);
expect(resolvedVersion.version).toBe(expected);
});
it('version is found but binaries list is empty', async () => {
const distribution = new AdoptDistribution({
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
distribution['getAvailableVersions'] = async () => manifestData;
await expect(distribution['findPackageForDownload']('9.0.8')).rejects.toThrowError(
/Could not find satisfied version for SemVer */
);
});
it('version is not found', async () => {
const distribution = new AdoptDistribution({
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
distribution['getAvailableVersions'] = async () => manifestData;
await expect(distribution['findPackageForDownload']('7.x')).rejects.toThrowError(
/Could not find satisfied version for SemVer */
);
});
it('version list is empty', async () => {
const distribution = new AdoptDistribution({
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
distribution['getAvailableVersions'] = async () => [];
await expect(distribution['findPackageForDownload']('11')).rejects.toThrowError(
/Could not find satisfied version for SemVer */
);
});
});

@ -0,0 +1,351 @@
import * as tc from '@actions/tool-cache';
import * as core from '@actions/core';
import * as util from '../../src/util';
import path from 'path';
import * as semver from 'semver';
import { JavaBase } from '../../src/distributions/base-installer';
import {
JavaDownloadRelease,
JavaInstallerOptions,
JavaInstallerResults
} from '../../src/distributions/base-models';
class EmptyJavaBase extends JavaBase {
constructor(installerOptions: JavaInstallerOptions) {
super('Empty', installerOptions);
}
protected async downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults> {
return {
version: '11.0.9',
path: path.join('toolcache', this.toolcacheFolderName, '11.0.9', this.architecture)
};
}
protected async findPackageForDownload(range: string): Promise<JavaDownloadRelease> {
const availableVersion = '11.0.9';
if (!semver.satisfies(availableVersion, range)) {
throw new Error('Available version not found');
}
return {
version: availableVersion,
url: `some/random_url/java/${availableVersion}`
};
}
}
describe('findInToolcache', () => {
const actualJavaVersion = '11.0.8';
const javaPath = path.join('Java_Empty_jdk', actualJavaVersion, 'x64');
let mockJavaBase: EmptyJavaBase;
let spyGetToolcachePath: jest.SpyInstance;
let spyTcFindAllVersions: jest.SpyInstance;
beforeEach(() => {
spyGetToolcachePath = jest.spyOn(util, 'getToolcachePath');
spyTcFindAllVersions = jest.spyOn(tc, 'findAllVersions');
});
afterEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
});
it.each([
[
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{ version: actualJavaVersion, path: javaPath }
],
[
{ version: '11.0', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{ version: actualJavaVersion, path: javaPath }
],
[
{ version: '11.0.8', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{ version: actualJavaVersion, path: javaPath }
],
[
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: true },
{ version: actualJavaVersion, path: javaPath }
],
[
{ version: '11.0', architecture: 'x64', packageType: 'jdk', checkLatest: true },
{ version: actualJavaVersion, path: javaPath }
],
[
{ version: '11.0.8', architecture: 'x64', packageType: 'jdk', checkLatest: true },
{ version: actualJavaVersion, path: javaPath }
],
[{ version: '11', architecture: 'x64', packageType: 'jre', checkLatest: false }, null],
[{ version: '8', architecture: 'x64', packageType: 'jdk', checkLatest: false }, null],
[{ version: '11', architecture: 'x86', packageType: 'jdk', checkLatest: false }, null],
[{ version: '11', architecture: 'x86', packageType: 'jre', checkLatest: false }, null]
])(`should find java for path %s -> %s`, (input, expected) => {
spyTcFindAllVersions.mockReturnValue([actualJavaVersion]);
spyGetToolcachePath.mockImplementation(
(toolname: string, javaVersion: string, architecture: string) => {
const semverVersion = new semver.Range(javaVersion);
if (path.basename(javaPath) !== architecture || !javaPath.includes(toolname)) {
return '';
}
return semver.satisfies(actualJavaVersion, semverVersion) ? javaPath : '';
}
);
mockJavaBase = new EmptyJavaBase(input);
expect(mockJavaBase['findInToolcache']()).toEqual(expected);
});
it.each([
['11', { version: '11.0.3+2', versionInPath: '11.0.3-2' }],
['11.0', { version: '11.0.3+2', versionInPath: '11.0.3-2' }],
['11.0.1', { version: '11.0.1', versionInPath: '11.0.1' }],
['11.0.3', { version: '11.0.3+2', versionInPath: '11.0.3-2' }],
['15', { version: '15.0.2+4', versionInPath: '15.0.2-4' }],
['x', { version: '15.0.2+4', versionInPath: '15.0.2-4' }],
['x-ea', { version: '17.4.4', versionInPath: '17.4.4-ea' }],
['11-ea', { version: '11.3.3+5.2.1231421', versionInPath: '11.3.3-ea.5.2.1231421' }],
['11.2-ea', { version: '11.2.1', versionInPath: '11.2.1-ea' }],
['11.2.1-ea', { version: '11.2.1', versionInPath: '11.2.1-ea' }]
])('should choose correct java from tool-cache for input %s', (input, expected) => {
spyTcFindAllVersions.mockReturnValue([
'17.4.4-ea',
'11.0.2',
'15.0.2-4',
'11.0.3-2',
'11.2.1-ea',
'11.3.2-ea',
'11.3.2-ea.5',
'11.3.3-ea.5.2.1231421',
'12.3.2-0',
'11.0.1'
]);
spyGetToolcachePath.mockImplementation(
(toolname: string, javaVersion: string, architecture: string) =>
`/hostedtoolcache/${toolname}/${javaVersion}/${architecture}`
);
mockJavaBase = new EmptyJavaBase({
version: input,
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
const foundVersion = mockJavaBase['findInToolcache']();
expect(foundVersion).toEqual({
version: expected.version,
path: `/hostedtoolcache/Java_Empty_jdk/${expected.versionInPath}/x64`
});
});
});
describe('setupJava', () => {
const actualJavaVersion = '11.0.9';
const installedJavaVersion = '11.0.8';
const javaPath = path.join('Java_Empty_jdk', installedJavaVersion, 'x86');
const javaPathInstalled = path.join('toolcache', 'Java_Empty_jdk', actualJavaVersion, 'x86');
let mockJavaBase: EmptyJavaBase;
let spyGetToolcachePath: jest.SpyInstance;
let spyTcFindAllVersions: jest.SpyInstance;
let spyCoreDebug: jest.SpyInstance;
let spyCoreInfo: jest.SpyInstance;
let spyCoreExportVariable: jest.SpyInstance;
let spyCoreAddPath: jest.SpyInstance;
let spyCoreSetOutput: jest.SpyInstance;
beforeEach(() => {
spyGetToolcachePath = jest.spyOn(util, 'getToolcachePath');
spyGetToolcachePath.mockImplementation(
(toolname: string, javaVersion: string, architecture: string) => {
const semverVersion = new semver.Range(javaVersion);
if (path.basename(javaPath) !== architecture || !javaPath.includes(toolname)) {
return '';
}
return semver.satisfies(installedJavaVersion, semverVersion) ? javaPath : '';
}
);
spyTcFindAllVersions = jest.spyOn(tc, 'findAllVersions');
spyTcFindAllVersions.mockReturnValue([installedJavaVersion]);
// Spy on core methods
spyCoreDebug = jest.spyOn(core, 'debug');
spyCoreDebug.mockImplementation(() => undefined);
spyCoreInfo = jest.spyOn(core, 'info');
spyCoreInfo.mockImplementation(() => undefined);
spyCoreAddPath = jest.spyOn(core, 'addPath');
spyCoreAddPath.mockImplementation(() => undefined);
spyCoreExportVariable = jest.spyOn(core, 'exportVariable');
spyCoreExportVariable.mockImplementation(() => undefined);
spyCoreSetOutput = jest.spyOn(core, 'setOutput');
spyCoreSetOutput.mockImplementation(() => undefined);
});
afterEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
});
it.each([
[
{ version: '11', architecture: 'x86', packageType: 'jdk', checkLatest: false },
{ version: installedJavaVersion, path: javaPath }
],
[
{ version: '11.0', architecture: 'x86', packageType: 'jdk', checkLatest: false },
{ version: installedJavaVersion, path: javaPath }
],
[
{ version: '11.0.8', architecture: 'x86', packageType: 'jdk', checkLatest: false },
{ version: installedJavaVersion, path: javaPath }
]
])('should find java locally for %s', (input, expected) => {
mockJavaBase = new EmptyJavaBase(input);
expect(mockJavaBase.setupJava()).resolves.toEqual(expected);
expect(spyGetToolcachePath).toHaveBeenCalled();
expect(spyCoreInfo).toHaveBeenCalledWith(`Resolved Java ${expected.version} from tool-cache`);
expect(spyCoreInfo).toHaveBeenCalledWith(`Setting Java ${expected.version} as the default`);
expect(spyCoreInfo).not.toHaveBeenCalledWith(
'Trying to resolve the latest version from remote'
);
expect(spyCoreInfo).not.toHaveBeenCalledWith('Trying to download...');
});
it.each([
[
{ version: '11', architecture: 'x86', packageType: 'jre', checkLatest: false },
{ path: path.join('toolcache', 'Java_Empty_jre', '11.0.9', 'x86'), version: '11.0.9' }
],
[
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{ path: path.join('toolcache', 'Java_Empty_jdk', '11.0.9', 'x64'), version: '11.0.9' }
],
[
{ version: '11', architecture: 'x64', packageType: 'jre', checkLatest: false },
{ path: path.join('toolcache', 'Java_Empty_jre', '11.0.9', 'x64'), version: '11.0.9' }
]
])('download java with configuration %s', async (input, expected) => {
mockJavaBase = new EmptyJavaBase(input);
await expect(mockJavaBase.setupJava()).resolves.toEqual(expected);
expect(spyGetToolcachePath).toHaveBeenCalled();
expect(spyCoreAddPath).toHaveBeenCalled();
expect(spyCoreExportVariable).toHaveBeenCalled();
expect(spyCoreSetOutput).toHaveBeenCalled();
expect(spyCoreInfo).toHaveBeenCalledWith('Trying to resolve the latest version from remote');
expect(spyCoreInfo).toHaveBeenCalledWith(`Resolved latest version as ${expected.version}`);
expect(spyCoreInfo).toHaveBeenCalledWith('Trying to download...');
expect(spyCoreInfo).toHaveBeenCalledWith(`Java ${expected.version} was downloaded`);
expect(spyCoreInfo).toHaveBeenCalledWith(`Setting Java ${expected.version} as the default`);
});
it.each([
[
{ version: '11.0.9', architecture: 'x86', packageType: 'jdk', checkLatest: true },
{ version: '11.0.9', path: javaPathInstalled }
]
])('should check the latest java version for %s and resolve locally', async (input, expected) => {
mockJavaBase = new EmptyJavaBase(input);
mockJavaBase['findInToolcache'] = () => ({ version: '11.0.9', path: expected.path });
await expect(mockJavaBase.setupJava()).resolves.toEqual(expected);
expect(spyCoreInfo).toHaveBeenCalledWith('Trying to resolve the latest version from remote');
expect(spyCoreInfo).toHaveBeenCalledWith(`Resolved latest version as ${expected.version}`);
expect(spyCoreInfo).toHaveBeenCalledWith(`Resolved Java ${expected.version} from tool-cache`);
expect(spyCoreInfo).toHaveBeenCalledWith(`Setting Java ${expected.version} as the default`);
});
it.each([
[
{ version: '11', architecture: 'x86', packageType: 'jdk', checkLatest: true },
{ version: actualJavaVersion, path: javaPathInstalled }
],
[
{ version: '11.0', architecture: 'x86', packageType: 'jdk', checkLatest: true },
{ version: actualJavaVersion, path: javaPathInstalled }
],
[
{ version: '11.0.x', architecture: 'x86', packageType: 'jdk', checkLatest: true },
{ version: actualJavaVersion, path: javaPathInstalled }
]
])('should check the latest java version for %s and download', async (input, expected) => {
mockJavaBase = new EmptyJavaBase(input);
await expect(mockJavaBase.setupJava()).resolves.toEqual(expected);
expect(spyGetToolcachePath).toHaveBeenCalled();
expect(spyCoreInfo).toHaveBeenCalledWith('Trying to resolve the latest version from remote');
expect(spyCoreInfo).toHaveBeenCalledWith(`Resolved latest version as ${actualJavaVersion}`);
expect(spyCoreInfo).toHaveBeenCalledWith('Trying to download...');
expect(spyCoreInfo).toHaveBeenCalledWith(`Java ${actualJavaVersion} was downloaded`);
expect(spyCoreInfo).toHaveBeenCalledWith(`Setting Java ${expected.version} as the default`);
});
it.each([
[{ version: '15', architecture: 'x86', packageType: 'jre', checkLatest: false }],
[{ version: '11.0.7', architecture: 'x64', packageType: 'jre', checkLatest: false }]
])('should throw an error for Available version not found for %s', async input => {
mockJavaBase = new EmptyJavaBase(input);
await expect(mockJavaBase.setupJava()).rejects.toThrowError('Available version not found');
expect(spyTcFindAllVersions).toHaveBeenCalled();
expect(spyCoreAddPath).not.toHaveBeenCalled();
expect(spyCoreExportVariable).not.toHaveBeenCalled();
expect(spyCoreSetOutput).not.toHaveBeenCalled();
});
});
describe('normalizeVersion', () => {
const DummyJavaBase = JavaBase as any;
it.each([
['11', { version: '11', stable: true }],
['11.0', { version: '11.0', stable: true }],
['11.0.10', { version: '11.0.10', stable: true }],
['11-ea', { version: '11', stable: false }],
['11.0.2-ea', { version: '11.0.2', stable: false }]
])('normalizeVersion from %s to %s', (input, expected) => {
expect(DummyJavaBase.prototype.normalizeVersion.call(null, input)).toEqual(expected);
});
it('normalizeVersion should throw an error for non semver', () => {
const version = '11g';
expect(DummyJavaBase.prototype.normalizeVersion.bind(null, version)).toThrowError(
`The string '${version}' is not valid SemVer notation for a Java version. Please check README file for code snippets and more detailed information`
);
});
});
describe('getToolcacheVersionName', () => {
const DummyJavaBase = JavaBase as any;
it.each([
[{ version: '11', stable: true }, '11'],
[{ version: '11.0.2', stable: true }, '11.0.2'],
[{ version: '11.0.2+4', stable: true }, '11.0.2-4'],
[{ version: '11.0.2+4.1.2563234', stable: true }, '11.0.2-4.1.2563234'],
[{ version: '11.0', stable: false }, '11.0-ea'],
[{ version: '11.0.3', stable: false }, '11.0.3-ea'],
[{ version: '11.0.3+4', stable: false }, '11.0.3-ea.4'],
[{ version: '11.0.3+4.2.256', stable: false }, '11.0.3-ea.4.2.256']
])('returns correct version name for %s', (input, expected) => {
const inputVersion = input.stable ? '11' : '11-ea';
const mockJavaBase = new EmptyJavaBase({
version: inputVersion,
packageType: 'jdk',
architecture: 'x64',
checkLatest: false
});
const actual = mockJavaBase['getToolcacheVersionName'](input.version);
expect(actual).toBe(expected);
});
});

@ -0,0 +1,235 @@
import fs from 'fs';
import * as tc from '@actions/tool-cache';
import * as core from '@actions/core';
import path from 'path';
import * as semver from 'semver';
import * as util from '../../src/util';
import { LocalDistribution } from '../../src/distributions/local/installer';
describe('setupJava', () => {
const actualJavaVersion = '11.1.10';
const javaPath = path.join('Java_jdkfile_jdk', actualJavaVersion, 'x86');
let mockJavaBase: LocalDistribution;
let spyGetToolcachePath: jest.SpyInstance;
let spyTcCacheDir: jest.SpyInstance;
let spyTcFindAllVersions: jest.SpyInstance;
let spyCoreDebug: jest.SpyInstance;
let spyCoreInfo: jest.SpyInstance;
let spyCoreExportVariable: jest.SpyInstance;
let spyCoreAddPath: jest.SpyInstance;
let spyCoreSetOutput: jest.SpyInstance;
let spyFsStat: jest.SpyInstance;
let spyFsReadDir: jest.SpyInstance;
let spyUtilsExtractJdkFile: jest.SpyInstance;
let spyPathResolve: jest.SpyInstance;
let expectedJdkFile = 'JavaLocalJdkFile';
beforeEach(() => {
spyGetToolcachePath = jest.spyOn(util, 'getToolcachePath');
spyGetToolcachePath.mockImplementation(
(toolname: string, javaVersion: string, architecture: string) => {
const semverVersion = new semver.Range(javaVersion);
if (path.basename(javaPath) !== architecture || !javaPath.includes(toolname)) {
return '';
}
return semver.satisfies(actualJavaVersion, semverVersion) ? javaPath : '';
}
);
spyTcCacheDir = jest.spyOn(tc, 'cacheDir');
spyTcCacheDir.mockImplementation(
(archivePath: string, toolcacheFolderName: string, version: string, architecture: string) =>
path.join(toolcacheFolderName, version, architecture)
);
spyTcFindAllVersions = jest.spyOn(tc, 'findAllVersions');
spyTcFindAllVersions.mockReturnValue([actualJavaVersion]);
// Spy on core methods
spyCoreDebug = jest.spyOn(core, 'debug');
spyCoreDebug.mockImplementation(() => undefined);
spyCoreInfo = jest.spyOn(core, 'info');
spyCoreInfo.mockImplementation(() => undefined);
spyCoreAddPath = jest.spyOn(core, 'addPath');
spyCoreAddPath.mockImplementation(() => undefined);
spyCoreExportVariable = jest.spyOn(core, 'exportVariable');
spyCoreExportVariable.mockImplementation(() => undefined);
spyCoreSetOutput = jest.spyOn(core, 'setOutput');
spyCoreSetOutput.mockImplementation(() => undefined);
// Spy on fs methods
spyFsReadDir = jest.spyOn(fs, 'readdirSync');
spyFsReadDir.mockImplementation(() => ['JavaTest']);
spyFsStat = jest.spyOn(fs, 'statSync');
spyFsStat.mockImplementation((file: string) => {
return { isFile: () => file === expectedJdkFile };
});
// Spy on util methods
spyUtilsExtractJdkFile = jest.spyOn(util, 'extractJdkFile');
spyUtilsExtractJdkFile.mockImplementation(() => 'some/random/path/');
// Spy on path methods
spyPathResolve = jest.spyOn(path, 'resolve');
spyPathResolve.mockImplementation((path: string) => path);
});
afterEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
});
it('java is resolved from toolcache, jdkfile is untouched', async () => {
const inputs = {
version: actualJavaVersion,
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
};
const jdkFile = 'not_existing_one';
const expected = {
version: actualJavaVersion,
path: path.join('Java_jdkfile_jdk', inputs.version, inputs.architecture)
};
mockJavaBase = new LocalDistribution(inputs, jdkFile);
await expect(mockJavaBase.setupJava()).resolves.toEqual(expected);
expect(spyGetToolcachePath).toHaveBeenCalled();
expect(spyCoreInfo).toHaveBeenCalledWith(`Resolved Java ${actualJavaVersion} from tool-cache`);
expect(spyCoreInfo).not.toHaveBeenCalledWith(
`Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...`
);
});
it("java is resolved from toolcache, jdkfile doesn't exist", async () => {
const inputs = {
version: actualJavaVersion,
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
};
const jdkFile = undefined;
const expected = {
version: actualJavaVersion,
path: path.join('Java_jdkfile_jdk', inputs.version, inputs.architecture)
};
mockJavaBase = new LocalDistribution(inputs, jdkFile);
await expect(mockJavaBase.setupJava()).resolves.toEqual(expected);
expect(spyGetToolcachePath).toHaveBeenCalled();
expect(spyCoreInfo).toHaveBeenCalledWith(`Resolved Java ${actualJavaVersion} from tool-cache`);
expect(spyCoreInfo).not.toHaveBeenCalledWith(
`Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...`
);
});
it('java is unpacked from jdkfile', async () => {
const inputs = {
version: '11.0.289',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
};
const jdkFile = expectedJdkFile;
const expected = {
version: '11.0.289',
path: path.join('Java_jdkfile_jdk', inputs.version, inputs.architecture)
};
mockJavaBase = new LocalDistribution(inputs, jdkFile);
await expect(mockJavaBase.setupJava()).resolves.toEqual(expected);
expect(spyTcFindAllVersions).toHaveBeenCalled();
expect(spyCoreInfo).not.toHaveBeenCalledWith(
`Resolved Java ${actualJavaVersion} from tool-cache`
);
expect(spyCoreInfo).toHaveBeenCalledWith(`Extracting Java from '${jdkFile}'`);
expect(spyCoreInfo).toHaveBeenCalledWith(
`Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...`
);
});
it('jdk file is not found', async () => {
const inputs = {
version: '11.0.289',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
};
const jdkFile = 'not_existing_one';
const expected = {
javaVersion: '11.0.289',
javaPath: path.join('Java_jdkfile_jdk', inputs.version, inputs.architecture)
};
mockJavaBase = new LocalDistribution(inputs, jdkFile);
expected.javaPath = path.join('Java_jdkfile_jdk', inputs.version, inputs.architecture);
await expect(mockJavaBase.setupJava()).rejects.toThrowError(
"JDK file was not found in path 'not_existing_one'"
);
expect(spyTcFindAllVersions).toHaveBeenCalled();
expect(spyCoreInfo).not.toHaveBeenCalledWith(
`Resolved Java ${actualJavaVersion} from tool-cache`
);
expect(spyCoreInfo).not.toHaveBeenCalledWith(`Extracting Java from '${jdkFile}'`);
expect(spyCoreInfo).toHaveBeenCalledWith(
`Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...`
);
});
it.each([
[
{ version: '8.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false },
'otherJdkFile'
],
[
{ version: '11.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false },
'otherJdkFile'
],
[
{ version: '12.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false },
'otherJdkFile'
],
[
{ version: '11.1.11', architecture: 'x64', packageType: 'jdk', checkLatest: false },
'not_existing_one'
]
])(
`Throw an error if jdkfile has wrong path, inputs %s, jdkfile %s, real name ${expectedJdkFile}`,
async (inputs, jdkFile) => {
mockJavaBase = new LocalDistribution(inputs, jdkFile);
await expect(mockJavaBase.setupJava()).rejects.toThrowError(
/JDK file was not found in path */
);
expect(spyTcFindAllVersions).toHaveBeenCalled();
}
);
it.each([
[{ version: '8.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false }, ''],
[
{ version: '7.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false },
undefined
],
[
{ version: '11.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false },
undefined
]
])('Throw an error if jdkfile is not specified, inputs %s', async (inputs, jdkFile) => {
mockJavaBase = new LocalDistribution(inputs, jdkFile);
await expect(mockJavaBase.setupJava()).rejects.toThrowError("'jdkFile' is not specified");
expect(spyTcFindAllVersions).toHaveBeenCalled();
});
});

@ -0,0 +1,165 @@
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';
const manifestData = require('../data/zulu-releases-default.json') as [];
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
let spyUtilGetDownloadArchiveExtension: jest.SpyInstance;
beforeEach(() => {
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
spyHttpClient.mockReturnValue({
statusCode: 200,
headers: {},
result: manifestData as IZuluVersions[]
});
spyUtilGetDownloadArchiveExtension = jest.spyOn(utils, 'getDownloadArchiveExtension');
spyUtilGetDownloadArchiveExtension.mockReturnValue('tar.gz');
});
afterEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
});
it.each([
[
{ version: '11', architecture: 'x86', packageType: 'jdk', checkLatest: false },
'?os=macos&ext=tar.gz&bundle_type=jdk&javafx=false&arch=x86&hw_bitness=32&release_status=ga'
],
[
{ version: '11-ea', architecture: 'x86', packageType: 'jdk', checkLatest: false },
'?os=macos&ext=tar.gz&bundle_type=jdk&javafx=false&arch=x86&hw_bitness=32&release_status=ea'
],
[
{ version: '8', architecture: 'x64', packageType: 'jdk', checkLatest: false },
'?os=macos&ext=tar.gz&bundle_type=jdk&javafx=false&arch=x86&hw_bitness=64&release_status=ga'
],
[
{ version: '8', architecture: 'x64', packageType: 'jre', checkLatest: false },
'?os=macos&ext=tar.gz&bundle_type=jre&javafx=false&arch=x86&hw_bitness=64&release_status=ga'
],
[
{ version: '8', architecture: 'x64', packageType: 'jdk+fx', checkLatest: false },
'?os=macos&ext=tar.gz&bundle_type=jdk&javafx=true&arch=x86&hw_bitness=64&release_status=ga&features=fx'
],
[
{ version: '8', architecture: 'x64', packageType: 'jre+fx', checkLatest: false },
'?os=macos&ext=tar.gz&bundle_type=jre&javafx=true&arch=x86&hw_bitness=64&release_status=ga&features=fx'
]
])('build correct url for %s -> %s', async (input, parsedUrl) => {
const distribution = new ZuluDistribution(input);
distribution['getPlatformOption'] = () => 'macos';
const buildUrl = `https://api.azul.com/zulu/download/community/v1.0/bundles/${parsedUrl}`;
await distribution['getAvailableVersions']();
expect(spyHttpClient.mock.calls).toHaveLength(1);
expect(spyHttpClient.mock.calls[0][0]).toBe(buildUrl);
});
it('load available versions', async () => {
const distribution = new ZuluDistribution({
version: '11',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
});
const availableVersions = await distribution['getAvailableVersions']();
expect(availableVersions).toHaveLength(manifestData.length);
});
});
describe('getArchitectureOptions', () => {
it.each([
[{ architecture: 'x64' }, { arch: 'x86', hw_bitness: '64', abi: '' }],
[{ architecture: 'x86' }, { arch: 'x86', hw_bitness: '32', abi: '' }],
[{ architecture: 'x32' }, { arch: 'x32', hw_bitness: '', abi: '' }],
[{ architecture: 'arm' }, { arch: 'arm', hw_bitness: '', abi: '' }]
])('%s -> %s', (input, expected) => {
const distribution = new ZuluDistribution({
version: '11',
architecture: input.architecture,
packageType: 'jdk',
checkLatest: false
});
expect(distribution['getArchitectureOptions']()).toEqual(expected);
});
});
describe('findPackageForDownload', () => {
it.each([
['8', '8.0.282+8'],
['11.x', '11.0.10+9'],
['8.0', '8.0.282+8'],
['11.0.x', '11.0.10+9'],
['15', '15.0.2+7'],
['9.0.0', '9.0.0+0'],
['9.0', '9.0.1+0'],
['8.0.262', '8.0.262+19'], // validate correct choise between [8.0.262.17, 8.0.262.19, 8.0.262.18]
['8.0.262+17', '8.0.262+17'],
['15.0.1+8', '15.0.1+8'],
['15.0.1+9', '15.0.1+9']
])('version is %s -> %s', async (input, expected) => {
const distribution = new ZuluDistribution({
version: input,
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
});
distribution['getAvailableVersions'] = async () => manifestData;
const result = await distribution['findPackageForDownload'](distribution['version']);
expect(result.version).toBe(expected);
});
it('select correct bundle if there are multiple items with the same jdk version but different zulu versions', async () => {
const distribution = new ZuluDistribution({
version: '',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
});
distribution['getAvailableVersions'] = async () => manifestData;
const result = await distribution['findPackageForDownload']('11.0.5');
expect(result.url).toBe(
'https://cdn.azul.com/zulu/bin/zulu11.35.15-ca-jdk11.0.5-macosx_x64.tar.gz'
);
});
it('should throw an error', async () => {
const distribution = new ZuluDistribution({
version: '18',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
});
await expect(
distribution['findPackageForDownload'](distribution['version'])
).rejects.toThrowError(/Could not find satisfied version for semver */);
});
});
describe('convertVersionToSemver', () => {
it.each([
[[12], '12'],
[[12, 0], '12.0'],
[[12, 0, 2], '12.0.2'],
[[12, 0, 2, 1], '12.0.2+1'],
[[12, 0, 2, 1, 3], '12.0.2+1']
])('%s -> %s', (input: number[], expected: string) => {
const distribution = new ZuluDistribution({
version: '18',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
});
const actual = distribution['convertVersionToSemver'](input);
expect(actual).toBe(expected);
});
});

@ -33,11 +33,7 @@ describe('gpg tests', () => {
expect(keyId).toBeNull();
expect(exec.exec).toHaveBeenCalledWith(
'gpg',
expect.anything(),
expect.anything()
);
expect(exec.exec).toHaveBeenCalledWith('gpg', expect.anything(), expect.anything());
});
});
@ -46,11 +42,7 @@ describe('gpg tests', () => {
const keyId = 'asdfhjkl';
await gpg.deleteKey(keyId);
expect(exec.exec).toHaveBeenCalledWith(
'gpg',
expect.anything(),
expect.anything()
);
expect(exec.exec).toHaveBeenCalledWith('gpg', expect.anything(), expect.anything());
});
});
});

@ -1,159 +0,0 @@
import io = require('@actions/io');
import fs = require('fs');
import path = require('path');
import child_process = require('child_process');
const toolDir = path.join(__dirname, 'runner', 'tools');
const tempDir = path.join(__dirname, 'runner', 'temp');
const javaDir = path.join(__dirname, 'runner', 'java');
process.env['RUNNER_TOOL_CACHE'] = toolDir;
process.env['RUNNER_TEMP'] = tempDir;
import * as installer from '../src/installer';
let javaFilePath = '';
let javaUrl = '';
if (process.platform === 'win32') {
javaFilePath = path.join(javaDir, 'java_win.zip');
javaUrl =
'https://download.java.net/java/GA/jdk12/33/GPL/openjdk-12_windows-x64_bin.zip';
} else if (process.platform === 'darwin') {
javaFilePath = path.join(javaDir, 'java_mac.tar.gz');
javaUrl =
'https://download.java.net/java/GA/jdk12/33/GPL/openjdk-12_osx-x64_bin.tar.gz';
} else {
javaFilePath = path.join(javaDir, 'java_linux.tar.gz');
javaUrl =
'https://download.java.net/java/GA/jdk12/33/GPL/openjdk-12_linux-x64_bin.tar.gz';
}
describe('installer tests', () => {
beforeAll(async () => {
await io.rmRF(toolDir);
await io.rmRF(tempDir);
if (!fs.existsSync(`${javaFilePath}.complete`)) {
// Download java
await io.mkdirP(javaDir);
console.log('Downloading java');
child_process.execSync(`curl "${javaUrl}" > "${javaFilePath}"`);
// Write complete file so we know it was successful
fs.writeFileSync(`${javaFilePath}.complete`, 'content');
}
}, 300000);
afterAll(async () => {
try {
await io.rmRF(toolDir);
await io.rmRF(tempDir);
} catch {
console.log('Failed to remove test directories');
}
}, 100000);
it('Installs version of Java from jdkFile if no matching version is installed', async () => {
await installer.getJava('12', 'x64', javaFilePath, 'jdk');
const JavaDir = path.join(toolDir, 'jdk', '12.0.0', 'x64');
expect(fs.existsSync(`${JavaDir}.complete`)).toBe(true);
expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true);
}, 100000);
it('Throws if invalid directory to jdk', async () => {
let thrown = false;
try {
await installer.getJava('1000', 'x64', 'bad path', 'jdk');
} catch {
thrown = true;
}
expect(thrown).toBe(true);
});
it('Downloads java if no file given', async () => {
await installer.getJava('8.0.102', 'x64', '', 'jdk');
const JavaDir = path.join(toolDir, 'jdk', '8.0.102', 'x64');
expect(fs.existsSync(`${JavaDir}.complete`)).toBe(true);
expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true);
}, 100000);
it('Downloads java with 1.x syntax', async () => {
await installer.getJava('1.10', 'x64', '', 'jdk');
const JavaDir = path.join(toolDir, 'jdk', '10.0.2', 'x64');
expect(fs.existsSync(`${JavaDir}.complete`)).toBe(true);
expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true);
}, 100000);
it('Downloads java with normal semver syntax', async () => {
await installer.getJava('9.0.x', 'x64', '', 'jdk');
const JavaDir = path.join(toolDir, 'jdk', '9.0.7', 'x64');
expect(fs.existsSync(`${JavaDir}.complete`)).toBe(true);
expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true);
}, 100000);
it('Downloads java if package is jre', async () => {
await installer.getJava('8.0.222', 'x64', '', 'jre');
const JavaDir = path.join(toolDir, 'jre', '8.0.222', 'x64');
expect(fs.existsSync(`${JavaDir}.complete`)).toBe(true);
expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true);
}, 100000);
it('Downloads java if package is jdk+fx', async () => {
await installer.getJava('8.0.222', 'x64', '', 'jdk+fx');
const JavaDir = path.join(toolDir, 'jdk+fx', '8.0.222', 'x64');
expect(fs.existsSync(`${JavaDir}.complete`)).toBe(true);
expect(fs.existsSync(path.join(JavaDir, 'bin'))).toBe(true);
}, 100000);
it('Throws if invalid java package is specified', async () => {
let thrown = false;
try {
await installer.getJava('8.0.222', 'x64', '', 'bad jdk');
} catch {
thrown = true;
}
expect(thrown).toBe(true);
});
it('Throws if invalid directory to jdk', async () => {
let thrown = false;
try {
await installer.getJava('1000', 'x64', 'bad path', 'jdk');
} catch {
thrown = true;
}
expect(thrown).toBe(true);
});
it('Uses version of Java installed in cache', async () => {
const JavaDir: string = path.join(toolDir, 'jdk', '250.0.0', 'x64');
await io.mkdirP(JavaDir);
fs.writeFileSync(`${JavaDir}.complete`, 'hello');
// This will throw if it doesn't find it in the cache (because no such version exists)
await installer.getJava(
'250',
'x64',
'path shouldnt matter, found in cache',
'jdk'
);
return;
});
it('Doesnt use version of Java that was only partially installed in cache', async () => {
const JavaDir: string = path.join(toolDir, 'jdk', '251.0.0', 'x64');
await io.mkdirP(JavaDir);
let thrown = false;
try {
// This will throw if it doesn't find it in the cache (because no such version exists)
await installer.getJava('251', 'x64', 'bad path', 'jdk');
} catch {
thrown = true;
}
expect(thrown).toBe(true);
return;
});
});

@ -1,61 +1,22 @@
import path = require('path');
import { isVersionSatisfies } from '../src/util';
const env = process.env;
describe('util tests', () => {
beforeEach(() => {
const tempEnv = Object.assign({}, env);
delete tempEnv.RUNNER_TEMP;
delete tempEnv.USERPROFILE;
process.env = tempEnv;
Object.defineProperty(process, 'platform', {value: 'linux'});
});
describe('getTempDir', () => {
it('gets temp dir using env', () => {
process.env['RUNNER_TEMP'] = 'defaulttmp';
const util = require('../src/util');
const tempDir = util.getTempDir();
expect(tempDir).toEqual(process.env['RUNNER_TEMP']);
});
it('gets temp dir for windows using userprofile', () => {
Object.defineProperty(process, 'platform', {value: 'win32'});
process.env['USERPROFILE'] = 'winusertmp';
const util = require('../src/util');
const tempDir = util.getTempDir();
expect(tempDir).toEqual(
path.join(process.env['USERPROFILE'], 'actions', 'temp')
);
});
it('gets temp dir for windows using c drive', () => {
Object.defineProperty(process, 'platform', {value: 'win32'});
const util = require('../src/util');
const tempDir = util.getTempDir();
expect(tempDir).toEqual(path.join('C:\\', 'actions', 'temp'));
});
it('gets temp dir for mac', () => {
Object.defineProperty(process, 'platform', {value: 'darwin'});
const util = require('../src/util');
const tempDir = util.getTempDir();
expect(tempDir).toEqual(path.join('/Users', 'actions', 'temp'));
});
it('gets temp dir for linux', () => {
const util = require('../src/util');
const tempDir = util.getTempDir();
expect(tempDir).toEqual(path.join('/home', 'actions', 'temp'));
});
describe('isVersionSatisfies', () => {
it.each([
['x', '11.0.0', true],
['3', '3.7.1', true],
['3', '3.7.2', true],
['3', '3.7.2+4', true],
['2.5', '2.5.0', true],
['2.5', '2.5.0+1', true],
['2.5', '2.6.1', false],
['2.5.1', '2.5.0', false],
['2.5.1+3', '2.5.0', false],
['2.5.1+3', '2.5.1+3', true],
['2.5.1+3', '2.5.1+2', false],
['15.0.0+14', '15.0.0+14.1.202003190635', false],
['15.0.0+14.1.202003190635', '15.0.0+14.1.202003190635', true]
])('%s, %s -> %s', (inputRange: string, inputVersion: string, expected: boolean) => {
const actual = isVersionSatisfies(inputRange, inputVersion);
expect(actual).toBe(expected);
});
});

@ -1,31 +0,0 @@
if (!$args.Count -or !$args[0])
{
throw "Must supply java version argument"
}
$java_version = & cmd.exe /c "java -version 2>&1" | Out-String
Write-Host "Found java version: $java_version"
if (!$java_version.Contains($args[0]))
{
throw "Unexpected version"
}
if ($args.Count -lt 2 -or !$args[1])
{
throw "Must supply java path argument"
}
if ($args[1] -ne $Env:JAVA_HOME)
{
throw "Unexpected path"
}
if ($args.Count -lt 3 -or !$args[2])
{
throw "Must supply java version argument"
}
if ($args[0] -ne $args[2])
{
throw "Unexpected version"
}

@ -5,29 +5,35 @@ if [ -z "$1" ]; then
exit 1
fi
java_version="$(java -version 2>&1)"
echo "Found java version: $java_version"
if [ -z "$(echo $java_version | grep --fixed-strings $1)" ]; then
echo "::error::Unexpected version"
exit 1
fi
if [ -z "$2" ]; then
echo "::error::Must supply java path argument"
exit 1
fi
if [ "$2" != "$JAVA_HOME" ]; then
echo "::error::Unexpected path"
exit 1
EXPECTED_JAVA_VERSION=$1
EXPECTED_PATH=$2
EXPECTED_JAVA_VERSION=$(echo $EXPECTED_JAVA_VERSION | cut -d'+' -f1)
if [[ $EXPECTED_JAVA_VERSION == 8 ]] || [[ $EXPECTED_JAVA_VERSION == 8.* ]]; then
EXPECTED_JAVA_VERSION="1.${EXPECTED_JAVA_VERSION}"
fi
if [[ $EXPECTED_JAVA_VERSION == *-ea* ]]; then
EXPECTED_JAVA_VERSION=$(echo $EXPECTED_JAVA_VERSION | cut -d'-' -f1 | cut -d'.' -f1)
fi
if [ -z "$3" ]; then
echo "::error::Must supply java version argument"
exit 1
fi
ACTUAL_JAVA_VERSION="$(java -version 2>&1)"
echo "Found java version: $ACTUAL_JAVA_VERSION"
if [ "$1" != "$3" ]; then
GREP_RESULT=$(echo $ACTUAL_JAVA_VERSION | grep "^openjdk version \"$EXPECTED_JAVA_VERSION")
if [ -z "$GREP_RESULT" ]; then
echo "::error::Unexpected version"
echo "Expected version: $EXPECTED_JAVA_VERSION"
exit 1
fi
if [ "$EXPECTED_PATH" != "$JAVA_HOME" ]; then
echo "::error::Unexpected path"
echo "Actual path: $JAVA_HOME"
echo "Expected path: $EXPECTED_PATH"
exit 1
fi

@ -0,0 +1,17 @@
#!/bin/bash
if [[ "$(git status --porcelain)" != "" ]]; then
echo ----------------------------------------
echo git status
echo ----------------------------------------
git status
echo ----------------------------------------
echo git diff
echo ----------------------------------------
git diff
echo ----------------------------------------
echo Troubleshooting
echo ----------------------------------------
echo "::error::Unstaged changes detected. Locally try running: git clean -ffdx && npm ci && npm run pre-checkin"
exit 1
fi

@ -4,23 +4,26 @@ description: 'Set up a specific version of the Java JDK and add the
author: 'GitHub'
inputs:
java-version:
description: 'The Java version to make available on the path. Takes a whole
or semver Java version, or 1.x syntax (e.g. 1.8 => Java 8.x).
Early access versions can be specified in the form of e.g. 14-ea,
14.0.0-ea, or 14.0.0-ea.28'
description: 'The Java version to set up. Takes a whole or semver Java version. See examples of supported syntax in README file'
required: true
distribution:
description: 'Java distribution. See the list of supported distributions in README file'
required: true
java-package:
description: 'The package type (jre, jdk, jdk+fx)'
description: 'The package type (jdk, jre, jdk+fx, jre+fx)'
required: false
default: 'jdk'
architecture:
description: 'The architecture (x86, x64) of the package.'
description: 'The architecture of the package'
required: false
default: 'x64'
jdkFile:
description: 'Path to where the compressed JDK is located. The path could
be in your source repository or a local path on the agent.'
description: 'Path to where the compressed JDK is located'
required: false
check-latest:
description: 'Set this option if you want the action to check for the latest available version that satisfies the version spec'
required: false
default: false
server-id:
description: 'ID of the distributionManagement repository in the pom.xml
file. Default is `github`'
@ -39,6 +42,10 @@ inputs:
settings-path:
description: 'Path to where the settings.xml file will be written. Default is ~/.m2.'
required: false
overwrite-settings:
description: 'Overwrite the settings.xml file if it exists. Default is "true".'
required: false
default: true
gpg-private-key:
description: 'GPG private key to import. Default is empty string.'
required: false
@ -47,10 +54,12 @@ inputs:
$GPG_PASSPHRASE.'
required: false
outputs:
path:
description: 'Path to where the java environment has been installed (same as $JAVA_HOME)'
distribution:
description: 'Distribution of Java that has been installed'
version:
description: 'Actual version of the java environment that has been installed'
path:
description: 'Path to where the java environment has been installed (same as $JAVA_HOME)'
runs:
using: 'node12'
main: 'dist/setup/index.js'

6680
dist/cleanup/index.js vendored

File diff suppressed because it is too large Load Diff

44078
dist/setup/index.js vendored

File diff suppressed because it is too large Load Diff

BIN
dist/setup/unzip vendored

Binary file not shown.

301
docs/advanced-usage.md Normal file

@ -0,0 +1,301 @@
# Usage
- [Selecting a Java distribution](#Selecting-a-Java-distribution)
- [Adopt](#Adopt)
- [Zulu](#Zulu)
- [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)
- [Testing against different Java distributions](#Testing-against-different-Java-distributions)
- [Testing against different platforms](#Testing-against-different-platforms)
- [Publishing using Apache Maven](#Publishing-using-Apache-Maven)
- [Publishing using Gradle](#Publishing-using-Gradle)
- [Hosted Tool Cache](#Hosted-Tool-Cache)
See [action.yml](../action.yml) for more details on task inputs.
## Selecting a Java distribution
Inputs `java-version` and `distribution` are mandatory and needs to be provided. See [Supported distributions](../README.md#Supported-distributions) for a list of available options.
### Adopt
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v2-preview
with:
distribution: 'adopt'
java-version: '11'
- run: java -cp java HelloWorldApp
```
### Zulu
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v2-preview
with:
distribution: 'zulu'
java-version: '11'
java-package: jdk # optional (jdk, jre, jdk+fx or jre+fx) - defaults to jdk
- run: java -cp java HelloWorldApp
```
## Installing custom Java package type
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v2-preview
with:
distribution: '<distribution>'
java-version: '11'
java-package: jdk # optional (jdk or jre) - defaults to jdk
- run: java -cp java HelloWorldApp
```
## Installing custom Java architecture
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v2-preview
with:
distribution: '<distribution>'
java-version: '11'
architecture: x86 # optional - defaults to x64
- run: java -cp java HelloWorldApp
```
## Installing Java from local file
If your use-case requires a custom distribution or a version that is not provided by setup-java, you can download it manually and setup-java will take care of the installation and caching on the VM:
```yaml
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@v2-preview
with:
distribution: 'jdkFile'
jdkFile: ${{ runner.temp }}/java_package.tar.gz
java-version: '11.0.0'
architecture: x64
- run: java -cp java HelloWorldApp
```
## Testing against different Java distributions
**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.
```yaml
jobs:
build:
runs-on: ubuntu-20.04
strategy:
matrix:
distribution: [ 'zulu', 'adopt' ]
java: [ '8', '11', '13', '15' ]
name: Java ${{ matrix.Java }} (${{ matrix.distribution }}) sample
steps:
- uses: actions/checkout@v2
- name: Setup java
uses: actions/setup-java@v2-preview
with:
distribution: ${{ matrix.distribution }}
java-version: ${{ matrix.java }}
- run: java -cp java HelloWorldApp
```
#### Testing against different platforms
```yaml
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
java: [ '8', '11' ]
os: [ 'ubuntu-latest', 'macos-latest', 'windows-latest' ]
name: Java ${{ matrix.Java }} (${{ matrix.os }}) sample
steps:
- uses: actions/checkout@v2
- name: Setup java
uses: actions/setup-java@v2-preview
with:
distribution: 'adopt'
java-version: ${{ matrix.java }}
- run: java -cp java HelloWorldApp
```
## Publishing using Apache Maven
### Yaml example:
```yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v2-preview
with:
distribution: '<distribution>'
java-version: '11'
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Publish to GitHub Packages Apache Maven
run: mvn deploy
env:
GITHUB_TOKEN: ${{ github.token }} # GITHUB_TOKEN is the default env for the password
- name: Set up Apache Maven Central
uses: actions/setup-java@v2-preview
with: # running setup-java again overwrites the settings.xml
distribution: 'adopt'
java-version: '11'
server-id: maven # Value of the distributionManagement/repository/id field of the pom.xml
server-username: MAVEN_USERNAME # env variable for username in deploy
server-password: MAVEN_CENTRAL_TOKEN # env variable for token in deploy
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import
gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase
- name: Publish to Apache Maven Central
run: mvn deploy
env:
MAVEN_USERNAME: maven_username123
MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
```
The two `settings.xml` files created from the above example look like the following.
`settings.xml` file created for the first deploy to GitHub Packages
```xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>github</id>
<username>${env.GITHUB_ACTOR}</username>
<password>${env.GITHUB_TOKEN}</password>
</server>
<server>
<id>gpg.passphrase</id>
<passphrase>${env.GPG_PASSPHRASE}</passphrase>
</server>
</servers>
</settings>
```
`settings.xml` file created for the second deploy to Apache Maven Central
```xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>maven</id>
<username>${env.MAVEN_USERNAME}</username>
<password>${env.MAVEN_CENTRAL_TOKEN}</password>
</server>
<server>
<id>gpg.passphrase</id>
<passphrase>${env.MAVEN_GPG_PASSPHRASE}</passphrase>
</server>
</servers>
</settings>
```
***NOTE***: The `settings.xml` file is created in the Actions $HOME/.m2 directory. If you have an existing `settings.xml` file at that location, it will be overwritten. See below for using the `settings-path` to change your `settings.xml` file location.
If you don't want to overwrite the `settings.xml` file, you can set `overwrite-settings: false`
### Extra setup for pom.xml:
The Maven GPG Plugin configuration in the pom.xml file should contain the following structure to avoid possible issues like `Inappropriate ioctl for device` or `gpg: signing failed: No such file or directory`:
```xml
<configuration>
<!-- Prevent gpg from using pinentry programs -->
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
```
GPG 2.1 requires `--pinentry-mode` to be set to `loopback` in order to pick up the `gpg.passphrase` value defined in Maven `settings.xml`.
### GPG
If `gpg-private-key` input is provided, the private key will be written to a file in the runner's temp directory, the private key file will be imported into the GPG keychain, and then the file will be promptly removed before proceeding with the rest of the setup process. A cleanup step will remove the imported private key from the GPG keychain after the job completes regardless of the job status. This ensures that the private key is no longer accessible on self-hosted runners and cannot "leak" between jobs (hosted runners are always clean instances).
**GPG key should be exported by: `gpg --armor --export-secret-keys YOUR_ID`**
See the help docs on [Publishing a Package](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-apache-maven-for-use-with-github-packages#publishing-a-package) for more information on the `pom.xml` file.
## Publishing using Gradle
```yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v2-preview
with:
distribution: '<distribution>'
java-version: '11'
- name: Build with Gradle
run: gradle build
- name: Publish to GitHub Packages
run: gradle publish
env:
USERNAME: ${{ github.actor }}
PASSWORD: ${{ secrets.GITHUB_TOKEN }}
```
***NOTE: The `USERNAME` and `PASSWORD` need to correspond to the credentials environment variables used in the publishing section of your `build.gradle`.***
See the help docs on [Publishing a Package with Gradle](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-gradle-for-use-with-github-packages#example-using-gradle-groovy-for-a-single-package-in-a-repository) for more information on the `build.gradle` configuration file.
## Apache Maven with a settings path
When using an Actions self-hosted runner with multiple shared runners the default `$HOME` directory can be shared by a number runners at the same time which could overwrite existing settings file. Setting the `settings-path` variable allows you to choose a unique location for your settings file.
```yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11 for Shared Runner
uses: actions/setup-java@v2-preview
with:
distribution: '<distribution>'
java-version: '11'
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
settings-path: ${{ github.workspace }} # location for the settings.xml file
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Publish to GitHub Packages Apache Maven
run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml
env:
GITHUB_TOKEN: ${{ github.token }}
```
## Hosted Tool Cache
GitHub Hosted Runners have a tool cache that comes with some Java versions pre-installed. This tool cache helps speed up runs and tool setup by not requiring any new downloads. There is an environment variable called `RUNNER_TOOL_CACHE` on each runner that describes the location of this tools cache and this is where you can find the pre-installed versions of Java. `setup-java` works by taking a specific version of Java in this tool cache and adding it to PATH if the version, architecture and distribution match.
Currently, LTS versions of Adopt OpenJDK (`adopt`) are cached on the GitHub Hosted Runners.
The tools cache gets updated on a weekly basis. For information regarding locally cached versions of Java on GitHub hosted runners, check out [GitHub Actions Virtual Environments](https://github.com/actions/virtual-environments).

35
docs/switching-to-v2.md Normal file

@ -0,0 +1,35 @@
# Switching to V2
## Java distribution
The major breaking change in V2 is the new mandatory `distribution` input. This field should be specified with one of supported distributions. See [Supported distributions](../README.md#Supported-distributions) for a list of available options.
Use the `zulu` keyword if you would like to continue using the same distribution as in V1.
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v2-preview
with:
distribution: 'zulu'
java-version: '11'
java-package: jdk # optional (jdk or jre) - defaults to jdk
- run: java -cp java HelloWorldApp
```
**General recommendation** — configure CI with the same distribution that is used on your local dev machine.
## Installing custom Java distribution from local file
Since the `distribution` input is required in V2, you should specify it using `jdkFile` to continue installing Java from a local file on the runner
```yaml
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@v2-preview
with:
distribution: 'jdkFile'
jdkFile: ${{ runner.temp }}/java_package.tar.gz
java-version: '11.0.0'
architecture: x64
```
## Dropping legacy Java version syntax 1.x
V1 supported legacy Java syntax such as `1.8` (same as `8`) and `1.8.0.212` (same as `8.0.212`).
V2 dropped support for legacy syntax so workflows should be updated accordingly.

4232
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,13 +1,13 @@
{
"name": "setup-java",
"version": "1.0.0",
"version": "2.0.0",
"private": true,
"description": "setup java action",
"main": "dist/setup/index.js",
"scripts": {
"build": "ncc build -o dist/setup src/setup-java.ts && ncc build -o dist/cleanup src/cleanup-java.ts",
"format": "prettier --write **/*.ts",
"format-check": "prettier --check **/*.ts",
"format": "prettier --write \"{,!(node_modules)/**/}*.ts\"",
"format-check": "prettier --check \"{,!(node_modules)/**/}*.ts\"",
"prerelease": "npm run-script build",
"release": "git add -f dist/setup/index.js dist/cleanup/index.js",
"test": "jest"
@ -18,30 +18,30 @@
},
"keywords": [
"actions",
"node",
"java",
"setup"
],
"author": "GitHub",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.0.0",
"@actions/exec": "^1.0.0",
"@actions/http-client": "^1.0.8",
"@actions/io": "^1.0.0",
"@actions/tool-cache": "^1.3.1",
"semver": "^6.1.1",
"xmlbuilder2": "^2.1.2"
"@actions/core": "^1.2.6",
"@actions/exec": "^1.0.4",
"@actions/http-client": "^1.0.9",
"@actions/io": "^1.0.2",
"@actions/tool-cache": "^1.6.1",
"semver": "^7.3.4",
"xmlbuilder2": "^2.4.0"
},
"devDependencies": {
"@types/jest": "^24.0.13",
"@types/node": "^12.0.4",
"@types/semver": "^6.0.0",
"@types/jest": "^26.0.20",
"@types/node": "^12.19.13",
"@types/semver": "^7.3.4",
"@zeit/ncc": "^0.20.5",
"jest": "^24.8.0",
"jest-circus": "^24.7.1",
"jest": "^26.6.3",
"jest-circus": "^26.6.3",
"prettier": "^1.19.1",
"ts-jest": "^24.0.2",
"typescript": "^3.5.1"
"ts-jest": "^26.5.3",
"typescript": "^4.2.3"
},
"husky": {
"skipCI": true,

@ -1,38 +1,67 @@
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import * as core from '@actions/core';
import * as io from '@actions/io';
import * as fs from 'fs';
import * as os from 'os';
import { create as xmlCreate } from 'xmlbuilder2';
import * as constants from './constants';
import * as gpg from './gpg';
import { getBooleanInput } from './util';
export const M2_DIR = '.m2';
export const SETTINGS_FILE = 'settings.xml';
export async function configAuthentication(
export async function configureAuthentication() {
const id = core.getInput(constants.INPUT_SERVER_ID);
const username = core.getInput(constants.INPUT_SERVER_USERNAME);
const password = core.getInput(constants.INPUT_SERVER_PASSWORD);
const settingsDirectory =
core.getInput(constants.INPUT_SETTINGS_PATH) || path.join(os.homedir(), M2_DIR);
const overwriteSettings = getBooleanInput(constants.INPUT_OVERWRITE_SETTINGS, true);
const gpgPrivateKey =
core.getInput(constants.INPUT_GPG_PRIVATE_KEY) || constants.INPUT_DEFAULT_GPG_PRIVATE_KEY;
const gpgPassphrase =
core.getInput(constants.INPUT_GPG_PASSPHRASE) ||
(gpgPrivateKey ? constants.INPUT_DEFAULT_GPG_PASSPHRASE : undefined);
if (gpgPrivateKey) {
core.setSecret(gpgPrivateKey);
}
await createAuthenticationSettings(
id,
username,
password,
settingsDirectory,
overwriteSettings,
gpgPassphrase
);
if (gpgPrivateKey) {
core.info('Importing private gpg key');
const keyFingerprint = (await gpg.importKey(gpgPrivateKey)) || '';
core.saveState(constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT, keyFingerprint);
}
}
export async function createAuthenticationSettings(
id: string,
username: string,
password: string,
settingsDirectory: string,
overwriteSettings: boolean,
gpgPassphrase: string | undefined = undefined
) {
console.log(
`creating ${SETTINGS_FILE} with server-id: ${id};`,
'environment variables:',
`username=\$${username},`,
`password=\$${password},`,
`and gpg-passphrase=${gpgPassphrase ? '$' + gpgPassphrase : null}`
);
core.info(`Creating ${SETTINGS_FILE} with server-id: ${id}`);
// when an alternate m2 location is specified use only that location (no .m2 directory)
// otherwise use the home/.m2/ path
const settingsDirectory: string = path.join(
core.getInput(constants.INPUT_SETTINGS_PATH) || os.homedir(),
core.getInput(constants.INPUT_SETTINGS_PATH) ? '' : M2_DIR
);
await io.mkdirP(settingsDirectory);
core.debug(`created directory ${settingsDirectory}`);
await write(
settingsDirectory,
generate(id, username, password, gpgPassphrase)
generate(id, username, password, gpgPassphrase),
overwriteSettings
);
}
@ -41,7 +70,7 @@ export function generate(
id: string,
username: string,
password: string,
gpgPassphrase: string | undefined = undefined
gpgPassphrase?: string | undefined
) {
const xmlObj: { [key: string]: any } = {
settings: {
@ -69,15 +98,25 @@ export function generate(
xmlObj.settings.servers.server.push(gpgServer);
}
return xmlCreate(xmlObj).end({headless: true, prettyPrint: true, width: 80});
return xmlCreate(xmlObj).end({
headless: true,
prettyPrint: true,
width: 80
});
}
async function write(directory: string, settings: string) {
async function write(directory: string, settings: string, overwriteSettings: boolean) {
const location = path.join(directory, SETTINGS_FILE);
if (fs.existsSync(location)) {
console.warn(`overwriting existing file ${location}`);
const settingsExists = fs.existsSync(location);
if (settingsExists && overwriteSettings) {
core.info(`Overwriting existing file ${location}`);
} else if (!settingsExists) {
core.info(`Writing to ${location}`);
} else {
console.log(`writing ${location}`);
core.info(
`Skipping generation ${location} because file already exists and overwriting is not required`
);
return;
}
return fs.writeFileSync(location, settings, {

@ -4,14 +4,12 @@ import * as constants from './constants';
async function run() {
if (core.getInput(constants.INPUT_GPG_PRIVATE_KEY, { required: false })) {
core.info('removing private key from keychain');
core.info('Removing private key from keychain');
try {
const keyFingerprint = core.getState(
constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT
);
const keyFingerprint = core.getState(constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT);
await gpg.deleteKey(keyFingerprint);
} catch (error) {
core.setFailed('failed to remove private key');
core.setFailed('Failed to remove private key');
}
}
}

@ -1,12 +1,15 @@
export const INPUT_VERSION = 'version';
export const MACOS_JAVA_CONTENT_POSTFIX = 'Contents/Home';
export const INPUT_JAVA_VERSION = 'java-version';
export const INPUT_ARCHITECTURE = 'architecture';
export const INPUT_JAVA_PACKAGE = 'java-package';
export const INPUT_DISTRIBUTION = 'distribution';
export const INPUT_JDK_FILE = 'jdkFile';
export const INPUT_CHECK_LATEST = 'check-latest';
export const INPUT_SERVER_ID = 'server-id';
export const INPUT_SERVER_USERNAME = 'server-username';
export const INPUT_SERVER_PASSWORD = 'server-password';
export const INPUT_SETTINGS_PATH = 'settings-path';
export const INPUT_OVERWRITE_SETTINGS = 'overwrite-settings';
export const INPUT_GPG_PRIVATE_KEY = 'gpg-private-key';
export const INPUT_GPG_PASSPHRASE = 'gpg-passphrase';

@ -0,0 +1,141 @@
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 { IAdoptAvailableVersions } from './models';
import { JavaInstallerOptions, JavaDownloadRelease, JavaInstallerResults } from '../base-models';
import { MACOS_JAVA_CONTENT_POSTFIX } from '../../constants';
import { extractJdkFile, getDownloadArchiveExtension, isVersionSatisfies } from '../../util';
export class AdoptDistribution extends JavaBase {
constructor(installerOptions: JavaInstallerOptions) {
super('Adopt', installerOptions);
}
protected async findPackageForDownload(version: string): Promise<JavaDownloadRelease> {
const availableVersionsRaw = await this.getAvailableVersions();
const availableVersionsWithBinaries = availableVersionsRaw
.filter(item => item.binaries.length > 0)
.map(item => {
return {
version: item.version_data.semver,
url: item.binaries[0].package.link
} as JavaDownloadRelease;
});
const satisfiedVersions = availableVersionsWithBinaries
.filter(item => isVersionSatisfies(version, item.version))
.sort((a, b) => {
return -semver.compareBuild(a.version, b.version);
});
const resolvedFullVersion = satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) {
const availableOptions = availableVersionsWithBinaries.map(item => item.version).join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(
`Could not find satisfied version for SemVer '${version}'. ${availableOptionsMessage}`
);
}
return resolvedFullVersion;
}
protected async downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults> {
let javaPath: string;
let extractedJavaPath: string;
core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
);
const javaArchivePath = await tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`);
let extension = getDownloadArchiveExtension();
extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
const archiveName = fs.readdirSync(extractedJavaPath)[0];
const archivePath = path.join(extractedJavaPath, archiveName);
const version = this.getToolcacheVersionName(javaRelease.version);
javaPath = await tc.cacheDir(archivePath, this.toolcacheFolderName, version, this.architecture);
return { version: javaRelease.version, path: javaPath };
}
private async getAvailableVersions(): Promise<IAdoptAvailableVersions[]> {
const platform = this.getPlatformOption();
const arch = this.architecture;
const imageType = this.packageType;
const versionRange = encodeURI('[1.0,100.0]'); // retrieve all available versions
const releaseType = this.stable ? 'ga' : 'ea';
console.time('adopt-retrieve-available-versions');
const baseRequestArguments = [
`project=jdk`,
'vendor=adoptopenjdk',
`heap_size=normal`,
`jvm_impl=hotspot`,
'sort_method=DEFAULT',
'sort_order=DESC',
`os=${platform}`,
`architecture=${arch}`,
`image_type=${imageType}`,
`release_type=${releaseType}`
].join('&');
// need to iterate through all pages to retrieve the list of all versions
// Adopt API doesn't provide way to retrieve the count of pages to iterate so infinity loop
let page_index = 0;
const availableVersions: IAdoptAvailableVersions[] = [];
while (true) {
const requestArguments = `${baseRequestArguments}&page_size=20&page=${page_index}`;
const availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`;
if (core.isDebug() && page_index === 0) {
// url is identical except page_index so print it once for debug
core.debug(`Gathering available versions from '${availableVersionsUrl}'`);
}
const paginationPage = (
await this.http.getJson<IAdoptAvailableVersions[]>(availableVersionsUrl)
).result;
if (paginationPage === null || paginationPage.length === 0) {
// break infinity loop because we have reached end of pagination
break;
}
availableVersions.push(...paginationPage);
page_index++;
}
if (core.isDebug()) {
core.startGroup('Print information about available versions');
console.timeEnd('adopt-retrieve-available-versions');
console.log(`Available versions: [${availableVersions.length}]`);
console.log(availableVersions.map(item => item.version_data.semver).join(', '));
core.endGroup();
}
return availableVersions;
}
private getPlatformOption(): string {
// Adopt has own platform names so need to map them
switch (process.platform) {
case 'darwin':
return 'mac';
case 'win32':
return 'windows';
default:
return process.platform;
}
}
}

@ -0,0 +1,38 @@
// Models from https://api.adoptopenjdk.net/swagger-ui/#/Assets/get_v3_assets_version__version
export interface IAdoptAvailableVersions {
binaries: [
{
architecture: string;
heap_size: string;
image_type: string;
jvm_impl: string;
os: string;
package: {
checksum: string;
checksum_link: string;
download_count: number;
link: string;
metadata_link: string;
name: string;
size: string;
};
project: string;
scm_ref: string;
updated_at: string;
}
];
id: string;
release_link: string;
release_name: string;
release_type: string;
vendor: string;
version_data: {
build: number;
major: number;
minor: number;
openjdk_version: string;
security: string;
semver: string;
};
}

@ -0,0 +1,151 @@
import * as tc from '@actions/tool-cache';
import * as core from '@actions/core';
import * as fs from 'fs';
import semver from 'semver';
import path from 'path';
import * as httpm from '@actions/http-client';
import { getToolcachePath, getVersionFromToolcachePath, isVersionSatisfies } from '../util';
import { JavaDownloadRelease, JavaInstallerOptions, JavaInstallerResults } from './base-models';
import { MACOS_JAVA_CONTENT_POSTFIX } from '../constants';
export abstract class JavaBase {
protected http: httpm.HttpClient;
protected version: string;
protected architecture: string;
protected packageType: string;
protected stable: boolean;
protected checkLatest: boolean;
constructor(protected distribution: string, installerOptions: JavaInstallerOptions) {
this.http = new httpm.HttpClient('actions/setup-java', undefined, {
allowRetries: true,
maxRetries: 3
});
({ version: this.version, stable: this.stable } = this.normalizeVersion(
installerOptions.version
));
this.architecture = installerOptions.architecture;
this.packageType = installerOptions.packageType;
this.checkLatest = installerOptions.checkLatest;
}
protected abstract downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults>;
protected abstract findPackageForDownload(range: string): Promise<JavaDownloadRelease>;
public async setupJava(): Promise<JavaInstallerResults> {
let foundJava = this.findInToolcache();
if (foundJava && !this.checkLatest) {
core.info(`Resolved Java ${foundJava.version} from tool-cache`);
} else {
core.info('Trying to resolve the latest version from remote');
const javaRelease = await this.findPackageForDownload(this.version);
core.info(`Resolved latest version as ${javaRelease.version}`);
if (foundJava?.version === javaRelease.version) {
core.info(`Resolved Java ${foundJava.version} from tool-cache`);
} else {
core.info('Trying to download...');
foundJava = await this.downloadTool(javaRelease);
core.info(`Java ${foundJava.version} was downloaded`);
}
}
// JDK folder may contain postfix "Contents/Home" on macOS
const macOSPostfixPath = path.join(foundJava.path, MACOS_JAVA_CONTENT_POSTFIX);
if (process.platform === 'darwin' && fs.existsSync(macOSPostfixPath)) {
foundJava.path = macOSPostfixPath;
}
core.info(`Setting Java ${foundJava.version} as the default`);
this.setJavaDefault(foundJava.version, foundJava.path);
return foundJava;
}
protected get toolcacheFolderName(): string {
return `Java_${this.distribution}_${this.packageType}`;
}
protected getToolcacheVersionName(version: string): string {
if (!this.stable) {
if (version.includes('+')) {
return version.replace('+', '-ea.');
} else {
return `${version}-ea`;
}
}
// Kotlin and some Java dependencies don't work properly when Java path contains "+" sign
// so replace "/hostedtoolcache/Java/11.0.3+4/x64" to "/hostedtoolcache/Java/11.0.3-4/x64" when saves to cache
// related issue: https://github.com/actions/virtual-environments/issues/3014
return version.replace('+', '-');
}
protected findInToolcache(): JavaInstallerResults | null {
// we can't use tc.find directly because firstly, we need to filter versions by stability flag
// if *-ea is provided, take only ea versions from toolcache, otherwise - only stable versions
const availableVersions = tc
.findAllVersions(this.toolcacheFolderName, this.architecture)
.map(item => {
return {
version: item
.replace('-ea.', '+')
.replace(/-ea$/, '')
// Kotlin and some Java dependencies don't work properly when Java path contains "+" sign
// so replace "/hostedtoolcache/Java/11.0.3-4/x64" to "/hostedtoolcache/Java/11.0.3+4/x64" when retrieves to cache
// related issue: https://github.com/actions/virtual-environments/issues/3014
.replace('-', '+'),
path: getToolcachePath(this.toolcacheFolderName, item, this.architecture) || '',
stable: !item.includes('-ea')
};
})
.filter(item => item.stable === this.stable);
const satisfiedVersions = availableVersions
.filter(item => isVersionSatisfies(this.version, item.version))
.filter(item => item.path)
.sort((a, b) => {
return -semver.compareBuild(a.version, b.version);
});
if (!satisfiedVersions || satisfiedVersions.length === 0) {
return null;
}
return {
version: satisfiedVersions[0].version,
path: satisfiedVersions[0].path
};
}
protected normalizeVersion(version: string) {
let stable = true;
if (version.endsWith('-ea')) {
version = version.replace(/-ea$/, '');
stable = false;
} else if (version.includes('-ea.')) {
// transform '11.0.3-ea.2' -> '11.0.3+2'
version = version.replace('-ea.', '+');
stable = false;
}
if (!semver.validRange(version)) {
throw new Error(
`The string '${version}' is not valid SemVer notation for a Java version. Please check README file for code snippets and more detailed information`
);
}
return {
version,
stable
};
}
protected setJavaDefault(version: string, toolPath: string) {
core.exportVariable('JAVA_HOME', toolPath);
core.addPath(path.join(toolPath, 'bin'));
core.setOutput('distribution', this.distribution);
core.setOutput('path', toolPath);
core.setOutput('version', version);
}
}

@ -0,0 +1,16 @@
export interface JavaInstallerOptions {
version: string;
architecture: string;
packageType: string;
checkLatest: boolean;
}
export interface JavaInstallerResults {
version: string;
path: string;
}
export interface JavaDownloadRelease {
version: string;
url: string;
}

@ -0,0 +1,28 @@
import { AdoptDistribution } from './adopt/installer';
import { JavaBase } from './base-installer';
import { JavaInstallerOptions } from './base-models';
import { LocalDistribution } from './local/installer';
import { ZuluDistribution } from './zulu/installer';
enum JavaDistribution {
Adopt = 'adopt',
Zulu = 'zulu',
JdkFile = 'jdkfile'
}
export function getJavaDistribution(
distributionName: string,
installerOptions: JavaInstallerOptions,
jdkFile?: string
): JavaBase | null {
switch (distributionName) {
case JavaDistribution.JdkFile:
return new LocalDistribution(installerOptions, jdkFile);
case JavaDistribution.Adopt:
return new AdoptDistribution(installerOptions);
case JavaDistribution.Zulu:
return new ZuluDistribution(installerOptions);
default:
return null;
}
}

@ -0,0 +1,76 @@
import * as tc from '@actions/tool-cache';
import * as core from '@actions/core';
import fs from 'fs';
import path from 'path';
import semver from 'semver';
import { JavaBase } from '../base-installer';
import { JavaInstallerOptions, JavaDownloadRelease, JavaInstallerResults } from '../base-models';
import { extractJdkFile } from '../../util';
import { MACOS_JAVA_CONTENT_POSTFIX } from '../../constants';
export class LocalDistribution extends JavaBase {
constructor(installerOptions: JavaInstallerOptions, private jdkFile?: string) {
super('jdkfile', installerOptions);
}
public async setupJava(): Promise<JavaInstallerResults> {
let foundJava = this.findInToolcache();
if (foundJava) {
core.info(`Resolved Java ${foundJava.version} from tool-cache`);
} else {
core.info(`Java ${this.version} was not found in tool-cache. Trying to unpack JDK file...`);
if (!this.jdkFile) {
throw new Error("'jdkFile' is not specified");
}
const jdkFilePath = path.resolve(this.jdkFile);
const stats = fs.statSync(jdkFilePath);
if (!stats.isFile()) {
throw new Error(`JDK file was not found in path '${jdkFilePath}'`);
}
core.info(`Extracting Java from '${jdkFilePath}'`);
const extractedJavaPath = await extractJdkFile(jdkFilePath);
const archiveName = fs.readdirSync(extractedJavaPath)[0];
const archivePath = path.join(extractedJavaPath, archiveName);
const javaVersion = this.version;
let javaPath = await tc.cacheDir(
archivePath,
this.toolcacheFolderName,
this.getToolcacheVersionName(javaVersion),
this.architecture
);
// for different Java distributions, postfix can exist or not so need to check both cases
if (
process.platform === 'darwin' &&
fs.existsSync(path.join(javaPath, MACOS_JAVA_CONTENT_POSTFIX))
) {
javaPath = path.join(javaPath, MACOS_JAVA_CONTENT_POSTFIX);
}
foundJava = {
version: javaVersion,
path: javaPath
};
}
core.info(`Setting Java ${foundJava.version} as default`);
this.setJavaDefault(foundJava.version, foundJava.path);
return foundJava;
}
protected async findPackageForDownload(version: string): Promise<JavaDownloadRelease> {
throw new Error('This method should not be implemented in local file provider');
}
protected async downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults> {
throw new Error('This method should not be implemented in local file provider');
}
}

@ -0,0 +1,163 @@
import * as core from '@actions/core';
import * as tc from '@actions/tool-cache';
import path from 'path';
import fs from 'fs';
import semver from 'semver';
import { JavaBase } from '../base-installer';
import { IZuluVersions } from './models';
import { extractJdkFile, getDownloadArchiveExtension, isVersionSatisfies } from '../../util';
import { JavaDownloadRelease, JavaInstallerOptions, JavaInstallerResults } from '../base-models';
export class ZuluDistribution extends JavaBase {
constructor(installerOptions: JavaInstallerOptions) {
super('Zulu', installerOptions);
}
protected async findPackageForDownload(version: string): Promise<JavaDownloadRelease> {
const availableVersionsRaw = await this.getAvailableVersions();
const availableVersions = availableVersionsRaw.map(item => {
return {
version: this.convertVersionToSemver(item.jdk_version),
url: item.url,
zuluVersion: this.convertVersionToSemver(item.zulu_version)
};
});
const satisfiedVersions = availableVersions
.filter(item => isVersionSatisfies(version, item.version))
.sort((a, b) => {
// Azul provides two versions: jdk_version and azul_version
// we should sort by both fields by descending
return (
-semver.compareBuild(a.version, b.version) ||
-semver.compareBuild(a.zuluVersion, b.zuluVersion)
);
})
.map(item => {
return {
version: item.version,
url: item.url
} as JavaDownloadRelease;
});
const resolvedFullVersion = satisfiedVersions.length > 0 ? satisfiedVersions[0] : null;
if (!resolvedFullVersion) {
const availableOptions = availableVersions.map(item => item.version).join(', ');
const availableOptionsMessage = availableOptions
? `\nAvailable versions: ${availableOptions}`
: '';
throw new Error(
`Could not find satisfied version for semver ${version}. ${availableOptionsMessage}`
);
}
return resolvedFullVersion;
}
protected async downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults> {
let extractedJavaPath: string;
core.info(
`Downloading Java ${javaRelease.version} (${this.distribution}) from ${javaRelease.url} ...`
);
const javaArchivePath = await tc.downloadTool(javaRelease.url);
core.info(`Extracting Java archive...`);
let extension = getDownloadArchiveExtension();
extractedJavaPath = await extractJdkFile(javaArchivePath, extension);
const archiveName = fs.readdirSync(extractedJavaPath)[0];
const archivePath = path.join(extractedJavaPath, archiveName);
const javaPath = await tc.cacheDir(
archivePath,
this.toolcacheFolderName,
this.getToolcacheVersionName(javaRelease.version),
this.architecture
);
return { version: javaRelease.version, path: javaPath };
}
private async getAvailableVersions(): Promise<IZuluVersions[]> {
const { arch, hw_bitness, abi } = this.getArchitectureOptions();
const [bundleType, features] = this.packageType.split('+');
const platform = this.getPlatformOption();
const extension = getDownloadArchiveExtension();
const javafx = features?.includes('fx') ?? false;
const releaseStatus = this.stable ? 'ga' : 'ea';
console.time('azul-retrieve-available-versions');
const requestArguments = [
`os=${platform}`,
`ext=${extension}`,
`bundle_type=${bundleType}`,
`javafx=${javafx}`,
`arch=${arch}`,
`hw_bitness=${hw_bitness}`,
`release_status=${releaseStatus}`,
abi ? `abi=${abi}` : null,
features ? `features=${features}` : null
]
.filter(Boolean)
.join('&');
const availableVersionsUrl = `https://api.azul.com/zulu/download/community/v1.0/bundles/?${requestArguments}`;
if (core.isDebug()) {
core.debug(`Gathering available versions from '${availableVersionsUrl}'`);
}
const availableVersions =
(await this.http.getJson<Array<IZuluVersions>>(availableVersionsUrl)).result ?? [];
if (core.isDebug()) {
core.startGroup('Print information about available versions');
console.timeEnd('azul-retrieve-available-versions');
console.log(`Available versions: [${availableVersions.length}]`);
console.log(availableVersions.map(item => item.jdk_version.join('.')).join(', '));
core.endGroup();
}
return availableVersions;
}
private getArchitectureOptions(): {
arch: string;
hw_bitness: string;
abi: string;
} {
if (this.architecture == 'x64') {
return { arch: 'x86', hw_bitness: '64', abi: '' };
} else if (this.architecture == 'x86') {
return { arch: 'x86', hw_bitness: '32', abi: '' };
} else {
return { arch: this.architecture, hw_bitness: '', abi: '' };
}
}
private getPlatformOption(): string {
// Azul has own platform names so need to map them
switch (process.platform) {
case 'darwin':
return 'macos';
case 'win32':
return 'windows';
default:
return process.platform;
}
}
// Azul API returns jdk_version as array of digits like [11, 0, 2, 1]
private convertVersionToSemver(version_array: number[]) {
const mainVersion = version_array.slice(0, 3).join('.');
if (version_array.length > 3) {
// intentionally ignore more than 4 numbers because it is invalid semver
return `${mainVersion}+${version_array[3]}`;
}
return mainVersion;
}
}

@ -0,0 +1,9 @@
// Models from https://app.swaggerhub.com/apis-docs/azul/zulu-download-community/1.0
export interface IZuluVersions {
id: number;
name: string;
url: string;
jdk_version: Array<number>;
zulu_version: Array<number>;
}

@ -28,13 +28,7 @@ export async function importKey(privateKey: string) {
await exec.exec(
'gpg',
[
'--batch',
'--import-options',
'import-show',
'--import',
PRIVATE_KEY_FILE
],
['--batch', '--import-options', 'import-show', '--import', PRIVATE_KEY_FILE],
options
);
@ -45,14 +39,8 @@ export async function importKey(privateKey: string) {
}
export async function deleteKey(keyFingerprint: string) {
await exec.exec(
'gpg',
['--batch', '--yes', '--delete-secret-keys', keyFingerprint],
{silent: true}
);
await exec.exec(
'gpg',
['--batch', '--yes', '--delete-keys', keyFingerprint],
{silent: true}
);
await exec.exec('gpg', ['--batch', '--yes', '--delete-secret-keys', keyFingerprint], {
silent: true
});
await exec.exec('gpg', ['--batch', '--yes', '--delete-keys', keyFingerprint], { silent: true });
}

@ -1,298 +0,0 @@
import * as core from '@actions/core';
import * as io from '@actions/io';
import * as exec from '@actions/exec';
import * as httpm from '@actions/http-client';
import * as tc from '@actions/tool-cache';
import * as fs from 'fs';
import * as path from 'path';
import * as semver from 'semver';
import * as util from './util';
const tempDirectory = util.getTempDir();
const IS_WINDOWS = util.isWindows();
export async function getJava(
version: string,
arch: string,
jdkFile: string,
javaPackage: string
): Promise<void> {
let toolPath = tc.find(javaPackage, version);
if (toolPath) {
core.debug(`Tool found in cache ${toolPath}`);
} else {
let compressedFileExtension = '';
if (!jdkFile) {
core.debug('Downloading JDK from Azul');
const http = new httpm.HttpClient('setup-java', undefined, {
allowRetries: true,
maxRetries: 3
});
const url = 'https://static.azul.com/zulu/bin/';
const response = await http.get(url);
const statusCode = response.message.statusCode || 0;
if (statusCode < 200 || statusCode > 299) {
let body = '';
try {
body = await response.readBody();
} catch (err) {
core.debug(`Unable to read body: ${err.message}`);
}
const message = `Unexpected HTTP status code '${response.message.statusCode}' when retrieving versions from '${url}'. ${body}`.trim();
throw new Error(message);
}
const contents = await response.readBody();
const refs = contents.match(/<a href.*\">/gi) || [];
const downloadInfo = getDownloadInfo(refs, version, arch, javaPackage);
jdkFile = await tc.downloadTool(downloadInfo.url);
version = downloadInfo.version;
compressedFileExtension = IS_WINDOWS ? '.zip' : '.tar.gz';
} else {
core.debug('Retrieving Jdk from local path');
}
compressedFileExtension = compressedFileExtension || getFileEnding(jdkFile);
let tempDir: string = path.join(
tempDirectory,
'temp_' + Math.floor(Math.random() * 2000000000)
);
const jdkDir = await unzipJavaDownload(
jdkFile,
compressedFileExtension,
tempDir
);
core.debug(`jdk extracted to ${jdkDir}`);
toolPath = await tc.cacheDir(
jdkDir,
javaPackage,
getCacheVersionString(version),
arch
);
}
let extendedJavaHome = 'JAVA_HOME_' + version + '_' + arch;
core.exportVariable(extendedJavaHome, toolPath); //TODO: remove for v2
// For portability reasons environment variables should only consist of
// uppercase letters, digits, and the underscore. Therefore we convert
// the extendedJavaHome variable to upper case and replace '.' symbols and
// any other non-alphanumeric characters with an underscore.
extendedJavaHome = extendedJavaHome.toUpperCase().replace(/[^0-9A-Z_]/g, '_');
core.exportVariable('JAVA_HOME', toolPath);
core.exportVariable(extendedJavaHome, toolPath);
core.addPath(path.join(toolPath, 'bin'));
core.setOutput('path', toolPath);
core.setOutput('version', version);
}
function getCacheVersionString(version: string) {
const versionArray = version.split('.');
const major = versionArray[0];
const minor = versionArray.length > 1 ? versionArray[1] : '0';
const patch = versionArray.length > 2 ? versionArray[2] : '0';
return `${major}.${minor}.${patch}`;
}
function getFileEnding(file: string): string {
let fileEnding = '';
if (file.endsWith('.tar')) {
fileEnding = '.tar';
} else if (file.endsWith('.tar.gz')) {
fileEnding = '.tar.gz';
} else if (file.endsWith('.zip')) {
fileEnding = '.zip';
} else if (file.endsWith('.7z')) {
fileEnding = '.7z';
} else {
throw new Error(`${file} has an unsupported file extension`);
}
return fileEnding;
}
async function extractFiles(
file: string,
fileEnding: string,
destinationFolder: string
): Promise<void> {
const stats = fs.statSync(file);
if (!stats) {
throw new Error(`Failed to extract ${file} - it doesn't exist`);
} else if (stats.isDirectory()) {
throw new Error(`Failed to extract ${file} - it is a directory`);
}
if ('.tar' === fileEnding || '.tar.gz' === fileEnding) {
await tc.extractTar(file, destinationFolder);
} else if ('.zip' === fileEnding) {
await tc.extractZip(file, destinationFolder);
} else {
// fall through and use sevenZip
await tc.extract7z(file, destinationFolder);
}
}
// This method recursively finds all .pack files under fsPath and unpacks them with the unpack200 tool
async function unpackJars(fsPath: string, javaBinPath: string) {
if (fs.existsSync(fsPath)) {
if (fs.lstatSync(fsPath).isDirectory()) {
for (const file in fs.readdirSync(fsPath)) {
const curPath = path.join(fsPath, file);
await unpackJars(curPath, javaBinPath);
}
} else if (path.extname(fsPath).toLowerCase() === '.pack') {
// Unpack the pack file synchonously
const p = path.parse(fsPath);
const toolName = IS_WINDOWS ? 'unpack200.exe' : 'unpack200';
const args = IS_WINDOWS ? '-r -v -l ""' : '';
const name = path.join(p.dir, p.name);
await exec.exec(`"${path.join(javaBinPath, toolName)}"`, [
`${args} "${name}.pack" "${name}.jar"`
]);
}
}
}
async function unzipJavaDownload(
repoRoot: string,
fileEnding: string,
destinationFolder: string,
extension?: string
): Promise<string> {
// Create the destination folder if it doesn't exist
await io.mkdirP(destinationFolder);
const jdkFile = path.normalize(repoRoot);
const stats = fs.statSync(jdkFile);
if (stats.isFile()) {
await extractFiles(jdkFile, fileEnding, destinationFolder);
const jdkDirectory = path.join(
destinationFolder,
fs.readdirSync(destinationFolder)[0]
);
await unpackJars(jdkDirectory, path.join(jdkDirectory, 'bin'));
return jdkDirectory;
} else {
throw new Error(`Jdk argument ${jdkFile} is not a file`);
}
}
function getDownloadInfo(
refs: string[],
version: string,
arch: string,
javaPackage: string
): {version: string; url: string} {
version = normalizeVersion(version);
const archExtension = arch === 'x86' ? 'i686' : 'x64';
let extension = '';
if (IS_WINDOWS) {
extension = `-win_${archExtension}.zip`;
} else {
if (process.platform === 'darwin') {
extension = `-macosx_${archExtension}.tar.gz`;
} else {
extension = `-linux_${archExtension}.tar.gz`;
}
}
core.debug(`Searching for files with extension: ${extension}`);
let pkgRegexp = new RegExp('');
let pkgTypeLength = 0;
if (javaPackage === 'jdk') {
pkgRegexp = /jdk.*-/gi;
pkgTypeLength = 'jdk'.length;
} else if (javaPackage == 'jre') {
pkgRegexp = /jre.*-/gi;
pkgTypeLength = 'jre'.length;
} else if (javaPackage == 'jdk+fx') {
pkgRegexp = /fx-jdk.*-/gi;
pkgTypeLength = 'fx-jdk'.length;
} else {
throw new Error(
`package argument ${javaPackage} is not in [jdk | jre | jdk+fx]`
);
}
// Maps version to url
let versionMap = new Map();
// Filter by platform
refs.forEach(ref => {
if (!ref.endsWith(extension + '">')) {
return;
}
// If we haven't returned, means we're looking at the correct platform
let versions = ref.match(pkgRegexp) || [];
if (versions.length > 1) {
throw new Error(
`Invalid ref received from https://static.azul.com/zulu/bin/: ${ref}`
);
}
if (versions.length == 0) {
return;
}
const refVersion = versions[0].slice(pkgTypeLength, versions[0].length - 1);
if (semver.satisfies(refVersion, version)) {
versionMap.set(
refVersion,
'https://static.azul.com/zulu/bin/' +
ref.slice('<a href="'.length, ref.length - '">'.length)
);
}
});
// Choose the most recent satisfying version
let curVersion = '0.0.0';
let curUrl = '';
for (const entry of versionMap.entries()) {
const entryVersion = entry[0];
const entryUrl = entry[1];
if (semver.gt(entryVersion, curVersion)) {
curUrl = entryUrl;
curVersion = entryVersion;
}
}
if (curUrl == '') {
throw new Error(
`No valid download found for version ${version} and package ${javaPackage}. Check https://static.azul.com/zulu/bin/ for a list of valid versions or download your own jdk file and add the jdkFile argument`
);
}
return {version: curVersion, url: curUrl};
}
function normalizeVersion(version: string): string {
if (version.slice(0, 2) === '1.') {
// Trim leading 1. for versions like 1.8
version = version.slice(2);
if (!version) {
throw new Error('1. is not a valid version');
}
}
if (version.endsWith('-ea')) {
// convert e.g. 14-ea to 14.0.0-ea
if (version.indexOf('.') == -1) {
version = version.slice(0, version.length - 3) + '.0.0-ea';
}
// match anything in -ea.X (semver won't do .x matching on pre-release versions)
if (version[0] >= '0' && version[0] <= '9') {
version = '>=' + version;
}
} else if (version.split('.').length < 3) {
// For non-ea versions, add trailing .x if it is missing
if (version[version.length - 1] != 'x') {
version = version + '.x';
}
}
return version;
}

@ -1,64 +1,45 @@
import * as core from '@actions/core';
import * as installer from './installer';
import * as auth from './auth';
import * as gpg from './gpg';
import { getBooleanInput } from './util';
import * as constants from './constants';
import * as path from 'path';
import { getJavaDistribution } from './distributions/distribution-factory';
import { JavaInstallerOptions } from './distributions/base-models';
async function run() {
try {
let version = core.getInput(constants.INPUT_VERSION);
if (!version) {
version = core.getInput(constants.INPUT_JAVA_VERSION, {required: true});
const version = core.getInput(constants.INPUT_JAVA_VERSION, { required: true });
const distributionName = core.getInput(constants.INPUT_DISTRIBUTION, { required: true });
const architecture = core.getInput(constants.INPUT_ARCHITECTURE);
const packageType = core.getInput(constants.INPUT_JAVA_PACKAGE);
const jdkFile = core.getInput(constants.INPUT_JDK_FILE);
const checkLatest = getBooleanInput(constants.INPUT_CHECK_LATEST, false);
const installerOptions: JavaInstallerOptions = {
architecture,
packageType,
version,
checkLatest
};
const distribution = getJavaDistribution(distributionName, installerOptions, jdkFile);
if (!distribution) {
throw new Error(`No supported distribution was found for input ${distributionName}`);
}
const arch = core.getInput(constants.INPUT_ARCHITECTURE, {required: true});
if (!['x86', 'x64'].includes(arch)) {
throw new Error(`architecture "${arch}" is not in [x86 | x64]`);
}
const result = await distribution.setupJava();
const javaPackage = core.getInput(constants.INPUT_JAVA_PACKAGE, {
required: true
});
const jdkFile = core.getInput(constants.INPUT_JDK_FILE, {required: false});
await installer.getJava(version, arch, jdkFile, javaPackage);
core.info('');
core.info('Java configuration:');
core.info(` Distribution: ${distributionName}`);
core.info(` Version: ${result.version}`);
core.info(` Path: ${result.path}`);
core.info('');
const matchersPath = path.join(__dirname, '..', '..', '.github');
core.info(`##[add-matcher]${path.join(matchersPath, 'java.json')}`);
const id = core.getInput(constants.INPUT_SERVER_ID, {required: false});
const username = core.getInput(constants.INPUT_SERVER_USERNAME, {
required: false
});
const password = core.getInput(constants.INPUT_SERVER_PASSWORD, {
required: false
});
const gpgPrivateKey =
core.getInput(constants.INPUT_GPG_PRIVATE_KEY, {required: false}) ||
constants.INPUT_DEFAULT_GPG_PRIVATE_KEY;
const gpgPassphrase =
core.getInput(constants.INPUT_GPG_PASSPHRASE, {required: false}) ||
(gpgPrivateKey ? constants.INPUT_DEFAULT_GPG_PASSPHRASE : undefined);
if (gpgPrivateKey) {
core.setSecret(gpgPrivateKey);
}
await auth.configAuthentication(id, username, password, gpgPassphrase);
if (gpgPrivateKey) {
core.info('importing private key');
const keyFingerprint = (await gpg.importKey(gpgPrivateKey)) || '';
core.saveState(
constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT,
keyFingerprint
);
}
core.warning(
`All setup-java actions pinned to the 'main' branch will fail on April 5th 2021. Please explicitly reference your action with the 'v1' tag ('actions/setup-java@v1') to avoid build failures. Find more details at https://github.com/actions/setup-java/issues/137`
);
await auth.configureAuthentication();
} catch (error) {
core.setFailed(error.message);
}

@ -1,26 +1,71 @@
import * as path from 'path';
import os from 'os';
import path from 'path';
import * as fs from 'fs';
import * as semver from 'semver';
import * as core from '@actions/core';
import * as tc from '@actions/tool-cache';
export function getTempDir() {
let tempDirectory = process.env.RUNNER_TEMP;
if (tempDirectory === undefined) {
let baseLocation;
if (isWindows()) {
// On windows use the USERPROFILE env variable
baseLocation = process.env['USERPROFILE']
? process.env['USERPROFILE']
: 'C:\\';
} else {
if (process.platform === 'darwin') {
baseLocation = '/Users';
} else {
baseLocation = '/home';
}
}
tempDirectory = path.join(baseLocation, 'actions', 'temp');
}
let tempDirectory = process.env['RUNNER_TEMP'] || os.tmpdir();
return tempDirectory;
}
export function isWindows() {
return process.platform === 'win32';
export function getBooleanInput(inputName: string, defaultValue: boolean = false) {
return (core.getInput(inputName) || String(defaultValue)).toUpperCase() === 'TRUE';
}
export function getVersionFromToolcachePath(toolPath: string) {
if (toolPath) {
return path.basename(path.dirname(toolPath));
}
return toolPath;
}
export async function extractJdkFile(toolPath: string, extension?: string) {
if (!extension) {
extension = toolPath.endsWith('.tar.gz') ? 'tar.gz' : path.extname(toolPath);
if (extension.startsWith('.')) {
extension = extension.substring(1);
}
}
switch (extension) {
case 'tar.gz':
case 'tar':
return await tc.extractTar(toolPath);
case 'zip':
return await tc.extractZip(toolPath);
default:
return await tc.extract7z(toolPath);
}
}
export function getDownloadArchiveExtension() {
return process.platform === 'win32' ? 'zip' : 'tar.gz';
}
export function isVersionSatisfies(range: string, version: string): boolean {
if (semver.valid(range)) {
// if full version with build digit is provided as a range (such as '1.2.3+4')
// we should check for exact equal via compareBuild
// since semver.satisfies doesn't handle 4th digit
const semRange = semver.parse(range);
if (semRange && semRange.build?.length > 0) {
return semver.compareBuild(range, version) === 0;
}
}
return semver.satisfies(version, range);
}
export function getToolcachePath(toolName: string, version: string, architecture: string) {
const toolcacheRoot = process.env['RUNNER_TOOL_CACHE'] ?? '';
const fullPath = path.join(toolcacheRoot, toolName, version, architecture);
if (fs.existsSync(fullPath)) {
return fullPath;
}
return null;
}

@ -1,7 +1,7 @@
extends: default
rules:
# 80 chars should be enough, but don't fail if a line is longer
# 100 chars should be enough, but don't fail if a line is longer
line-length:
max: 80
max: 100
level: warning