mirror of
https://github.com/actions/setup-java.git
synced 2026-06-23 00:01:14 +03:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a263f84254 | |||
| 6929a11922 | |||
| ad52b8c6db | |||
| 2321ab295d | |||
| 849c8f0094 | |||
| cefdecda46 | |||
| 347226bb3b | |||
| 5866e121b4 | |||
| 2872526dc6 | |||
| bb8b13a4a5 | |||
| 957ad8b43e | |||
| ce7f9ce621 | |||
| 6e9017e125 | |||
| baa1691374 | |||
| bc52a13212 | |||
| c9b6aee07e | |||
| f300429fba |
@@ -10,5 +10,9 @@ on:
|
||||
|
||||
jobs:
|
||||
call-codeQL-analysis:
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
name: CodeQL analysis
|
||||
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
|
||||
|
||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: "@actions/cache"
|
||||
version: 5.0.5
|
||||
version: 5.1.0
|
||||
type: npm
|
||||
summary: Actions cache lib
|
||||
homepage: https://github.com/actions/toolkit/tree/main/packages/cache
|
||||
|
||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: debug
|
||||
version: 4.3.4
|
||||
version: 4.4.3
|
||||
type: npm
|
||||
summary: Lightweight debugging utility for Node.js and the browser
|
||||
homepage:
|
||||
|
||||
Generated
+2
-2
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: ms
|
||||
version: 2.1.2
|
||||
version: 2.1.3
|
||||
type: npm
|
||||
summary: Tiny millisecond conversion utility
|
||||
homepage:
|
||||
@@ -10,7 +10,7 @@ licenses:
|
||||
text: |
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Zeit, Inc.
|
||||
Copyright (c) 2020 Vercel, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -105,29 +105,29 @@ The `java-version` input supports an exact version or a version range using [Sem
|
||||
|
||||
#### Supported distributions
|
||||
Currently, the following distributions are supported:
|
||||
| Keyword | Distribution | Official site | License
|
||||
|-|-|-|-|
|
||||
| `temurin` | Eclipse Temurin | [Link](https://adoptium.net/) | [Link](https://adoptium.net/about.html)
|
||||
| `zulu` | Azul 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` or `adopt-hotspot` | AdoptOpenJDK Hotspot | [Link](https://adoptopenjdk.net/) | [Link](https://adoptopenjdk.net/about.html) |
|
||||
| `adopt-openj9` | AdoptOpenJDK OpenJ9 | [Link](https://adoptopenjdk.net/) | [Link](https://adoptopenjdk.net/about.html) |
|
||||
| `liberica` | Liberica JDK | [Link](https://bell-sw.com/) | [Link](https://bell-sw.com/liberica_eula/) |
|
||||
| `microsoft` | Microsoft Build of OpenJDK | [Link](https://www.microsoft.com/openjdk) | [Link](https://docs.microsoft.com/java/openjdk/faq)
|
||||
| `corretto` | Amazon Corretto Build of OpenJDK | [Link](https://aws.amazon.com/corretto/) | [Link](https://aws.amazon.com/corretto/faqs/)
|
||||
| `semeru` | IBM Semeru Runtime Open Edition | [Link](https://developer.ibm.com/languages/java/semeru-runtimes/downloads/) | [Link](https://openjdk.java.net/legal/gplv2+ce.html) |
|
||||
| `oracle` | Oracle JDK | [Link](https://www.oracle.com/java/technologies/downloads/) | [Link](https://java.com/freeuselicense)
|
||||
| `dragonwell` | Alibaba Dragonwell JDK | [Link](https://dragonwell-jdk.io/) | [Link](https://www.aliyun.com/product/dragonwell/)
|
||||
| `sapmachine` | SAP SapMachine JDK/JRE | [Link](https://sapmachine.io/) | [Link](https://github.com/SAP/SapMachine/blob/sapmachine/LICENSE)
|
||||
| `graalvm` | Oracle GraalVM | [Link](https://www.graalvm.org/) | [Link](https://www.oracle.com/downloads/licenses/graal-free-license.html)
|
||||
| `jetbrains` | JetBrains Runtime | [Link](https://github.com/JetBrains/JetBrainsRuntime/) | [Link](https://github.com/JetBrains/JetBrainsRuntime/blob/main/LICENSE)
|
||||
| Keyword | Distribution / Official site | License
|
||||
|-|-|-|
|
||||
| `temurin` | [Eclipse Temurin](https://adoptium.net/) | [`temurin` license](https://adoptium.net/about.html)
|
||||
| `zulu` | [Azul Zulu OpenJDK](https://www.azul.com/downloads/zulu-community/?package=jdk) | [`zulu` license](https://www.azul.com/products/zulu-and-zulu-enterprise/zulu-terms-of-use/) |
|
||||
| `adopt` or `adopt-hotspot` | [AdoptOpenJDK Hotspot](https://adoptopenjdk.net/) | [`adopt-hotspot` license](https://adoptopenjdk.net/about.html) |
|
||||
| `adopt-openj9` | [AdoptOpenJDK OpenJ9](https://adoptopenjdk.net/) | [`adopt-openj9` license](https://adoptopenjdk.net/about.html) |
|
||||
| `liberica` | [Liberica JDK](https://bell-sw.com/) | [`liberica` license](https://bell-sw.com/liberica_eula/) |
|
||||
| `microsoft` | [Microsoft Build of OpenJDK](https://www.microsoft.com/openjdk) | [`microsoft` license](https://docs.microsoft.com/java/openjdk/faq)
|
||||
| `corretto` | [Amazon Corretto Build of OpenJDK](https://aws.amazon.com/corretto/) | [`corretto` license](https://aws.amazon.com/corretto/faqs/)
|
||||
| `semeru` | [IBM Semeru Runtime Open Edition](https://developer.ibm.com/languages/java/semeru-runtimes/downloads/) | [`semeru` license](https://openjdk.java.net/legal/gplv2+ce.html) |
|
||||
| `oracle` | [Oracle JDK](https://www.oracle.com/java/technologies/downloads/) | [`oracle` license](https://java.com/freeuselicense)
|
||||
| `dragonwell` | [Alibaba Dragonwell JDK](https://dragonwell-jdk.io/) | [`dragonwell` license](https://www.aliyun.com/product/dragonwell/)
|
||||
| `sapmachine` | [SAP SapMachine JDK/JRE](https://sapmachine.io/) | [`sapmachine` license](https://github.com/SAP/SapMachine/blob/sapmachine/LICENSE)
|
||||
| `graalvm` | [Oracle GraalVM](https://www.graalvm.org/) | [`graalvm` license](https://www.oracle.com/downloads/licenses/graal-free-license.html)
|
||||
| `graalvm-community` | [GraalVM Community](https://github.com/graalvm/graalvm-ce-builds/releases) | [`graalvm-community` license](https://github.com/oracle/graal/blob/master/LICENSE)
|
||||
| `jetbrains` | [JetBrains Runtime](https://github.com/JetBrains/JetBrainsRuntime/) | [`jetbrains` license](https://github.com/JetBrains/JetBrainsRuntime/blob/main/LICENSE)
|
||||
|
||||
**NOTE:** The different distributors can provide discrepant list of available versions / supported configurations. Please refer to the official documentation to see the list of supported versions.
|
||||
|
||||
**NOTE:** AdoptOpenJDK got moved to Eclipse Temurin and won't be updated anymore. It is highly recommended to migrate workflows from `adopt` and `adopt-openj9`, to `temurin` and `semeru` respectively, to keep receiving software and security updates. See more details in the [Good-bye AdoptOpenJDK post](https://blog.adoptopenjdk.net/2021/08/goodbye-adoptopenjdk-hello-adoptium/).
|
||||
|
||||
**NOTE:** For Azul Zulu OpenJDK architectures x64 and arm64 are mapped to x86 / arm with proper hw_bitness.
|
||||
|
||||
**NOTE:** To comply with the GraalVM Free Terms and Conditions (GFTC) license, it is recommended to use GraalVM JDK 17 version 17.0.12, as this is the only version of GraalVM JDK 17 available under the GFTC license. Additionally, it is encouraged to consider upgrading to GraalVM JDK 21, which offers the latest features and improvements.
|
||||
> [!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.
|
||||
> - AdoptOpenJDK got moved to Eclipse Temurin and won't be updated anymore. It is highly recommended to migrate workflows from `adopt` and `adopt-openj9`, to `temurin` and `semeru` respectively, to keep receiving software and security updates. See more details in the [Good-bye AdoptOpenJDK post](https://blog.adoptopenjdk.net/2021/08/goodbye-adoptopenjdk-hello-adoptium/).
|
||||
> - For Azul Zulu OpenJDK architectures x64 and arm64 are mapped to x86 / arm with proper hw_bitness.
|
||||
> - To comply with the GraalVM Free Terms and Conditions (GFTC) license, it is recommended to use GraalVM JDK 17 version 17.0.12, as this is the only version of GraalVM JDK 17 available under the GFTC license. Additionally, it is encouraged to consider upgrading to GraalVM JDK 21, which offers the latest features and improvements.
|
||||
> - GraalVM Community is available as `distribution: 'graalvm-community'` for stable JDK 17 and later releases published on GitHub.
|
||||
|
||||
**NOTE:** Oracle JDK 17 licensing varies by patch level. As shown on the [JDK 17 Archive](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) (versions up to 17.0.12 are under the [NFTC](https://www.oracle.com/downloads/licenses/no-fee-license.html) license) and the [JDK 17.0.13+ Archive](https://www.oracle.com/java/technologies/javase/jdk17-0-13-later-archive-downloads.html) (versions 17.0.13 and later are under the [OTN](https://www.oracle.com/downloads/licenses/javase-license1.html) license). To stay on the free NFTC license, use `distribution: 'oracle'` with `java-version: '17.0.12'` (or earlier) instead of the floating `'17'`. Alternatively, upgrade to Oracle JDK 21+, which remains under the NFTC license.
|
||||
|
||||
@@ -137,7 +137,7 @@ Currently, the following distributions are supported:
|
||||
The action has a built-in functionality for caching and restoring dependencies. It uses [toolkit/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under hood for caching dependencies but requires less configuration settings. Supported package managers are gradle, maven and sbt. The format of the used cache key is `setup-java-${{ platform }}-${{ packageManager }}-${{ fileHash }}`, where the hash is based on the following files:
|
||||
|
||||
- gradle: `**/*.gradle*`, `**/gradle-wrapper.properties`, `buildSrc/**/Versions.kt`, `buildSrc/**/Dependencies.kt`, `gradle/*.versions.toml`, and `**/versions.properties`
|
||||
- maven: `**/pom.xml`
|
||||
- maven: `**/pom.xml` and `**/.mvn/wrapper/maven-wrapper.properties`
|
||||
- sbt: all sbt build definition files `**/*.sbt`, `**/project/build.properties`, `**/project/**.scala`, `**/project/**.sbt`
|
||||
|
||||
When the option `cache-dependency-path` is specified, the hash is based on the matching file. This option supports wildcards and a list of file names, and is especially useful for monorepos.
|
||||
@@ -218,7 +218,7 @@ In the basic examples above, the `check-latest` flag defaults to `false`. When s
|
||||
|
||||
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.
|
||||
For Java distributions that are not cached on Hosted images, `check-latest` always behaves as `true` and downloads Java on the fly. Check out [Hosted Tool Cache](docs/advanced-usage.md#Hosted-Tool-Cache) for more details about pre-cached Java versions.
|
||||
|
||||
|
||||
```yaml
|
||||
@@ -282,6 +282,7 @@ In the example above multiple JDKs are installed for the same job. The result af
|
||||
- [Alibaba Dragonwell](docs/advanced-usage.md#Alibaba-Dragonwell)
|
||||
- [SapMachine](docs/advanced-usage.md#SapMachine)
|
||||
- [GraalVM](docs/advanced-usage.md#GraalVM)
|
||||
- [JetBrains](docs/advanced-usage.md#JetBrains)
|
||||
- [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)
|
||||
|
||||
+38
-7
@@ -96,19 +96,48 @@ describe('dependency cache', () => {
|
||||
});
|
||||
|
||||
describe('for maven', () => {
|
||||
it('throws error if no pom.xml found', async () => {
|
||||
it('throws error if no pom.xml or maven-wrapper.properties found', async () => {
|
||||
await expect(restore('maven', '')).rejects.toThrow(
|
||||
`No file in ${projectRoot(
|
||||
workspace
|
||||
)} matched to [**/pom.xml], make sure you have checked out the target repository`
|
||||
)} matched to [**/pom.xml,**/.mvn/wrapper/maven-wrapper.properties], make sure you have checked out the target repository`
|
||||
);
|
||||
});
|
||||
it('downloads cache', async () => {
|
||||
it('downloads cache based on pom.xml', async () => {
|
||||
createFile(join(workspace, 'pom.xml'));
|
||||
|
||||
await restore('maven', '');
|
||||
expect(spyCacheRestore).toHaveBeenCalled();
|
||||
expect(spyGlobHashFiles).toHaveBeenCalledWith('**/pom.xml');
|
||||
expect(spyCacheRestore).toHaveBeenCalledWith(
|
||||
[
|
||||
join(os.homedir(), '.m2', 'repository'),
|
||||
join(os.homedir(), '.m2', 'wrapper', 'dists')
|
||||
],
|
||||
expect.any(String)
|
||||
);
|
||||
expect(spyGlobHashFiles).toHaveBeenCalledWith(
|
||||
'**/pom.xml\n**/.mvn/wrapper/maven-wrapper.properties'
|
||||
);
|
||||
expect(spyWarning).not.toHaveBeenCalled();
|
||||
expect(spyInfo).toHaveBeenCalledWith('maven cache is not found');
|
||||
});
|
||||
it('downloads cache based on maven-wrapper.properties', async () => {
|
||||
createDirectory(join(workspace, '.mvn'));
|
||||
createDirectory(join(workspace, '.mvn', 'wrapper'));
|
||||
createFile(
|
||||
join(workspace, '.mvn', 'wrapper', 'maven-wrapper.properties')
|
||||
);
|
||||
|
||||
await restore('maven', '');
|
||||
expect(spyCacheRestore).toHaveBeenCalledWith(
|
||||
[
|
||||
join(os.homedir(), '.m2', 'repository'),
|
||||
join(os.homedir(), '.m2', 'wrapper', 'dists')
|
||||
],
|
||||
expect.any(String)
|
||||
);
|
||||
expect(spyGlobHashFiles).toHaveBeenCalledWith(
|
||||
'**/pom.xml\n**/.mvn/wrapper/maven-wrapper.properties'
|
||||
);
|
||||
expect(spyWarning).not.toHaveBeenCalled();
|
||||
expect(spyInfo).toHaveBeenCalledWith('maven cache is not found');
|
||||
});
|
||||
@@ -291,10 +320,12 @@ describe('dependency cache', () => {
|
||||
await save('maven');
|
||||
expect(spyCacheSave).toHaveBeenCalled();
|
||||
expect(spyWarning).not.toHaveBeenCalled();
|
||||
expect(spyInfo).toHaveBeenCalled();
|
||||
expect(spyInfo).toHaveBeenCalledWith(
|
||||
expect(spyInfo).not.toHaveBeenCalledWith(
|
||||
expect.stringMatching(/^Cache saved with the key:.*/)
|
||||
);
|
||||
expect(spyDebug).toHaveBeenCalledWith(
|
||||
expect.stringMatching(/^Cache was not saved for the key:.*/)
|
||||
);
|
||||
});
|
||||
|
||||
it('saves with error from toolkit, should fail workflow', async () => {
|
||||
|
||||
@@ -39,7 +39,7 @@ describe('cleanup', () => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('does not fail nor warn even when the save process throws a ReserveCacheError', async () => {
|
||||
it('does not warn/fail even when the save process throws a ReserveCacheError', async () => {
|
||||
spyCacheSave.mockImplementation((paths: string[], key: string) =>
|
||||
Promise.reject(
|
||||
new cache.ReserveCacheError(
|
||||
|
||||
@@ -79,6 +79,49 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "17.0.18",
|
||||
"stable": true,
|
||||
"release_url": "https://aka.ms/download-jdk",
|
||||
"files": [
|
||||
{
|
||||
"filename": "microsoft-jdk-17.0.18-macos-x64.tar.gz",
|
||||
"arch": "x64",
|
||||
"platform": "darwin",
|
||||
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-17.0.18-macos-x64.tar.gz"
|
||||
},
|
||||
{
|
||||
"filename": "microsoft-jdk-17.0.18-linux-x64.tar.gz",
|
||||
"arch": "x64",
|
||||
"platform": "linux",
|
||||
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-17.0.18-linux-x64.tar.gz"
|
||||
},
|
||||
{
|
||||
"filename": "microsoft-jdk-17.0.18-windows-x64.zip",
|
||||
"arch": "x64",
|
||||
"platform": "win32",
|
||||
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-17.0.18-windows-x64.zip"
|
||||
},
|
||||
{
|
||||
"filename": "microsoft-jdk-17.0.18-macos-aarch64.tar.gz",
|
||||
"arch": "aarch64",
|
||||
"platform": "darwin",
|
||||
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-17.0.18-macos-aarch64.tar.gz"
|
||||
},
|
||||
{
|
||||
"filename": "microsoft-jdk-17.0.18-linux-aarch64.tar.gz",
|
||||
"arch": "aarch64",
|
||||
"platform": "linux",
|
||||
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-17.0.18-linux-aarch64.tar.gz"
|
||||
},
|
||||
{
|
||||
"filename": "microsoft-jdk-17.0.18-windows-aarch64.zip",
|
||||
"arch": "aarch64",
|
||||
"platform": "win32",
|
||||
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-17.0.18-windows-aarch64.zip"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "17.0.7",
|
||||
"stable": true,
|
||||
|
||||
@@ -247,7 +247,7 @@
|
||||
{
|
||||
"id": 12446,
|
||||
"url": "https://cdn.azul.com/zulu/bin/zulu17.48.15-ca-jdk17.0.10-windows_aarch64.zip",
|
||||
"name": "zulu17.48.15-ca-jdk17.0.10-win_aarhc4.zip",
|
||||
"name": "zulu17.48.15-ca-jdk17.0.10-win_aarch4.zip",
|
||||
"zulu_version": [17, 48, 15, 0],
|
||||
"jdk_version": [17, 0, 10, 7]
|
||||
}
|
||||
|
||||
@@ -3,7 +3,11 @@ import * as tc from '@actions/tool-cache';
|
||||
import * as http from '@actions/http-client';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import {GraalVMDistribution} from '../../src/distributions/graalvm/installer';
|
||||
import {
|
||||
GraalVMCommunityDistribution,
|
||||
GraalVMDistribution
|
||||
} from '../../src/distributions/graalvm/installer';
|
||||
import {getJavaDistribution} from '../../src/distributions/distribution-factory';
|
||||
import {JavaInstallerOptions} from '../../src/distributions/base-models';
|
||||
import * as util from '../../src/util';
|
||||
|
||||
@@ -41,6 +45,7 @@ beforeAll(() => {
|
||||
|
||||
describe('GraalVMDistribution', () => {
|
||||
let distribution: GraalVMDistribution;
|
||||
let communityDistribution: GraalVMCommunityDistribution;
|
||||
let mockHttpClient: jest.Mocked<http.HttpClient>;
|
||||
let spyCoreError: jest.SpyInstance;
|
||||
|
||||
@@ -55,9 +60,11 @@ describe('GraalVMDistribution', () => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
distribution = new GraalVMDistribution(defaultOptions);
|
||||
communityDistribution = new GraalVMCommunityDistribution(defaultOptions);
|
||||
|
||||
mockHttpClient = new http.HttpClient() as jest.Mocked<http.HttpClient>;
|
||||
(distribution as any).http = mockHttpClient;
|
||||
(communityDistribution as any).http = mockHttpClient;
|
||||
|
||||
(util.getDownloadArchiveExtension as jest.Mock).mockReturnValue('tar.gz');
|
||||
|
||||
@@ -242,6 +249,21 @@ describe('GraalVMDistribution', () => {
|
||||
path: '/cached/java/path'
|
||||
});
|
||||
});
|
||||
|
||||
it('should use a dedicated toolcache folder for GraalVM Community', async () => {
|
||||
const result = await (communityDistribution as any).downloadTool(javaRelease);
|
||||
|
||||
expect(tc.cacheDir).toHaveBeenCalledWith(
|
||||
path.join('/tmp/extracted', 'graalvm-jdk-17.0.5'),
|
||||
'Java_GraalVM_Community_jdk',
|
||||
'17.0.5',
|
||||
'x64'
|
||||
);
|
||||
expect(result).toEqual({
|
||||
version: '17.0.5',
|
||||
path: '/cached/java/path'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('findPackageForDownload', () => {
|
||||
@@ -948,5 +970,104 @@ describe('GraalVMDistribution', () => {
|
||||
configurable: true
|
||||
});
|
||||
});
|
||||
|
||||
describe('GraalVMCommunityDistribution', () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(communityDistribution, 'getPlatform').mockReturnValue('linux');
|
||||
});
|
||||
|
||||
it('should resolve an exact GraalVM Community version from GitHub releases', async () => {
|
||||
mockHttpClient.getJson.mockResolvedValue({
|
||||
result: [
|
||||
{
|
||||
draft: false,
|
||||
prerelease: false,
|
||||
assets: [
|
||||
{
|
||||
name: 'graalvm-community-jdk-21.0.2_linux-x64_bin.tar.gz',
|
||||
browser_download_url:
|
||||
'https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-21.0.2/graalvm-community-jdk-21.0.2_linux-x64_bin.tar.gz'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
statusCode: 200,
|
||||
headers: {}
|
||||
});
|
||||
|
||||
const result = await (communityDistribution as any).findPackageForDownload(
|
||||
'21.0.2'
|
||||
);
|
||||
|
||||
expect(result).toEqual({
|
||||
url: 'https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-21.0.2/graalvm-community-jdk-21.0.2_linux-x64_bin.tar.gz',
|
||||
version: '21.0.2'
|
||||
});
|
||||
});
|
||||
|
||||
it('should resolve the latest GraalVM Community release for a major version', async () => {
|
||||
mockHttpClient.getJson.mockResolvedValue({
|
||||
result: [
|
||||
{
|
||||
draft: false,
|
||||
prerelease: false,
|
||||
assets: [
|
||||
{
|
||||
name: 'graalvm-community-jdk-21.0.1_linux-x64_bin.tar.gz',
|
||||
browser_download_url:
|
||||
'https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-21.0.1/graalvm-community-jdk-21.0.1_linux-x64_bin.tar.gz'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
draft: false,
|
||||
prerelease: false,
|
||||
assets: [
|
||||
{
|
||||
name: 'graalvm-community-jdk-21.0.2_linux-x64_bin.tar.gz',
|
||||
browser_download_url:
|
||||
'https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-21.0.2/graalvm-community-jdk-21.0.2_linux-x64_bin.tar.gz'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
statusCode: 200,
|
||||
headers: {}
|
||||
});
|
||||
|
||||
const result = await (communityDistribution as any).findPackageForDownload(
|
||||
'21'
|
||||
);
|
||||
|
||||
expect(result).toEqual({
|
||||
url: 'https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-21.0.2/graalvm-community-jdk-21.0.2_linux-x64_bin.tar.gz',
|
||||
version: '21.0.2'
|
||||
});
|
||||
});
|
||||
|
||||
it('should reject GraalVM Community early access requests', async () => {
|
||||
(communityDistribution as any).stable = false;
|
||||
|
||||
await expect(
|
||||
(communityDistribution as any).findPackageForDownload('23')
|
||||
).rejects.toThrow('GraalVM Community does not provide early access builds');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('distribution factory', () => {
|
||||
const defaultOptions: JavaInstallerOptions = {
|
||||
version: '17',
|
||||
architecture: 'x64',
|
||||
packageType: 'jdk',
|
||||
checkLatest: false
|
||||
};
|
||||
|
||||
it('should map graalvm-community to the community installer', () => {
|
||||
const community = getJavaDistribution('graalvm-community', defaultOptions);
|
||||
|
||||
expect(community).toBeInstanceOf(GraalVMCommunityDistribution);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -219,7 +219,7 @@ describe('setupJava', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('java is resolved from toolcache including Contents/Home on MacOS', async () => {
|
||||
it('java is resolved from toolcache including Contents/Home on macOS', async () => {
|
||||
const inputs = {
|
||||
version: actualJavaVersion,
|
||||
architecture: 'x86',
|
||||
@@ -262,7 +262,7 @@ describe('setupJava', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('java is unpacked from jdkfile including Contents/Home on MacOS', async () => {
|
||||
it('java is unpacked from jdkfile including Contents/Home on macOS', async () => {
|
||||
const inputs = {
|
||||
version: '11.0.289',
|
||||
architecture: 'x86',
|
||||
|
||||
@@ -44,16 +44,21 @@ describe('findPackageForDownload', () => {
|
||||
'21.0.0',
|
||||
'https://aka.ms/download-jdk/microsoft-jdk-21.0.0-{{OS_TYPE}}-x64.{{ARCHIVE_TYPE}}'
|
||||
],
|
||||
[
|
||||
'17.x',
|
||||
'17.0.18',
|
||||
'https://aka.ms/download-jdk/microsoft-jdk-17.0.18-{{OS_TYPE}}-x64.{{ARCHIVE_TYPE}}'
|
||||
],
|
||||
[
|
||||
'17.0.7',
|
||||
'17.0.7',
|
||||
'https://aka.ms/download-jdk/microsoft-jdk-17.0.7-{{OS_TYPE}}-x64.{{ARCHIVE_TYPE}}'
|
||||
],
|
||||
[
|
||||
'17.0.1',
|
||||
'17.0.1+12.1',
|
||||
'https://aka.ms/download-jdk/microsoft-jdk-17.0.1.12.1-{{OS_TYPE}}-x64.{{ARCHIVE_TYPE}}'
|
||||
],
|
||||
[
|
||||
'17.x',
|
||||
'17.0.7',
|
||||
'https://aka.ms/download-jdk/microsoft-jdk-17.0.7-{{OS_TYPE}}-x64.{{ARCHIVE_TYPE}}'
|
||||
],
|
||||
[
|
||||
'16.0.x',
|
||||
'16.0.2+7.1',
|
||||
@@ -119,7 +124,7 @@ describe('findPackageForDownload', () => {
|
||||
});
|
||||
|
||||
const result = await distro['findPackageForDownload'](version);
|
||||
const expectedUrl = `https://aka.ms/download-jdk/microsoft-jdk-17.0.7-macos-${distroArch}.tar.gz`;
|
||||
const expectedUrl = `https://aka.ms/download-jdk/microsoft-jdk-17.0.18-macos-${distroArch}.tar.gz`;
|
||||
|
||||
expect(result.url).toBe(expectedUrl);
|
||||
}
|
||||
@@ -145,7 +150,7 @@ describe('findPackageForDownload', () => {
|
||||
});
|
||||
|
||||
const result = await distro['findPackageForDownload'](version);
|
||||
const expectedUrl = `https://aka.ms/download-jdk/microsoft-jdk-17.0.7-linux-${distroArch}.tar.gz`;
|
||||
const expectedUrl = `https://aka.ms/download-jdk/microsoft-jdk-17.0.18-linux-${distroArch}.tar.gz`;
|
||||
|
||||
expect(result.url).toBe(expectedUrl);
|
||||
}
|
||||
@@ -171,7 +176,7 @@ describe('findPackageForDownload', () => {
|
||||
});
|
||||
|
||||
const result = await distro['findPackageForDownload'](version);
|
||||
const expectedUrl = `https://aka.ms/download-jdk/microsoft-jdk-17.0.7-windows-${distroArch}.zip`;
|
||||
const expectedUrl = `https://aka.ms/download-jdk/microsoft-jdk-17.0.18-windows-${distroArch}.zip`;
|
||||
|
||||
expect(result.url).toBe(expectedUrl);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,11 @@ describe('isVersionSatisfies', () => {
|
||||
['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]
|
||||
['15.0.0+14.1.202003190635', '15.0.0+14.1.202003190635', true],
|
||||
// 4-segment versions (e.g. JetBrains Runtime '17.0.8.1+1080.1') are not
|
||||
// valid semver — they should be rejected, not throw.
|
||||
['25.0.3+480.61', '17.0.8.1+1080.1', false],
|
||||
['17', '17.0.8.1+1080.1', false]
|
||||
])(
|
||||
'%s, %s -> %s',
|
||||
(inputRange: string, inputVersion: string, expected: boolean) => {
|
||||
|
||||
+7
-3
@@ -5,8 +5,10 @@ author: 'GitHub'
|
||||
inputs:
|
||||
java-version:
|
||||
description: 'The Java version to set up. Takes a whole or semver Java version. See examples of supported syntax in README file'
|
||||
required: false
|
||||
java-version-file:
|
||||
description: 'The path to the `.java-version` file. See examples of supported syntax in README file'
|
||||
description: 'The path to a file containing the Java version to set up (.java-version, .tool-versions, .sdkmanrc). Used when java-version is not set. See examples of supported syntax in README file'
|
||||
required: false
|
||||
distribution:
|
||||
description: 'Java distribution. See the list of supported distributions in README file'
|
||||
required: true
|
||||
@@ -49,9 +51,9 @@ inputs:
|
||||
gpg-private-key:
|
||||
description: 'GPG private key to import. Default is empty string.'
|
||||
required: false
|
||||
default: ''
|
||||
gpg-passphrase:
|
||||
description: 'Environment variable name for the GPG private key passphrase. Default is
|
||||
$GPG_PASSPHRASE.'
|
||||
description: 'Environment variable name for the GPG private key passphrase. Defaults to GPG_PASSPHRASE when gpg-private-key is set; ignored otherwise.'
|
||||
required: false
|
||||
cache:
|
||||
description: 'Name of the build platform to cache dependencies. It can be "maven", "gradle" or "sbt".'
|
||||
@@ -61,9 +63,11 @@ inputs:
|
||||
required: false
|
||||
job-status:
|
||||
description: 'Workaround to pass job status to post job step. This variable is not intended for manual setting'
|
||||
required: false
|
||||
default: ${{ job.status }}
|
||||
token:
|
||||
description: The token used to authenticate when fetching version manifests hosted on github.com, such as for the Microsoft Build of OpenJDK. When running this action on github.com, the default value is sufficient. When running on GHES, you can pass a personal access token for github.com if you are experiencing rate limiting.
|
||||
required: false
|
||||
default: ${{ github.server_url == 'https://github.com' && github.token || '' }}
|
||||
mvn-toolchain-id:
|
||||
description: 'Name of Maven Toolchain ID if the default name of "${distribution}_${java-version}" is not wanted. See examples of supported syntax in Advanced Usage file'
|
||||
|
||||
Vendored
+415
-142
@@ -49,7 +49,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.FinalizeCacheError = exports.ReserveCacheError = exports.ValidationError = void 0;
|
||||
exports.FinalizeCacheError = exports.CacheWriteDeniedError = exports.CACHE_WRITE_DENIED_PREFIX = exports.ReserveCacheError = exports.ValidationError = void 0;
|
||||
exports.isFeatureAvailable = isFeatureAvailable;
|
||||
exports.restoreCache = restoreCache;
|
||||
exports.saveCache = saveCache;
|
||||
@@ -77,6 +77,26 @@ class ReserveCacheError extends Error {
|
||||
}
|
||||
}
|
||||
exports.ReserveCacheError = ReserveCacheError;
|
||||
/**
|
||||
* Stable prefix used by the cache receiver to signal that the token has
|
||||
* no writable scopes (read-only cache policy). Consumers can match on
|
||||
* this prefix to distinguish policy denials from ordinary contention.
|
||||
*/
|
||||
exports.CACHE_WRITE_DENIED_PREFIX = 'cache write denied:';
|
||||
/**
|
||||
* Extends ReserveCacheError for source-compatibility: existing
|
||||
* `instanceof ReserveCacheError` checks and `typedError.name ===
|
||||
* ReserveCacheError.name` paths keep working, while consumers that want to
|
||||
* distinguish a policy denial can check for CacheWriteDeniedError.name.
|
||||
*/
|
||||
class CacheWriteDeniedError extends ReserveCacheError {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = 'CacheWriteDeniedError';
|
||||
Object.setPrototypeOf(this, CacheWriteDeniedError.prototype);
|
||||
}
|
||||
}
|
||||
exports.CacheWriteDeniedError = CacheWriteDeniedError;
|
||||
class FinalizeCacheError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
@@ -387,7 +407,11 @@ function saveCacheV1(paths_1, key_1, options_1) {
|
||||
throw new Error((_d = (_c = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _c === void 0 ? void 0 : _c.message) !== null && _d !== void 0 ? _d : `Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the data cap limit, not saving cache.`);
|
||||
}
|
||||
else {
|
||||
throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache. More details: ${(_e = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _e === void 0 ? void 0 : _e.message}`);
|
||||
const detailMessage = (_e = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _e === void 0 ? void 0 : _e.message;
|
||||
if (detailMessage === null || detailMessage === void 0 ? void 0 : detailMessage.startsWith(exports.CACHE_WRITE_DENIED_PREFIX)) {
|
||||
throw new CacheWriteDeniedError(`Unable to reserve cache with key ${key}. More details: ${detailMessage}`);
|
||||
}
|
||||
throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache. More details: ${detailMessage}`);
|
||||
}
|
||||
core.debug(`Saving Cache (ID: ${cacheId})`);
|
||||
yield cacheHttpClient.saveCache(cacheId, archivePath, '', options);
|
||||
@@ -397,6 +421,9 @@ function saveCacheV1(paths_1, key_1, options_1) {
|
||||
if (typedError.name === ValidationError.name) {
|
||||
throw error;
|
||||
}
|
||||
else if (typedError.name === CacheWriteDeniedError.name) {
|
||||
core.warning(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else if (typedError.name === ReserveCacheError.name) {
|
||||
core.info(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
@@ -435,6 +462,7 @@ function saveCacheV1(paths_1, key_1, options_1) {
|
||||
*/
|
||||
function saveCacheV2(paths_1, key_1, options_1) {
|
||||
return __awaiter(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) {
|
||||
var _a;
|
||||
// Override UploadOptions to force the use of Azure
|
||||
// ...options goes first because we want to override the default values
|
||||
// set in UploadOptions with these specific figures
|
||||
@@ -470,7 +498,11 @@ function saveCacheV2(paths_1, key_1, options_1) {
|
||||
try {
|
||||
const response = yield twirpClient.CreateCacheEntry(request);
|
||||
if (!response.ok) {
|
||||
if (response.message) {
|
||||
// Skip the redundant inner warning when the receiver signalled a
|
||||
// policy denial: the outer catch arm below will log a single
|
||||
// customer-facing warning.
|
||||
if (response.message &&
|
||||
!response.message.startsWith(exports.CACHE_WRITE_DENIED_PREFIX)) {
|
||||
core.warning(`Cache reservation failed: ${response.message}`);
|
||||
}
|
||||
throw new Error(response.message || 'Response was not ok');
|
||||
@@ -479,6 +511,10 @@ function saveCacheV2(paths_1, key_1, options_1) {
|
||||
}
|
||||
catch (error) {
|
||||
core.debug(`Failed to reserve cache: ${error}`);
|
||||
const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '';
|
||||
if (errorMessage.startsWith(exports.CACHE_WRITE_DENIED_PREFIX)) {
|
||||
throw new CacheWriteDeniedError(`Unable to reserve cache with key ${key}. More details: ${errorMessage}`);
|
||||
}
|
||||
throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache.`);
|
||||
}
|
||||
core.debug(`Attempting to upload cache located at: ${archivePath}`);
|
||||
@@ -503,6 +539,9 @@ function saveCacheV2(paths_1, key_1, options_1) {
|
||||
if (typedError.name === ValidationError.name) {
|
||||
throw error;
|
||||
}
|
||||
else if (typedError.name === CacheWriteDeniedError.name) {
|
||||
core.warning(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
else if (typedError.name === ReserveCacheError.name) {
|
||||
core.info(`Failed to save: ${typedError.message}`);
|
||||
}
|
||||
@@ -18118,14 +18157,17 @@ function useColors() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let m;
|
||||
|
||||
// Is webkit? http://stackoverflow.com/a/16459606/376773
|
||||
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
||||
// eslint-disable-next-line no-return-assign
|
||||
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
||||
// Is firebug? http://stackoverflow.com/a/398120/376773
|
||||
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
||||
// Is firefox >= v31?
|
||||
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
||||
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
|
||||
(typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) ||
|
||||
// Double check webkit in userAgent just in case we are in a worker
|
||||
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
|
||||
}
|
||||
@@ -18209,7 +18251,7 @@ function save(namespaces) {
|
||||
function load() {
|
||||
let r;
|
||||
try {
|
||||
r = exports.storage.getItem('debug');
|
||||
r = exports.storage.getItem('debug') || exports.storage.getItem('DEBUG') ;
|
||||
} catch (error) {
|
||||
// Swallow
|
||||
// XXX (@Qix-) should we be logging these?
|
||||
@@ -18435,26 +18477,64 @@ function setup(env) {
|
||||
createDebug.names = [];
|
||||
createDebug.skips = [];
|
||||
|
||||
let i;
|
||||
const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
|
||||
const len = split.length;
|
||||
const split = (typeof namespaces === 'string' ? namespaces : '')
|
||||
.trim()
|
||||
.replace(/\s+/g, ',')
|
||||
.split(',')
|
||||
.filter(Boolean);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!split[i]) {
|
||||
// ignore empty strings
|
||||
continue;
|
||||
}
|
||||
|
||||
namespaces = split[i].replace(/\*/g, '.*?');
|
||||
|
||||
if (namespaces[0] === '-') {
|
||||
createDebug.skips.push(new RegExp('^' + namespaces.slice(1) + '$'));
|
||||
for (const ns of split) {
|
||||
if (ns[0] === '-') {
|
||||
createDebug.skips.push(ns.slice(1));
|
||||
} else {
|
||||
createDebug.names.push(new RegExp('^' + namespaces + '$'));
|
||||
createDebug.names.push(ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given string matches a namespace template, honoring
|
||||
* asterisks as wildcards.
|
||||
*
|
||||
* @param {String} search
|
||||
* @param {String} template
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function matchesTemplate(search, template) {
|
||||
let searchIndex = 0;
|
||||
let templateIndex = 0;
|
||||
let starIndex = -1;
|
||||
let matchIndex = 0;
|
||||
|
||||
while (searchIndex < search.length) {
|
||||
if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) {
|
||||
// Match character or proceed with wildcard
|
||||
if (template[templateIndex] === '*') {
|
||||
starIndex = templateIndex;
|
||||
matchIndex = searchIndex;
|
||||
templateIndex++; // Skip the '*'
|
||||
} else {
|
||||
searchIndex++;
|
||||
templateIndex++;
|
||||
}
|
||||
} else if (starIndex !== -1) { // eslint-disable-line no-negated-condition
|
||||
// Backtrack to the last '*' and try to match more characters
|
||||
templateIndex = starIndex + 1;
|
||||
matchIndex++;
|
||||
searchIndex = matchIndex;
|
||||
} else {
|
||||
return false; // No match
|
||||
}
|
||||
}
|
||||
|
||||
// Handle trailing '*' in template
|
||||
while (templateIndex < template.length && template[templateIndex] === '*') {
|
||||
templateIndex++;
|
||||
}
|
||||
|
||||
return templateIndex === template.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable debug output.
|
||||
*
|
||||
@@ -18463,8 +18543,8 @@ function setup(env) {
|
||||
*/
|
||||
function disable() {
|
||||
const namespaces = [
|
||||
...createDebug.names.map(toNamespace),
|
||||
...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)
|
||||
...createDebug.names,
|
||||
...createDebug.skips.map(namespace => '-' + namespace)
|
||||
].join(',');
|
||||
createDebug.enable('');
|
||||
return namespaces;
|
||||
@@ -18478,21 +18558,14 @@ function setup(env) {
|
||||
* @api public
|
||||
*/
|
||||
function enabled(name) {
|
||||
if (name[name.length - 1] === '*') {
|
||||
return true;
|
||||
}
|
||||
|
||||
let i;
|
||||
let len;
|
||||
|
||||
for (i = 0, len = createDebug.skips.length; i < len; i++) {
|
||||
if (createDebug.skips[i].test(name)) {
|
||||
for (const skip of createDebug.skips) {
|
||||
if (matchesTemplate(name, skip)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0, len = createDebug.names.length; i < len; i++) {
|
||||
if (createDebug.names[i].test(name)) {
|
||||
for (const ns of createDebug.names) {
|
||||
if (matchesTemplate(name, ns)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -18500,19 +18573,6 @@ function setup(env) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert regexp to namespace
|
||||
*
|
||||
* @param {RegExp} regxep
|
||||
* @return {String} namespace
|
||||
* @api private
|
||||
*/
|
||||
function toNamespace(regexp) {
|
||||
return regexp.toString()
|
||||
.substring(2, regexp.toString().length - 2)
|
||||
.replace(/\.\*\?$/, '*');
|
||||
}
|
||||
|
||||
/**
|
||||
* Coerce `val`.
|
||||
*
|
||||
@@ -18754,11 +18814,11 @@ function getDate() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes `util.format()` with the specified arguments and writes to stderr.
|
||||
* Invokes `util.formatWithOptions()` with the specified arguments and writes to stderr.
|
||||
*/
|
||||
|
||||
function log(...args) {
|
||||
return process.stderr.write(util.format(...args) + '\n');
|
||||
return process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + '\n');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28277,8 +28337,6 @@ function defaultFactory (origin, opts) {
|
||||
|
||||
class Agent extends DispatcherBase {
|
||||
constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) {
|
||||
super()
|
||||
|
||||
if (typeof factory !== 'function') {
|
||||
throw new InvalidArgumentError('factory must be a function.')
|
||||
}
|
||||
@@ -28291,6 +28349,8 @@ class Agent extends DispatcherBase {
|
||||
throw new InvalidArgumentError('maxRedirections must be a positive number')
|
||||
}
|
||||
|
||||
super(options)
|
||||
|
||||
if (connect && typeof connect !== 'function') {
|
||||
connect = { ...connect }
|
||||
}
|
||||
@@ -28664,6 +28724,9 @@ const EMPTY_BUF = Buffer.alloc(0)
|
||||
const FastBuffer = Buffer[Symbol.species]
|
||||
const addListener = util.addListener
|
||||
const removeAllListeners = util.removeAllListeners
|
||||
const kIdleSocketValidation = Symbol('kIdleSocketValidation')
|
||||
const kIdleSocketValidationTimeout = Symbol('kIdleSocketValidationTimeout')
|
||||
const kSocketUsed = Symbol('kSocketUsed')
|
||||
|
||||
let extractBody
|
||||
|
||||
@@ -28886,15 +28949,60 @@ class Parser {
|
||||
|
||||
const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr
|
||||
|
||||
if (ret !== constants.ERROR.OK) {
|
||||
const body = data.subarray(offset)
|
||||
|
||||
if (ret === constants.ERROR.PAUSED_UPGRADE) {
|
||||
this.onUpgrade(data.slice(offset))
|
||||
this.onUpgrade(body)
|
||||
} else if (ret === constants.ERROR.PAUSED) {
|
||||
this.paused = true
|
||||
socket.unshift(data.slice(offset))
|
||||
} else if (ret !== constants.ERROR.OK) {
|
||||
socket.unshift(body)
|
||||
} else {
|
||||
throw this.createError(ret, body)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
util.destroy(socket, err)
|
||||
}
|
||||
}
|
||||
|
||||
finish () {
|
||||
assert(currentParser === null)
|
||||
assert(this.ptr != null)
|
||||
assert(!this.paused)
|
||||
|
||||
const { llhttp } = this
|
||||
|
||||
let ret
|
||||
|
||||
try {
|
||||
currentParser = this
|
||||
ret = llhttp.llhttp_finish(this.ptr)
|
||||
} finally {
|
||||
currentParser = null
|
||||
}
|
||||
|
||||
if (ret === constants.ERROR.OK) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (ret === constants.ERROR.PAUSED || ret === constants.ERROR.PAUSED_UPGRADE) {
|
||||
this.paused = true
|
||||
return null
|
||||
}
|
||||
|
||||
return this.createError(ret, EMPTY_BUF)
|
||||
}
|
||||
|
||||
createError (ret, data) {
|
||||
const { llhttp, contentLength, bytesRead } = this
|
||||
|
||||
if (contentLength && bytesRead !== parseInt(contentLength, 10)) {
|
||||
return new ResponseContentLengthMismatchError()
|
||||
}
|
||||
|
||||
const ptr = llhttp.llhttp_get_error_reason(this.ptr)
|
||||
let message = ''
|
||||
/* istanbul ignore else: difficult to make a test case for */
|
||||
if (ptr) {
|
||||
const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
|
||||
message =
|
||||
@@ -28902,11 +29010,8 @@ class Parser {
|
||||
Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
|
||||
')'
|
||||
}
|
||||
throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset))
|
||||
}
|
||||
} catch (err) {
|
||||
util.destroy(socket, err)
|
||||
}
|
||||
|
||||
return new HTTPParserError(message, constants.ERROR[ret], data)
|
||||
}
|
||||
|
||||
destroy () {
|
||||
@@ -28936,6 +29041,11 @@ class Parser {
|
||||
return -1
|
||||
}
|
||||
|
||||
if (client[kRunning] === 0) {
|
||||
util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket)))
|
||||
return -1
|
||||
}
|
||||
|
||||
const request = client[kQueue][client[kRunningIdx]]
|
||||
if (!request) {
|
||||
return -1
|
||||
@@ -29039,6 +29149,11 @@ class Parser {
|
||||
return -1
|
||||
}
|
||||
|
||||
if (client[kRunning] === 0) {
|
||||
util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket)))
|
||||
return -1
|
||||
}
|
||||
|
||||
const request = client[kQueue][client[kRunningIdx]]
|
||||
|
||||
/* istanbul ignore next: difficult to make a test case for */
|
||||
@@ -29212,6 +29327,7 @@ class Parser {
|
||||
request.onComplete(headers)
|
||||
|
||||
client[kQueue][client[kRunningIdx]++] = null
|
||||
socket[kSocketUsed] = true
|
||||
|
||||
if (socket[kWriting]) {
|
||||
assert(client[kRunning] === 0)
|
||||
@@ -29270,6 +29386,9 @@ async function connectH1 (client, socket) {
|
||||
socket[kWriting] = false
|
||||
socket[kReset] = false
|
||||
socket[kBlocking] = false
|
||||
socket[kIdleSocketValidation] = 0
|
||||
socket[kIdleSocketValidationTimeout] = null
|
||||
socket[kSocketUsed] = false
|
||||
socket[kParser] = new Parser(client, socket, llhttpInstance)
|
||||
|
||||
addListener(socket, 'error', function (err) {
|
||||
@@ -29280,8 +29399,11 @@ async function connectH1 (client, socket) {
|
||||
// On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
|
||||
// to the user.
|
||||
if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) {
|
||||
// We treat all incoming data so for as a valid response.
|
||||
parser.onMessageComplete()
|
||||
const parserErr = parser.finish()
|
||||
if (parserErr) {
|
||||
this[kError] = parserErr
|
||||
this[kClient][kOnError](parserErr)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -29300,8 +29422,10 @@ async function connectH1 (client, socket) {
|
||||
const parser = this[kParser]
|
||||
|
||||
if (parser.statusCode && !parser.shouldKeepAlive) {
|
||||
// We treat all incoming data so far as a valid response.
|
||||
parser.onMessageComplete()
|
||||
const parserErr = parser.finish()
|
||||
if (parserErr) {
|
||||
util.destroy(this, parserErr)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -29311,10 +29435,11 @@ async function connectH1 (client, socket) {
|
||||
const client = this[kClient]
|
||||
const parser = this[kParser]
|
||||
|
||||
clearIdleSocketValidation(this)
|
||||
|
||||
if (parser) {
|
||||
if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) {
|
||||
// We treat all incoming data so far as a valid response.
|
||||
parser.onMessageComplete()
|
||||
this[kError] = parser.finish() || this[kError]
|
||||
}
|
||||
|
||||
this[kParser].destroy()
|
||||
@@ -29377,7 +29502,7 @@ async function connectH1 (client, socket) {
|
||||
return socket.destroyed
|
||||
},
|
||||
busy (request) {
|
||||
if (socket[kWriting] || socket[kReset] || socket[kBlocking]) {
|
||||
if (socket[kWriting] || socket[kReset] || socket[kBlocking] || socket[kIdleSocketValidation] === 1) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -29415,6 +29540,31 @@ async function connectH1 (client, socket) {
|
||||
}
|
||||
}
|
||||
|
||||
function clearIdleSocketValidation (socket) {
|
||||
if (socket[kIdleSocketValidationTimeout]) {
|
||||
clearTimeout(socket[kIdleSocketValidationTimeout])
|
||||
socket[kIdleSocketValidationTimeout] = null
|
||||
}
|
||||
|
||||
socket[kIdleSocketValidation] = 0
|
||||
}
|
||||
|
||||
function scheduleIdleSocketValidation (client, socket) {
|
||||
socket[kIdleSocketValidation] = 1
|
||||
socket[kIdleSocketValidationTimeout] = setTimeout(() => {
|
||||
socket[kIdleSocketValidationTimeout] = null
|
||||
socket[kIdleSocketValidation] = 2
|
||||
|
||||
if (client[kSocket] === socket && !socket.destroyed) {
|
||||
client[kResume]()
|
||||
}
|
||||
}, 0)
|
||||
socket[kIdleSocketValidationTimeout].unref?.()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./client.js')} client
|
||||
*/
|
||||
function resumeH1 (client) {
|
||||
const socket = client[kSocket]
|
||||
|
||||
@@ -29429,6 +29579,32 @@ function resumeH1 (client) {
|
||||
socket[kNoRef] = false
|
||||
}
|
||||
|
||||
if (client[kRunning] === 0 && client[kPending] > 0 && socket[kSocketUsed]) {
|
||||
if (socket[kIdleSocketValidation] === 0) {
|
||||
scheduleIdleSocketValidation(client, socket)
|
||||
socket[kParser].readMore()
|
||||
if (socket.destroyed) {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (socket[kIdleSocketValidation] === 1) {
|
||||
socket[kParser].readMore()
|
||||
if (socket.destroyed) {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (client[kRunning] === 0) {
|
||||
socket[kParser].readMore()
|
||||
if (socket.destroyed) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (client[kSize] === 0) {
|
||||
if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) {
|
||||
socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE)
|
||||
@@ -29522,6 +29698,7 @@ function writeH1 (client, request) {
|
||||
}
|
||||
|
||||
const socket = client[kSocket]
|
||||
clearIdleSocketValidation(socket)
|
||||
|
||||
const abort = (err) => {
|
||||
if (request.aborted || request.completed) {
|
||||
@@ -30843,9 +31020,10 @@ class Client extends DispatcherBase {
|
||||
autoSelectFamilyAttemptTimeout,
|
||||
// h2
|
||||
maxConcurrentStreams,
|
||||
allowH2
|
||||
allowH2,
|
||||
webSocket
|
||||
} = {}) {
|
||||
super()
|
||||
super({ webSocket })
|
||||
|
||||
if (keepAlive !== undefined) {
|
||||
throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead')
|
||||
@@ -31378,15 +31556,24 @@ const { kDestroy, kClose, kClosed, kDestroyed, kDispatch, kInterceptors } = __nc
|
||||
const kOnDestroyed = Symbol('onDestroyed')
|
||||
const kOnClosed = Symbol('onClosed')
|
||||
const kInterceptedDispatch = Symbol('Intercepted Dispatch')
|
||||
const kWebSocketOptions = Symbol('webSocketOptions')
|
||||
|
||||
class DispatcherBase extends Dispatcher {
|
||||
constructor () {
|
||||
constructor (opts) {
|
||||
super()
|
||||
|
||||
this[kDestroyed] = false
|
||||
this[kOnDestroyed] = null
|
||||
this[kClosed] = false
|
||||
this[kOnClosed] = []
|
||||
this[kWebSocketOptions] = opts?.webSocket ?? {}
|
||||
}
|
||||
|
||||
get webSocketOptions () {
|
||||
return {
|
||||
maxFragments: this[kWebSocketOptions].maxFragments ?? 131072,
|
||||
maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024
|
||||
}
|
||||
}
|
||||
|
||||
get destroyed () {
|
||||
@@ -31950,8 +32137,8 @@ const kRemoveClient = Symbol('remove client')
|
||||
const kStats = Symbol('stats')
|
||||
|
||||
class PoolBase extends DispatcherBase {
|
||||
constructor () {
|
||||
super()
|
||||
constructor (opts) {
|
||||
super(opts)
|
||||
|
||||
this[kQueue] = new FixedQueue()
|
||||
this[kClients] = []
|
||||
@@ -32211,8 +32398,6 @@ class Pool extends PoolBase {
|
||||
allowH2,
|
||||
...options
|
||||
} = {}) {
|
||||
super()
|
||||
|
||||
if (connections != null && (!Number.isFinite(connections) || connections < 0)) {
|
||||
throw new InvalidArgumentError('invalid connections')
|
||||
}
|
||||
@@ -32237,6 +32422,8 @@ class Pool extends PoolBase {
|
||||
})
|
||||
}
|
||||
|
||||
super(options)
|
||||
|
||||
this[kInterceptors] = options.interceptors?.Pool && Array.isArray(options.interceptors.Pool)
|
||||
? options.interceptors.Pool
|
||||
: []
|
||||
@@ -37321,32 +37508,25 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
|
||||
// If the attribute-name case-insensitively matches the string
|
||||
// "SameSite", the user agent MUST process the cookie-av as follows:
|
||||
|
||||
// 1. Let enforcement be "Default".
|
||||
let enforcement = 'Default'
|
||||
|
||||
const attributeValueLowercase = attributeValue.toLowerCase()
|
||||
|
||||
// 1. If cookie-av's attribute-value is a case-insensitive match for
|
||||
// "None", append an attribute to the cookie-attribute-list with an
|
||||
// attribute-name of "SameSite" and an attribute-value of "None".
|
||||
if (attributeValueLowercase === 'none') {
|
||||
cookieAttributeList.sameSite = 'None'
|
||||
} else if (attributeValueLowercase === 'strict') {
|
||||
// 2. If cookie-av's attribute-value is a case-insensitive match for
|
||||
// "None", set enforcement to "None".
|
||||
if (attributeValueLowercase.includes('none')) {
|
||||
enforcement = 'None'
|
||||
}
|
||||
|
||||
// "Strict", append an attribute to the cookie-attribute-list with
|
||||
// an attribute-name of "SameSite" and an attribute-value of
|
||||
// "Strict".
|
||||
cookieAttributeList.sameSite = 'Strict'
|
||||
} else if (attributeValueLowercase === 'lax') {
|
||||
// 3. If cookie-av's attribute-value is a case-insensitive match for
|
||||
// "Strict", set enforcement to "Strict".
|
||||
if (attributeValueLowercase.includes('strict')) {
|
||||
enforcement = 'Strict'
|
||||
// "Lax", append an attribute to the cookie-attribute-list with an
|
||||
// attribute-name of "SameSite" and an attribute-value of "Lax".
|
||||
cookieAttributeList.sameSite = 'Lax'
|
||||
}
|
||||
|
||||
// 4. If cookie-av's attribute-value is a case-insensitive match for
|
||||
// "Lax", set enforcement to "Lax".
|
||||
if (attributeValueLowercase.includes('lax')) {
|
||||
enforcement = 'Lax'
|
||||
}
|
||||
|
||||
// 5. Append an attribute to the cookie-attribute-list with an
|
||||
// attribute-name of "SameSite" and an attribute-value of
|
||||
// enforcement.
|
||||
cookieAttributeList.sameSite = enforcement
|
||||
} else {
|
||||
cookieAttributeList.unparsed ??= []
|
||||
|
||||
@@ -50052,40 +50232,35 @@ const tail = Buffer.from([0x00, 0x00, 0xff, 0xff])
|
||||
const kBuffer = Symbol('kBuffer')
|
||||
const kLength = Symbol('kLength')
|
||||
|
||||
// Default maximum decompressed message size: 4 MB
|
||||
const kDefaultMaxDecompressedSize = 4 * 1024 * 1024
|
||||
|
||||
class PerMessageDeflate {
|
||||
/** @type {import('node:zlib').InflateRaw} */
|
||||
#inflate
|
||||
|
||||
#options = {}
|
||||
|
||||
/** @type {boolean} */
|
||||
#aborted = false
|
||||
|
||||
/** @type {Function|null} */
|
||||
#currentCallback = null
|
||||
#maxPayloadSize = 0
|
||||
|
||||
/**
|
||||
* @param {Map<string, string>} extensions
|
||||
*/
|
||||
constructor (extensions) {
|
||||
constructor (extensions, options) {
|
||||
this.#options.serverNoContextTakeover = extensions.has('server_no_context_takeover')
|
||||
this.#options.serverMaxWindowBits = extensions.get('server_max_window_bits')
|
||||
|
||||
this.#maxPayloadSize = options.maxPayloadSize
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress a compressed payload.
|
||||
* @param {Buffer} chunk Compressed data
|
||||
* @param {boolean} fin Final fragment flag
|
||||
* @param {Function} callback Callback function
|
||||
*/
|
||||
decompress (chunk, fin, callback) {
|
||||
// An endpoint uses the following algorithm to decompress a message.
|
||||
// 1. Append 4 octets of 0x00 0x00 0xff 0xff to the tail end of the
|
||||
// payload of the message.
|
||||
// 2. Decompress the resulting data using DEFLATE.
|
||||
|
||||
if (this.#aborted) {
|
||||
callback(new MessageSizeExceededError())
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.#inflate) {
|
||||
let windowBits = Z_DEFAULT_WINDOWBITS
|
||||
|
||||
@@ -50108,23 +50283,12 @@ class PerMessageDeflate {
|
||||
this.#inflate[kLength] = 0
|
||||
|
||||
this.#inflate.on('data', (data) => {
|
||||
if (this.#aborted) {
|
||||
return
|
||||
}
|
||||
|
||||
this.#inflate[kLength] += data.length
|
||||
|
||||
if (this.#inflate[kLength] > kDefaultMaxDecompressedSize) {
|
||||
this.#aborted = true
|
||||
if (this.#maxPayloadSize > 0 && this.#inflate[kLength] > this.#maxPayloadSize) {
|
||||
callback(new MessageSizeExceededError())
|
||||
this.#inflate.removeAllListeners()
|
||||
this.#inflate.destroy()
|
||||
this.#inflate = null
|
||||
|
||||
if (this.#currentCallback) {
|
||||
const cb = this.#currentCallback
|
||||
this.#currentCallback = null
|
||||
cb(new MessageSizeExceededError())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -50137,14 +50301,13 @@ class PerMessageDeflate {
|
||||
})
|
||||
}
|
||||
|
||||
this.#currentCallback = callback
|
||||
this.#inflate.write(chunk)
|
||||
if (fin) {
|
||||
this.#inflate.write(tail)
|
||||
}
|
||||
|
||||
this.#inflate.flush(() => {
|
||||
if (this.#aborted || !this.#inflate) {
|
||||
if (!this.#inflate) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -50152,7 +50315,6 @@ class PerMessageDeflate {
|
||||
|
||||
this.#inflate[kBuffer].length = 0
|
||||
this.#inflate[kLength] = 0
|
||||
this.#currentCallback = null
|
||||
|
||||
callback(null, full)
|
||||
})
|
||||
@@ -50188,6 +50350,12 @@ const {
|
||||
const { WebsocketFrameSend } = __nccwpck_require__(3264)
|
||||
const { closeWebSocketConnection } = __nccwpck_require__(86897)
|
||||
const { PerMessageDeflate } = __nccwpck_require__(19469)
|
||||
const { MessageSizeExceededError } = __nccwpck_require__(68707)
|
||||
|
||||
function failWebsocketConnectionWithCode (ws, code, reason) {
|
||||
closeWebSocketConnection(ws, code, reason, Buffer.byteLength(reason))
|
||||
failWebsocketConnection(ws, reason)
|
||||
}
|
||||
|
||||
// This code was influenced by ws released under the MIT license.
|
||||
// Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com>
|
||||
@@ -50196,6 +50364,7 @@ const { PerMessageDeflate } = __nccwpck_require__(19469)
|
||||
|
||||
class ByteParser extends Writable {
|
||||
#buffers = []
|
||||
#fragmentsBytes = 0
|
||||
#byteOffset = 0
|
||||
#loop = false
|
||||
|
||||
@@ -50207,18 +50376,27 @@ class ByteParser extends Writable {
|
||||
/** @type {Map<string, PerMessageDeflate>} */
|
||||
#extensions
|
||||
|
||||
/** @type {number} */
|
||||
#maxFragments
|
||||
|
||||
/** @type {number} */
|
||||
#maxPayloadSize
|
||||
|
||||
/**
|
||||
* @param {import('./websocket').WebSocket} ws
|
||||
* @param {Map<string, string>|null} extensions
|
||||
* @param {{ maxFragments?: number, maxPayloadSize?: number }} [options]
|
||||
*/
|
||||
constructor (ws, extensions) {
|
||||
constructor (ws, extensions, options = {}) {
|
||||
super()
|
||||
|
||||
this.ws = ws
|
||||
this.#extensions = extensions == null ? new Map() : extensions
|
||||
this.#maxFragments = options.maxFragments ?? 0
|
||||
this.#maxPayloadSize = options.maxPayloadSize ?? 0
|
||||
|
||||
if (this.#extensions.has('permessage-deflate')) {
|
||||
this.#extensions.set('permessage-deflate', new PerMessageDeflate(extensions))
|
||||
this.#extensions.set('permessage-deflate', new PerMessageDeflate(extensions, options))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50234,6 +50412,19 @@ class ByteParser extends Writable {
|
||||
this.run(callback)
|
||||
}
|
||||
|
||||
#validatePayloadLength () {
|
||||
if (
|
||||
this.#maxPayloadSize > 0 &&
|
||||
!isControlFrame(this.#info.opcode) &&
|
||||
this.#info.payloadLength + this.#fragmentsBytes > this.#maxPayloadSize
|
||||
) {
|
||||
failWebsocketConnectionWithCode(this.ws, 1009, 'Payload size exceeds maximum allowed size')
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs whenever a new chunk is received.
|
||||
* Callback is called whenever there are no more chunks buffering,
|
||||
@@ -50322,6 +50513,10 @@ class ByteParser extends Writable {
|
||||
if (payloadLength <= 125) {
|
||||
this.#info.payloadLength = payloadLength
|
||||
this.#state = parserStates.READ_DATA
|
||||
|
||||
if (!this.#validatePayloadLength()) {
|
||||
return
|
||||
}
|
||||
} else if (payloadLength === 126) {
|
||||
this.#state = parserStates.PAYLOADLENGTH_16
|
||||
} else if (payloadLength === 127) {
|
||||
@@ -50346,6 +50541,10 @@ class ByteParser extends Writable {
|
||||
|
||||
this.#info.payloadLength = buffer.readUInt16BE(0)
|
||||
this.#state = parserStates.READ_DATA
|
||||
|
||||
if (!this.#validatePayloadLength()) {
|
||||
return
|
||||
}
|
||||
} else if (this.#state === parserStates.PAYLOADLENGTH_64) {
|
||||
if (this.#byteOffset < 8) {
|
||||
return callback()
|
||||
@@ -50368,6 +50567,10 @@ class ByteParser extends Writable {
|
||||
|
||||
this.#info.payloadLength = lower
|
||||
this.#state = parserStates.READ_DATA
|
||||
|
||||
if (!this.#validatePayloadLength()) {
|
||||
return
|
||||
}
|
||||
} else if (this.#state === parserStates.READ_DATA) {
|
||||
if (this.#byteOffset < this.#info.payloadLength) {
|
||||
return callback()
|
||||
@@ -50380,27 +50583,43 @@ class ByteParser extends Writable {
|
||||
this.#state = parserStates.INFO
|
||||
} else {
|
||||
if (!this.#info.compressed) {
|
||||
this.#fragments.push(body)
|
||||
if (!this.writeFragments(body)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
|
||||
failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message)
|
||||
return
|
||||
}
|
||||
|
||||
// If the frame is not fragmented, a message has been received.
|
||||
// If the frame is fragmented, it will terminate with a fin bit set
|
||||
// and an opcode of 0 (continuation), therefore we handle that when
|
||||
// parsing continuation frames, not here.
|
||||
if (!this.#info.fragmented && this.#info.fin) {
|
||||
const fullMessage = Buffer.concat(this.#fragments)
|
||||
websocketMessageReceived(this.ws, this.#info.binaryType, fullMessage)
|
||||
this.#fragments.length = 0
|
||||
websocketMessageReceived(this.ws, this.#info.binaryType, this.consumeFragments())
|
||||
}
|
||||
|
||||
this.#state = parserStates.INFO
|
||||
} else {
|
||||
this.#extensions.get('permessage-deflate').decompress(body, this.#info.fin, (error, data) => {
|
||||
this.#extensions.get('permessage-deflate').decompress(
|
||||
body,
|
||||
this.#info.fin,
|
||||
(error, data) => {
|
||||
if (error) {
|
||||
failWebsocketConnection(this.ws, error.message)
|
||||
const code = error instanceof MessageSizeExceededError ? 1009 : 1007
|
||||
failWebsocketConnectionWithCode(this.ws, code, error.message)
|
||||
return
|
||||
}
|
||||
|
||||
this.#fragments.push(data)
|
||||
if (!this.writeFragments(data)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
|
||||
failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message)
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.#info.fin) {
|
||||
this.#state = parserStates.INFO
|
||||
@@ -50409,13 +50628,13 @@ class ByteParser extends Writable {
|
||||
return
|
||||
}
|
||||
|
||||
websocketMessageReceived(this.ws, this.#info.binaryType, Buffer.concat(this.#fragments))
|
||||
websocketMessageReceived(this.ws, this.#info.binaryType, this.consumeFragments())
|
||||
|
||||
this.#loop = true
|
||||
this.#state = parserStates.INFO
|
||||
this.#fragments.length = 0
|
||||
this.run(callback)
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
this.#loop = false
|
||||
break
|
||||
@@ -50467,6 +50686,35 @@ class ByteParser extends Writable {
|
||||
return buffer
|
||||
}
|
||||
|
||||
writeFragments (fragment) {
|
||||
if (
|
||||
this.#maxFragments > 0 &&
|
||||
this.#fragments.length === this.#maxFragments
|
||||
) {
|
||||
failWebsocketConnectionWithCode(this.ws, 1008, 'Too many message fragments')
|
||||
return false
|
||||
}
|
||||
|
||||
this.#fragmentsBytes += fragment.length
|
||||
this.#fragments.push(fragment)
|
||||
return true
|
||||
}
|
||||
|
||||
consumeFragments () {
|
||||
const fragments = this.#fragments
|
||||
|
||||
if (fragments.length === 1) {
|
||||
this.#fragmentsBytes = 0
|
||||
return fragments.shift()
|
||||
}
|
||||
|
||||
const output = Buffer.concat(fragments, this.#fragmentsBytes)
|
||||
this.#fragments = []
|
||||
this.#fragmentsBytes = 0
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
parseCloseBody (data) {
|
||||
assert(data.length !== 1)
|
||||
|
||||
@@ -51502,7 +51750,14 @@ class WebSocket extends EventTarget {
|
||||
// once this happens, the connection is open
|
||||
this[kResponse] = response
|
||||
|
||||
const parser = new ByteParser(this, parsedExtensions)
|
||||
const webSocketOptions = this[kController]?.dispatcher?.webSocketOptions
|
||||
const maxFragments = webSocketOptions?.maxFragments
|
||||
const maxPayloadSize = webSocketOptions?.maxPayloadSize
|
||||
|
||||
const parser = new ByteParser(this, parsedExtensions, {
|
||||
maxFragments,
|
||||
maxPayloadSize
|
||||
})
|
||||
parser.on('drain', onParserDrain)
|
||||
parser.on('error', onParserError.bind(this))
|
||||
|
||||
@@ -51713,9 +51968,12 @@ const CACHE_KEY_PREFIX = 'setup-java';
|
||||
const supportedPackageManager = [
|
||||
{
|
||||
id: 'maven',
|
||||
path: [(0, path_1.join)(os_1.default.homedir(), '.m2', 'repository')],
|
||||
path: [
|
||||
(0, path_1.join)(os_1.default.homedir(), '.m2', 'repository'),
|
||||
(0, path_1.join)(os_1.default.homedir(), '.m2', 'wrapper', 'dists')
|
||||
],
|
||||
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---maven
|
||||
pattern: ['**/pom.xml']
|
||||
pattern: ['**/pom.xml', '**/.mvn/wrapper/maven-wrapper.properties']
|
||||
},
|
||||
{
|
||||
id: 'gradle',
|
||||
@@ -51828,7 +52086,15 @@ function save(id) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
yield cache.saveCache(packageManager.path, primaryKey);
|
||||
const cacheId = yield cache.saveCache(packageManager.path, primaryKey);
|
||||
if (cacheId === -1) {
|
||||
// saveCache returns -1 without throwing when the cache was not saved,
|
||||
// e.g. a reserve collision or a read-only token (fork PR). @actions/cache
|
||||
// has already logged the reason at the appropriate severity, so just
|
||||
// trace it instead of misreporting that the cache was saved.
|
||||
core.debug(`Cache was not saved for the key: ${primaryKey}`);
|
||||
return;
|
||||
}
|
||||
core.info(`Cache saved with the key: ${primaryKey}`);
|
||||
}
|
||||
catch (error) {
|
||||
@@ -52187,6 +52453,13 @@ function getDownloadArchiveExtension() {
|
||||
exports.getDownloadArchiveExtension = getDownloadArchiveExtension;
|
||||
function isVersionSatisfies(range, version) {
|
||||
var _a;
|
||||
// Some distributions (e.g. JetBrains Runtime) publish 4-segment versions
|
||||
// like '17.0.8.1+1080.1' that semver rejects. If the candidate version
|
||||
// isn't valid semver, it can't match — bail out rather than letting
|
||||
// compareBuild / satisfies throw.
|
||||
if (!semver.valid(version)) {
|
||||
return false;
|
||||
}
|
||||
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
|
||||
@@ -93780,7 +94053,7 @@ function randomUUID() {
|
||||
/***/ ((module) => {
|
||||
|
||||
"use strict";
|
||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"5.0.5","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^2.0.0","@actions/exec":"^2.0.0","@actions/glob":"^0.5.1","@protobuf-ts/runtime-rpc":"^2.11.1","@actions/http-client":"^3.0.2","@actions/io":"^2.0.0","@azure/abort-controller":"^1.1.0","@azure/core-rest-pipeline":"^1.22.0","@azure/storage-blob":"^12.29.1","semver":"^6.3.1"},"devDependencies":{"@types/node":"^24.1.0","@types/semver":"^6.0.0","@protobuf-ts/plugin":"^2.9.4","typescript":"^5.2.2"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}');
|
||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"5.1.0","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^2.0.0","@actions/exec":"^2.0.0","@actions/glob":"^0.5.1","@protobuf-ts/runtime-rpc":"^2.11.1","@actions/http-client":"^3.0.2","@actions/io":"^2.0.0","@azure/abort-controller":"^1.1.0","@azure/core-rest-pipeline":"^1.22.0","@azure/storage-blob":"^12.29.1","semver":"^6.3.1"},"devDependencies":{"@types/node":"^24.1.0","@types/semver":"^6.0.0","@protobuf-ts/plugin":"^2.9.4","typescript":"^5.2.2"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}');
|
||||
|
||||
/***/ })
|
||||
|
||||
|
||||
Vendored
+533
-155
File diff suppressed because it is too large
Load Diff
@@ -34,7 +34,7 @@ Requiring a default version will break users that are pinned to `@main` as they
|
||||
|
||||
`setup-java` should be structured in such a way that will allow the open source community to easily add support for extra distributions.
|
||||
|
||||
Existing code will be restructured so that distribution specific code will be easily separated. Currently the core download logic is in a single file, `installer.ts`. This file will be split up and abstracted out so that there will be no vendor specified logic. Each distribution will have it's own files under `src/distributions` that will contain the core setup logic for a specific distribution.
|
||||
Existing code will be restructured so that distribution specific code will be easily separated. Currently the core download logic is in a single file, `installer.ts`. This file will be split up and abstracted out so that there will be no vendor specified logic. Each distribution will have its own files under `src/distributions` that will contain the core setup logic for a specific distribution.
|
||||
|
||||
```yaml
|
||||
∟ src/
|
||||
|
||||
+1
-1
@@ -16,4 +16,4 @@ This folder includes ADRs for the setup-java action. ADRs are proposed in the fo
|
||||
|
||||
---
|
||||
|
||||
- More information about ADRs can be found [here](https://github.com/joelparkerhenderson/architecture_decision_record).
|
||||
- See [more information about ADRs](https://github.com/joelparkerhenderson/architecture_decision_record).
|
||||
+17
-1
@@ -10,6 +10,7 @@
|
||||
- [Alibaba Dragonwell](#Alibaba-Dragonwell)
|
||||
- [SapMachine](#SapMachine)
|
||||
- [GraalVM](#GraalVM)
|
||||
- [GraalVM Community](#GraalVM-Community)
|
||||
- [JetBrains](#JetBrains)
|
||||
- [Installing custom Java package type](#Installing-custom-Java-package-type)
|
||||
- [Installing custom Java architecture](#Installing-custom-Java-architecture)
|
||||
@@ -172,11 +173,26 @@ steps:
|
||||
native-image -cp java HelloWorldApp
|
||||
```
|
||||
|
||||
### GraalVM Community
|
||||
**NOTE:** GraalVM Community is available for stable JDK 17 and later releases.
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'graalvm-community'
|
||||
java-version: '21'
|
||||
- run: |
|
||||
java -cp java HelloWorldApp
|
||||
native-image -cp java HelloWorldApp
|
||||
```
|
||||
|
||||
### JetBrains
|
||||
|
||||
**NOTE:** JetBrains is only available for LTS versions on 11 or later (11, 17, 21, etc.).
|
||||
|
||||
Not all minor LTS versions are guarenteed to be available, since JetBrains considers what to ship IntelliJ IDEA with, most commonly on JDK 11.
|
||||
Not all minor LTS versions are guaranteed to be available, since JetBrains considers what to ship IntelliJ IDEA with, most commonly on JDK 11.
|
||||
For example, `11.0.24` is not available but `11.0.16` is.
|
||||
|
||||
```yaml
|
||||
|
||||
Generated
+202
-30
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "setup-java",
|
||||
"version": "5.2.0",
|
||||
"version": "5.3.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "setup-java",
|
||||
"version": "5.2.0",
|
||||
"version": "5.3.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/cache": "^5.0.5",
|
||||
"@actions/cache": "^5.1.0",
|
||||
"@actions/core": "^2.0.3",
|
||||
"@actions/exec": "^2.0.0",
|
||||
"@actions/glob": "^0.5.1",
|
||||
@@ -24,7 +24,7 @@
|
||||
"@types/node": "^25.9.3",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@typescript-eslint/eslint-plugin": "^8.48.0",
|
||||
"@typescript-eslint/parser": "^8.35.1",
|
||||
"@typescript-eslint/parser": "^8.61.1",
|
||||
"@vercel/ncc": "^0.44.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
@@ -50,9 +50,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/cache": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.0.5.tgz",
|
||||
"integrity": "sha512-jiQSg0gfd+C2KPgcmdCOq7dCuCIQQWQ4b1YfGIRaaA9w7PJbRwTOcCz4LiFEUnqZGf0ha/8OKL3BeNwetHzYsQ==",
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.1.0.tgz",
|
||||
"integrity": "sha512-kTIj4YPrjjRPKSGlj7f8eq+Pijoy/SKBEbJcAwNsQTFGEF29NGqj1mqD02/PmhV6r4bRAixycexAWpmUJ2aCwg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^2.0.0",
|
||||
@@ -2072,17 +2072,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "8.48.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.48.0.tgz",
|
||||
"integrity": "sha512-jCzKdm/QK0Kg4V4IK/oMlRZlY+QOcdjv89U2NgKHZk1CYTj82/RVSx1mV/0gqCVMJ/DA+Zf/S4NBWNF8GQ+eqQ==",
|
||||
"version": "8.61.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.61.1.tgz",
|
||||
"integrity": "sha512-PJ5vePq5/ognBbrIcoC5+SHO5dfpeLPzP9FpLkzWrguoYQEeeSjlJpVwOpo1JRSTEi7dRcwNy4h4dzV70PqHcg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.48.0",
|
||||
"@typescript-eslint/types": "8.48.0",
|
||||
"@typescript-eslint/typescript-estree": "8.48.0",
|
||||
"@typescript-eslint/visitor-keys": "8.48.0",
|
||||
"debug": "^4.3.4"
|
||||
"@typescript-eslint/scope-manager": "8.61.1",
|
||||
"@typescript-eslint/types": "8.61.1",
|
||||
"@typescript-eslint/typescript-estree": "8.61.1",
|
||||
"@typescript-eslint/visitor-keys": "8.61.1",
|
||||
"debug": "^4.4.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
@@ -2092,8 +2092,177 @@
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^8.57.0 || ^9.0.0",
|
||||
"typescript": ">=4.8.4 <6.0.0"
|
||||
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
||||
"typescript": ">=4.8.4 <6.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": {
|
||||
"version": "8.61.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.61.1.tgz",
|
||||
"integrity": "sha512-PrC4JYGmR241lYnfhmKGTXkFqv8+ymbTFgSAY0fVXpY82/QkMw5TZPl+vGzuDDU2QYJk9fIDOBTntF+yDv9LEA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/tsconfig-utils": "^8.61.1",
|
||||
"@typescript-eslint/types": "^8.61.1",
|
||||
"debug": "^4.4.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.8.4 <6.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "8.61.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.61.1.tgz",
|
||||
"integrity": "sha512-L2bdIeoQS8FlKAvONAr20w6OcLXeB+qiDKbAooS9A0Ben+iSIkBef0FxqwKWYqt5sa0i4KJtxVyVmhMylKzF5w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.61.1",
|
||||
"@typescript-eslint/visitor-keys": "8.61.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": {
|
||||
"version": "8.61.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.61.1.tgz",
|
||||
"integrity": "sha512-UN/H4di+OO7EWx2ovME+8t31YO+KVnK0RRKEHR3kOt21/Ay8BOq3M1OMvWs5vNiqcFCYGYoxK3MXPZzmMUE+yg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.8.4 <6.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": {
|
||||
"version": "8.61.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.61.1.tgz",
|
||||
"integrity": "sha512-G+CRlPqLv7Bz1IZVs03x5K59F1veqL0EJUROAdGhKsEq8qOiRiZbI+HUojPq5l0fEGOKModD9br6lObhB8zkoA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "8.61.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.61.1.tgz",
|
||||
"integrity": "sha512-u+oQD3BqYWPc8YV9Zab4vaJElJuwOLPRc10Jm1o/qS+6Qwen14HCWwx0Seo4LnSn2wxea2Ik8DxPt2/FHmuhrg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/project-service": "8.61.1",
|
||||
"@typescript-eslint/tsconfig-utils": "8.61.1",
|
||||
"@typescript-eslint/types": "8.61.1",
|
||||
"@typescript-eslint/visitor-keys": "8.61.1",
|
||||
"debug": "^4.4.3",
|
||||
"minimatch": "^10.2.2",
|
||||
"semver": "^7.7.3",
|
||||
"tinyglobby": "^0.2.15",
|
||||
"ts-api-utils": "^2.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.8.4 <6.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "8.61.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.61.1.tgz",
|
||||
"integrity": "sha512-6fJ9MHWtK14C1DSkiMlHUSOmrVebL7150xZJBlJiL62jjhIA4JmOq6flwBgDxIdBKKdoiZRel+dfPD5MLfny3w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.61.1",
|
||||
"eslint-visitor-keys": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/balanced-match": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
|
||||
"integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/brace-expansion": {
|
||||
"version": "5.0.6",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
|
||||
"integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz",
|
||||
"integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.13.0 || >=24"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser/node_modules/minimatch": {
|
||||
"version": "10.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
|
||||
"integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^5.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/project-service": {
|
||||
@@ -3131,11 +3300,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
@@ -5165,9 +5335,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/napi-postinstall": {
|
||||
"version": "0.3.4",
|
||||
@@ -6095,10 +6266,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ts-api-utils": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
||||
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz",
|
||||
"integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.12"
|
||||
},
|
||||
@@ -6247,9 +6419,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz",
|
||||
"integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==",
|
||||
"version": "6.27.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz",
|
||||
"integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.17"
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "setup-java",
|
||||
"version": "5.2.0",
|
||||
"version": "5.3.0",
|
||||
"private": true,
|
||||
"description": "setup java action",
|
||||
"main": "dist/setup/index.js",
|
||||
@@ -29,7 +29,7 @@
|
||||
"author": "GitHub",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/cache": "^5.0.5",
|
||||
"@actions/cache": "^5.1.0",
|
||||
"@actions/core": "^2.0.3",
|
||||
"@actions/exec": "^2.0.0",
|
||||
"@actions/glob": "^0.5.1",
|
||||
@@ -44,7 +44,7 @@
|
||||
"@types/node": "^25.9.3",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@typescript-eslint/eslint-plugin": "^8.48.0",
|
||||
"@typescript-eslint/parser": "^8.35.1",
|
||||
"@typescript-eslint/parser": "^8.61.1",
|
||||
"@vercel/ncc": "^0.44.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
|
||||
+14
-3
@@ -23,9 +23,12 @@ interface PackageManager {
|
||||
const supportedPackageManager: PackageManager[] = [
|
||||
{
|
||||
id: 'maven',
|
||||
path: [join(os.homedir(), '.m2', 'repository')],
|
||||
path: [
|
||||
join(os.homedir(), '.m2', 'repository'),
|
||||
join(os.homedir(), '.m2', 'wrapper', 'dists')
|
||||
],
|
||||
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---maven
|
||||
pattern: ['**/pom.xml']
|
||||
pattern: ['**/pom.xml', '**/.mvn/wrapper/maven-wrapper.properties']
|
||||
},
|
||||
{
|
||||
id: 'gradle',
|
||||
@@ -146,7 +149,15 @@ export async function save(id: string) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await cache.saveCache(packageManager.path, primaryKey);
|
||||
const cacheId = await cache.saveCache(packageManager.path, primaryKey);
|
||||
if (cacheId === -1) {
|
||||
// saveCache returns -1 without throwing when the cache was not saved,
|
||||
// e.g. a reserve collision or a read-only token (fork PR). @actions/cache
|
||||
// has already logged the reason at the appropriate severity, so just
|
||||
// trace it instead of misreporting that the cache was saved.
|
||||
core.debug(`Cache was not saved for the key: ${primaryKey}`);
|
||||
return;
|
||||
}
|
||||
core.info(`Cache saved with the key: ${primaryKey}`);
|
||||
} catch (error) {
|
||||
const err = error as Error;
|
||||
|
||||
@@ -11,7 +11,10 @@ import {CorrettoDistribution} from './corretto/installer';
|
||||
import {OracleDistribution} from './oracle/installer';
|
||||
import {DragonwellDistribution} from './dragonwell/installer';
|
||||
import {SapMachineDistribution} from './sapmachine/installer';
|
||||
import {GraalVMDistribution} from './graalvm/installer';
|
||||
import {
|
||||
GraalVMCommunityDistribution,
|
||||
GraalVMDistribution
|
||||
} from './graalvm/installer';
|
||||
import {JetBrainsDistribution} from './jetbrains/installer';
|
||||
|
||||
enum JavaDistribution {
|
||||
@@ -29,6 +32,7 @@ enum JavaDistribution {
|
||||
Dragonwell = 'dragonwell',
|
||||
SapMachine = 'sapmachine',
|
||||
GraalVM = 'graalvm',
|
||||
GraalVMCommunity = 'graalvm-community',
|
||||
JetBrains = 'jetbrains'
|
||||
}
|
||||
|
||||
@@ -74,6 +78,8 @@ export function getJavaDistribution(
|
||||
return new SapMachineDistribution(installerOptions);
|
||||
case JavaDistribution.GraalVM:
|
||||
return new GraalVMDistribution(installerOptions);
|
||||
case JavaDistribution.GraalVMCommunity:
|
||||
return new GraalVMCommunityDistribution(installerOptions);
|
||||
case JavaDistribution.JetBrains:
|
||||
return new JetBrainsDistribution(installerOptions);
|
||||
default:
|
||||
|
||||
@@ -2,6 +2,7 @@ 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 {HttpCodes} from '@actions/http-client';
|
||||
import {GraalVMEAVersion} from './models';
|
||||
@@ -11,14 +12,24 @@ import {
|
||||
JavaInstallerResults
|
||||
} from '../base-models';
|
||||
import {
|
||||
convertVersionToSemver,
|
||||
extractJdkFile,
|
||||
getDownloadArchiveExtension,
|
||||
getGitHubHttpHeaders,
|
||||
renameWinArchive
|
||||
getNextPageUrlFromLinkHeader,
|
||||
isVersionSatisfies,
|
||||
MAX_PAGINATION_PAGES,
|
||||
renameWinArchive,
|
||||
validatePaginationUrl
|
||||
} from '../../util';
|
||||
|
||||
const GRAALVM_DL_BASE = 'https://download.oracle.com/graalvm';
|
||||
const GRAALVM_DOWNLOAD_URL = 'https://www.graalvm.org/downloads/';
|
||||
const GRAALVM_COMMUNITY_RELEASES_URL =
|
||||
'https://api.github.com/repos/graalvm/graalvm-ce-builds/releases?per_page=100';
|
||||
const GRAALVM_COMMUNITY_RELEASES_PAGE_ORIGIN = 'https://api.github.com';
|
||||
const GRAALVM_COMMUNITY_DOWNLOAD_URL =
|
||||
'https://github.com/graalvm/graalvm-ce-builds/releases';
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
const GRAALVM_PLATFORM = IS_WINDOWS ? 'windows' : process.platform;
|
||||
const GRAALVM_MIN_VERSION = 17;
|
||||
@@ -26,9 +37,23 @@ const SUPPORTED_ARCHITECTURES = ['x64', 'aarch64'] as const;
|
||||
type SupportedArchitecture = (typeof SUPPORTED_ARCHITECTURES)[number];
|
||||
type OsVersions = 'linux' | 'macos' | 'windows';
|
||||
|
||||
interface GraalVMCommunityAsset {
|
||||
name: string;
|
||||
browser_download_url: string;
|
||||
}
|
||||
|
||||
interface GraalVMCommunityRelease {
|
||||
draft: boolean;
|
||||
prerelease: boolean;
|
||||
assets: GraalVMCommunityAsset[];
|
||||
}
|
||||
|
||||
export class GraalVMDistribution extends JavaBase {
|
||||
constructor(installerOptions: JavaInstallerOptions) {
|
||||
super('GraalVM', installerOptions);
|
||||
constructor(
|
||||
installerOptions: JavaInstallerOptions,
|
||||
distributionName = 'GraalVM'
|
||||
) {
|
||||
super(distributionName, installerOptions);
|
||||
}
|
||||
|
||||
protected async downloadTool(
|
||||
@@ -85,40 +110,14 @@ export class GraalVMDistribution extends JavaBase {
|
||||
protected async findPackageForDownload(
|
||||
range: string
|
||||
): Promise<JavaDownloadRelease> {
|
||||
// Add input validation
|
||||
if (!range || typeof range !== 'string') {
|
||||
throw new Error('Version range is required and must be a string');
|
||||
}
|
||||
|
||||
const arch = this.distributionArchitecture();
|
||||
if (!SUPPORTED_ARCHITECTURES.includes(arch as SupportedArchitecture)) {
|
||||
throw new Error(
|
||||
`Unsupported architecture: ${this.architecture}. Supported architectures are: ${SUPPORTED_ARCHITECTURES.join(', ')}`
|
||||
);
|
||||
}
|
||||
this.validateVersionRange(range);
|
||||
const arch = this.getSupportedArchitecture();
|
||||
|
||||
if (!this.stable) {
|
||||
return this.findEABuildDownloadUrl(`${range}-ea`);
|
||||
}
|
||||
|
||||
if (this.packageType !== 'jdk') {
|
||||
throw new Error('GraalVM provides only the `jdk` package type');
|
||||
}
|
||||
|
||||
const platform = this.getPlatform();
|
||||
const extension = getDownloadArchiveExtension();
|
||||
const major = range.includes('.') ? range.split('.')[0] : range;
|
||||
const majorVersion = parseInt(major);
|
||||
|
||||
if (isNaN(majorVersion)) {
|
||||
throw new Error(`Invalid version format: ${range}`);
|
||||
}
|
||||
|
||||
if (majorVersion < GRAALVM_MIN_VERSION) {
|
||||
throw new Error(
|
||||
`GraalVM is only supported for JDK ${GRAALVM_MIN_VERSION} and later. Requested version: ${major}`
|
||||
);
|
||||
}
|
||||
const {platform, extension, major} = this.validateStableBuildRequest(range);
|
||||
|
||||
const fileUrl = this.constructFileUrl(
|
||||
range,
|
||||
@@ -134,6 +133,56 @@ export class GraalVMDistribution extends JavaBase {
|
||||
return {url: fileUrl, version: range};
|
||||
}
|
||||
|
||||
protected validateVersionRange(range: string): void {
|
||||
if (!range || typeof range !== 'string') {
|
||||
throw new Error('Version range is required and must be a string');
|
||||
}
|
||||
}
|
||||
|
||||
protected getSupportedArchitecture(): SupportedArchitecture {
|
||||
const arch = this.distributionArchitecture();
|
||||
if (!SUPPORTED_ARCHITECTURES.includes(arch as SupportedArchitecture)) {
|
||||
throw new Error(
|
||||
`Unsupported architecture: ${this.architecture}. Supported architectures are: ${SUPPORTED_ARCHITECTURES.join(', ')}`
|
||||
);
|
||||
}
|
||||
|
||||
return arch as SupportedArchitecture;
|
||||
}
|
||||
|
||||
protected validateStableBuildRequest(range: string): {
|
||||
platform: OsVersions;
|
||||
extension: string;
|
||||
major: string;
|
||||
} {
|
||||
if (this.packageType !== 'jdk') {
|
||||
throw new Error(
|
||||
`${this.distribution} provides only the \`jdk\` package type`
|
||||
);
|
||||
}
|
||||
|
||||
const platform = this.getPlatform();
|
||||
const extension = getDownloadArchiveExtension();
|
||||
const major = range.includes('.') ? range.split('.')[0] : range;
|
||||
const majorVersion = parseInt(major);
|
||||
|
||||
if (isNaN(majorVersion)) {
|
||||
throw new Error(`Invalid version format: ${range}`);
|
||||
}
|
||||
|
||||
if (majorVersion < GRAALVM_MIN_VERSION) {
|
||||
throw new Error(
|
||||
`${this.distribution} is only supported for JDK ${GRAALVM_MIN_VERSION} and later. Requested version: ${major}`
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
platform,
|
||||
major,
|
||||
extension
|
||||
};
|
||||
}
|
||||
|
||||
private constructFileUrl(
|
||||
range: string,
|
||||
major: string,
|
||||
@@ -280,3 +329,143 @@ export class GraalVMDistribution extends JavaBase {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export class GraalVMCommunityDistribution extends GraalVMDistribution {
|
||||
constructor(installerOptions: JavaInstallerOptions) {
|
||||
super(installerOptions, 'GraalVM Community');
|
||||
}
|
||||
|
||||
protected get toolcacheFolderName(): string {
|
||||
return `Java_GraalVM_Community_${this.packageType}`;
|
||||
}
|
||||
|
||||
protected async findPackageForDownload(
|
||||
range: string
|
||||
): Promise<JavaDownloadRelease> {
|
||||
this.validateVersionRange(range);
|
||||
|
||||
if (!this.stable) {
|
||||
throw new Error('GraalVM Community does not provide early access builds');
|
||||
}
|
||||
|
||||
const arch = this.getSupportedArchitecture();
|
||||
const {platform, extension} = this.validateStableBuildRequest(range);
|
||||
const availableVersions = await this.getAvailableVersionsForPlatform(
|
||||
platform,
|
||||
arch,
|
||||
extension
|
||||
);
|
||||
|
||||
const satisfiedVersion = availableVersions
|
||||
.filter(item => isVersionSatisfies(range, item.version))
|
||||
.sort((a, b) => -semver.compareBuild(a.version, b.version))[0];
|
||||
|
||||
if (!satisfiedVersion) {
|
||||
const error = this.createVersionNotFoundError(
|
||||
range,
|
||||
availableVersions.map(item => item.version),
|
||||
`Platform: ${platform}`
|
||||
);
|
||||
error.message += `\nPlease check if this version is available at ${GRAALVM_COMMUNITY_DOWNLOAD_URL}.`;
|
||||
throw error;
|
||||
}
|
||||
|
||||
return satisfiedVersion;
|
||||
}
|
||||
|
||||
private async getAvailableVersionsForPlatform(
|
||||
platform: OsVersions,
|
||||
arch: SupportedArchitecture,
|
||||
extension: string
|
||||
): Promise<JavaDownloadRelease[]> {
|
||||
const headers = getGitHubHttpHeaders();
|
||||
const availableVersions = new Map<string, JavaDownloadRelease>();
|
||||
let releasesUrl: string | null = GRAALVM_COMMUNITY_RELEASES_URL;
|
||||
let pageCount = 0;
|
||||
|
||||
while (releasesUrl) {
|
||||
pageCount++;
|
||||
const response = await this.http.getJson<GraalVMCommunityRelease[]>(
|
||||
releasesUrl,
|
||||
headers
|
||||
);
|
||||
|
||||
const releases = Array.isArray(response.result) ? response.result : [];
|
||||
|
||||
for (const release of releases) {
|
||||
if (release.draft || release.prerelease) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const asset of release.assets ?? []) {
|
||||
const releaseForPlatform = this.toCommunityReleaseForPlatform(
|
||||
asset,
|
||||
platform,
|
||||
arch,
|
||||
extension
|
||||
);
|
||||
if (releaseForPlatform) {
|
||||
availableVersions.set(
|
||||
releaseForPlatform.version,
|
||||
releaseForPlatform
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const nextUrl = getNextPageUrlFromLinkHeader(response.headers);
|
||||
if (
|
||||
nextUrl &&
|
||||
!validatePaginationUrl(nextUrl, GRAALVM_COMMUNITY_RELEASES_PAGE_ORIGIN)
|
||||
) {
|
||||
core.warning(
|
||||
`Ignoring pagination link with unexpected origin: ${nextUrl}`
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
releasesUrl = nextUrl;
|
||||
|
||||
if (releases.length === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (pageCount >= MAX_PAGINATION_PAGES) {
|
||||
core.warning(
|
||||
`Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing GraalVM Community releases.`
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [...availableVersions.values()];
|
||||
}
|
||||
|
||||
private toCommunityReleaseForPlatform(
|
||||
asset: GraalVMCommunityAsset,
|
||||
platform: OsVersions,
|
||||
arch: SupportedArchitecture,
|
||||
extension: string
|
||||
): JavaDownloadRelease | null {
|
||||
const match = asset.name.match(
|
||||
/^graalvm-community-jdk-(?<version>\d+(?:\.\d+)+)_(?<platform>linux|macos|windows)-(?<arch>x64|aarch64)_bin\.(?<extension>tar\.gz|zip)$/
|
||||
);
|
||||
|
||||
if (!match?.groups) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (
|
||||
match.groups.platform !== platform ||
|
||||
match.groups.arch !== arch ||
|
||||
match.groups.extension !== extension
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
version: convertVersionToSemver(match.groups.version),
|
||||
url: asset.browser_download_url
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,6 +171,49 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "17.0.18",
|
||||
"stable": true,
|
||||
"release_url": "https://aka.ms/download-jdk",
|
||||
"files": [
|
||||
{
|
||||
"filename": "microsoft-jdk-17.0.18-macos-x64.tar.gz",
|
||||
"arch": "x64",
|
||||
"platform": "darwin",
|
||||
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-17.0.18-macos-x64.tar.gz"
|
||||
},
|
||||
{
|
||||
"filename": "microsoft-jdk-17.0.18-linux-x64.tar.gz",
|
||||
"arch": "x64",
|
||||
"platform": "linux",
|
||||
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-17.0.18-linux-x64.tar.gz"
|
||||
},
|
||||
{
|
||||
"filename": "microsoft-jdk-17.0.18-windows-x64.zip",
|
||||
"arch": "x64",
|
||||
"platform": "win32",
|
||||
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-17.0.18-windows-x64.zip"
|
||||
},
|
||||
{
|
||||
"filename": "microsoft-jdk-17.0.18-macos-aarch64.tar.gz",
|
||||
"arch": "aarch64",
|
||||
"platform": "darwin",
|
||||
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-17.0.18-macos-aarch64.tar.gz"
|
||||
},
|
||||
{
|
||||
"filename": "microsoft-jdk-17.0.18-linux-aarch64.tar.gz",
|
||||
"arch": "aarch64",
|
||||
"platform": "linux",
|
||||
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-17.0.18-linux-aarch64.tar.gz"
|
||||
},
|
||||
{
|
||||
"filename": "microsoft-jdk-17.0.18-windows-aarch64.zip",
|
||||
"arch": "aarch64",
|
||||
"platform": "win32",
|
||||
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-17.0.18-windows-aarch64.zip"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "17.0.10",
|
||||
"stable": true,
|
||||
@@ -180,7 +223,7 @@
|
||||
"filename": "microsoft-jdk-17.0.10-macos-x64.tar.gz",
|
||||
"arch": "x64",
|
||||
"platform": "darwin",
|
||||
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-17.0.7-macos-x64.tar.gz"
|
||||
"download_url": "https://aka.ms/download-jdk/microsoft-jdk-17.0.10-macos-x64.tar.gz"
|
||||
},
|
||||
{
|
||||
"filename": "microsoft-jdk-17.0.10-linux-x64.tar.gz",
|
||||
|
||||
@@ -55,6 +55,14 @@ export function getDownloadArchiveExtension() {
|
||||
}
|
||||
|
||||
export function isVersionSatisfies(range: string, version: string): boolean {
|
||||
// Some distributions (e.g. JetBrains Runtime) publish 4-segment versions
|
||||
// like '17.0.8.1+1080.1' that semver rejects. If the candidate version
|
||||
// isn't valid semver, it can't match — bail out rather than letting
|
||||
// compareBuild / satisfies throw.
|
||||
if (!semver.valid(version)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user