mirror of
https://github.com/actions/setup-java.git
synced 2026-06-29 16:42:36 +00:00
Compare commits
1 Commits
198dbd0311
...
ff6bc27707
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff6bc27707 |
4
.github/workflows/codeql-analysis.yml
vendored
4
.github/workflows/codeql-analysis.yml
vendored
@ -10,9 +10,5 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
call-codeQL-analysis:
|
call-codeQL-analysis:
|
||||||
permissions:
|
|
||||||
actions: read
|
|
||||||
contents: read
|
|
||||||
security-events: write
|
|
||||||
name: CodeQL analysis
|
name: CodeQL analysis
|
||||||
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
|
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
|
||||||
|
|||||||
BIN
.licenses/npm/debug.dep.yml
generated
BIN
.licenses/npm/debug.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/ms.dep.yml
generated
BIN
.licenses/npm/ms.dep.yml
generated
Binary file not shown.
@ -4,7 +4,6 @@ import {
|
|||||||
AdoptDistribution,
|
AdoptDistribution,
|
||||||
AdoptImplementation
|
AdoptImplementation
|
||||||
} from '../../src/distributions/adopt/installer';
|
} from '../../src/distributions/adopt/installer';
|
||||||
import {TemurinDistribution} from '../../src/distributions/temurin/installer';
|
|
||||||
import {JavaInstallerOptions} from '../../src/distributions/base-models';
|
import {JavaInstallerOptions} from '../../src/distributions/base-models';
|
||||||
|
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
@ -15,7 +14,6 @@ import * as core from '@actions/core';
|
|||||||
describe('getAvailableVersions', () => {
|
describe('getAvailableVersions', () => {
|
||||||
let spyHttpClient: jest.SpyInstance;
|
let spyHttpClient: jest.SpyInstance;
|
||||||
let spyCoreError: jest.SpyInstance;
|
let spyCoreError: jest.SpyInstance;
|
||||||
let spyCoreWarning: jest.SpyInstance;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
|
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
|
||||||
@ -28,8 +26,6 @@ describe('getAvailableVersions', () => {
|
|||||||
// Mock core.error to suppress error logs
|
// Mock core.error to suppress error logs
|
||||||
spyCoreError = jest.spyOn(core, 'error');
|
spyCoreError = jest.spyOn(core, 'error');
|
||||||
spyCoreError.mockImplementation(() => {});
|
spyCoreError.mockImplementation(() => {});
|
||||||
spyCoreWarning = jest.spyOn(core, 'warning');
|
|
||||||
spyCoreWarning.mockImplementation(() => {});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@ -140,19 +136,22 @@ describe('getAvailableVersions', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
it('load available versions', async () => {
|
it('load available versions', async () => {
|
||||||
const nextPageUrl =
|
|
||||||
'https://api.adoptopenjdk.net/v3/assets/version/%5B1.0,100.0%5D?page=1&page_size=20';
|
|
||||||
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
|
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
|
||||||
spyHttpClient
|
spyHttpClient
|
||||||
.mockReturnValueOnce({
|
.mockReturnValueOnce({
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
headers: {link: `<${nextPageUrl}>; rel="next"`},
|
headers: {},
|
||||||
result: manifestData as any
|
result: manifestData as any
|
||||||
})
|
})
|
||||||
.mockReturnValueOnce({
|
.mockReturnValueOnce({
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
headers: {},
|
headers: {},
|
||||||
result: manifestData as any
|
result: manifestData as any
|
||||||
|
})
|
||||||
|
.mockReturnValueOnce({
|
||||||
|
statusCode: 200,
|
||||||
|
headers: {},
|
||||||
|
result: []
|
||||||
});
|
});
|
||||||
|
|
||||||
const distribution = new AdoptDistribution(
|
const distribution = new AdoptDistribution(
|
||||||
@ -167,34 +166,6 @@ describe('getAvailableVersions', () => {
|
|||||||
const availableVersions = await distribution['getAvailableVersions']();
|
const availableVersions = await distribution['getAvailableVersions']();
|
||||||
expect(availableVersions).not.toBeNull();
|
expect(availableVersions).not.toBeNull();
|
||||||
expect(availableVersions.length).toBe(manifestData.length * 2);
|
expect(availableVersions.length).toBe(manifestData.length * 2);
|
||||||
expect(spyHttpClient).toHaveBeenNthCalledWith(2, nextPageUrl);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('stops pagination after 1000 pages as a safeguard', async () => {
|
|
||||||
const nextPageUrl =
|
|
||||||
'https://api.adoptopenjdk.net/v3/assets/version/%5B1.0,100.0%5D?page=2&page_size=20';
|
|
||||||
spyHttpClient.mockReturnValue({
|
|
||||||
statusCode: 200,
|
|
||||||
headers: {link: `<${nextPageUrl}>; rel="next"`},
|
|
||||||
result: [{version_data: {semver: '17.0.1'}, binaries: []}] as any
|
|
||||||
});
|
|
||||||
|
|
||||||
const distribution = new AdoptDistribution(
|
|
||||||
{
|
|
||||||
version: '11',
|
|
||||||
architecture: 'x64',
|
|
||||||
packageType: 'jdk',
|
|
||||||
checkLatest: false
|
|
||||||
},
|
|
||||||
AdoptImplementation.Hotspot
|
|
||||||
);
|
|
||||||
|
|
||||||
await distribution['getAvailableVersions']();
|
|
||||||
|
|
||||||
expect(spyHttpClient).toHaveBeenCalledTimes(1000);
|
|
||||||
expect(spyCoreWarning).toHaveBeenCalledWith(
|
|
||||||
expect.stringContaining('Reached pagination safeguard limit (1000 pages)')
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
@ -257,38 +228,6 @@ describe('getAvailableVersions', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('findPackageForDownload', () => {
|
describe('findPackageForDownload', () => {
|
||||||
it('returns Temurin result and does not query Adopt API when Temurin succeeds', async () => {
|
|
||||||
const temurinRelease = {
|
|
||||||
version: '11.0.31+11',
|
|
||||||
url: 'https://example.test/temurin-11.tar.gz'
|
|
||||||
};
|
|
||||||
const temurinFindPackageForDownload = jest
|
|
||||||
.fn()
|
|
||||||
.mockResolvedValue(temurinRelease);
|
|
||||||
const temurinDistribution = {
|
|
||||||
findPackageForDownload: temurinFindPackageForDownload
|
|
||||||
} as unknown as TemurinDistribution;
|
|
||||||
|
|
||||||
const distribution = new AdoptDistribution(
|
|
||||||
{
|
|
||||||
version: '11',
|
|
||||||
architecture: 'x64',
|
|
||||||
packageType: 'jdk',
|
|
||||||
checkLatest: false
|
|
||||||
},
|
|
||||||
AdoptImplementation.Hotspot,
|
|
||||||
temurinDistribution
|
|
||||||
);
|
|
||||||
const adoptLookupSpy = jest.fn();
|
|
||||||
distribution['getAvailableVersions'] = adoptLookupSpy;
|
|
||||||
|
|
||||||
const resolvedVersion = await distribution['findPackageForDownload']('11');
|
|
||||||
|
|
||||||
expect(resolvedVersion).toEqual(temurinRelease);
|
|
||||||
expect(temurinFindPackageForDownload).toHaveBeenCalledWith('11');
|
|
||||||
expect(adoptLookupSpy).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
['9', '9.0.7+10'],
|
['9', '9.0.7+10'],
|
||||||
['15', '15.0.2+7'],
|
['15', '15.0.2+7'],
|
||||||
@ -311,11 +250,6 @@ describe('findPackageForDownload', () => {
|
|||||||
},
|
},
|
||||||
AdoptImplementation.Hotspot
|
AdoptImplementation.Hotspot
|
||||||
);
|
);
|
||||||
// Mock Temurin to fail so fallback to AdoptOpenJDK is tested
|
|
||||||
distribution['temurinDistribution']!['findPackageForDownload'] =
|
|
||||||
async () => {
|
|
||||||
throw new Error('No matching version found for SemVer');
|
|
||||||
};
|
|
||||||
distribution['getAvailableVersions'] = async () => manifestData as any;
|
distribution['getAvailableVersions'] = async () => manifestData as any;
|
||||||
const resolvedVersion = await distribution['findPackageForDownload'](input);
|
const resolvedVersion = await distribution['findPackageForDownload'](input);
|
||||||
expect(resolvedVersion.version).toBe(expected);
|
expect(resolvedVersion.version).toBe(expected);
|
||||||
@ -331,11 +265,6 @@ describe('findPackageForDownload', () => {
|
|||||||
},
|
},
|
||||||
AdoptImplementation.Hotspot
|
AdoptImplementation.Hotspot
|
||||||
);
|
);
|
||||||
// Mock Temurin to fail so fallback to AdoptOpenJDK is tested
|
|
||||||
distribution['temurinDistribution']!['findPackageForDownload'] =
|
|
||||||
async () => {
|
|
||||||
throw new Error('No matching version found for SemVer');
|
|
||||||
};
|
|
||||||
distribution['getAvailableVersions'] = async () => manifestData as any;
|
distribution['getAvailableVersions'] = async () => manifestData as any;
|
||||||
await expect(
|
await expect(
|
||||||
distribution['findPackageForDownload']('9.0.8')
|
distribution['findPackageForDownload']('9.0.8')
|
||||||
@ -352,11 +281,6 @@ describe('findPackageForDownload', () => {
|
|||||||
},
|
},
|
||||||
AdoptImplementation.Hotspot
|
AdoptImplementation.Hotspot
|
||||||
);
|
);
|
||||||
// Mock Temurin to fail so fallback to AdoptOpenJDK is tested
|
|
||||||
distribution['temurinDistribution']!['findPackageForDownload'] =
|
|
||||||
async () => {
|
|
||||||
throw new Error('No matching version found for SemVer');
|
|
||||||
};
|
|
||||||
distribution['getAvailableVersions'] = async () => manifestData as any;
|
distribution['getAvailableVersions'] = async () => manifestData as any;
|
||||||
await expect(distribution['findPackageForDownload']('7.x')).rejects.toThrow(
|
await expect(distribution['findPackageForDownload']('7.x')).rejects.toThrow(
|
||||||
/No matching version found for SemVer */
|
/No matching version found for SemVer */
|
||||||
@ -373,11 +297,6 @@ describe('findPackageForDownload', () => {
|
|||||||
},
|
},
|
||||||
AdoptImplementation.Hotspot
|
AdoptImplementation.Hotspot
|
||||||
);
|
);
|
||||||
// Mock Temurin to fail so fallback to AdoptOpenJDK is tested
|
|
||||||
distribution['temurinDistribution']!['findPackageForDownload'] =
|
|
||||||
async () => {
|
|
||||||
throw new Error('No matching version found for SemVer');
|
|
||||||
};
|
|
||||||
distribution['getAvailableVersions'] = async () => [];
|
distribution['getAvailableVersions'] = async () => [];
|
||||||
await expect(distribution['findPackageForDownload']('11')).rejects.toThrow(
|
await expect(distribution['findPackageForDownload']('11')).rejects.toThrow(
|
||||||
/No matching version found for SemVer */
|
/No matching version found for SemVer */
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import * as core from '@actions/core';
|
|||||||
describe('getAvailableVersions', () => {
|
describe('getAvailableVersions', () => {
|
||||||
let spyHttpClient: jest.SpyInstance;
|
let spyHttpClient: jest.SpyInstance;
|
||||||
let spyCoreError: jest.SpyInstance;
|
let spyCoreError: jest.SpyInstance;
|
||||||
let spyCoreWarning: jest.SpyInstance;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
|
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
|
||||||
@ -21,8 +20,6 @@ describe('getAvailableVersions', () => {
|
|||||||
// Mock core.error to suppress error logs
|
// Mock core.error to suppress error logs
|
||||||
spyCoreError = jest.spyOn(core, 'error');
|
spyCoreError = jest.spyOn(core, 'error');
|
||||||
spyCoreError.mockImplementation(() => {});
|
spyCoreError.mockImplementation(() => {});
|
||||||
spyCoreWarning = jest.spyOn(core, 'warning');
|
|
||||||
spyCoreWarning.mockImplementation(() => {});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@ -85,19 +82,22 @@ describe('getAvailableVersions', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
it('load available versions', async () => {
|
it('load available versions', async () => {
|
||||||
const nextPageUrl =
|
|
||||||
'https://api.adoptopenjdk.net/v3/assets/version/%5B1.0,100.0%5D?page=1&page_size=20';
|
|
||||||
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
|
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
|
||||||
spyHttpClient
|
spyHttpClient
|
||||||
.mockReturnValueOnce({
|
.mockReturnValueOnce({
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
headers: {link: `<${nextPageUrl}>; rel="next"`},
|
headers: {},
|
||||||
result: manifestData as any
|
result: manifestData as any
|
||||||
})
|
})
|
||||||
.mockReturnValueOnce({
|
.mockReturnValueOnce({
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
headers: {},
|
headers: {},
|
||||||
result: manifestData as any
|
result: manifestData as any
|
||||||
|
})
|
||||||
|
.mockReturnValueOnce({
|
||||||
|
statusCode: 200,
|
||||||
|
headers: {},
|
||||||
|
result: []
|
||||||
});
|
});
|
||||||
|
|
||||||
const distribution = new SemeruDistribution({
|
const distribution = new SemeruDistribution({
|
||||||
@ -109,31 +109,6 @@ describe('getAvailableVersions', () => {
|
|||||||
const availableVersions = await distribution['getAvailableVersions']();
|
const availableVersions = await distribution['getAvailableVersions']();
|
||||||
expect(availableVersions).not.toBeNull();
|
expect(availableVersions).not.toBeNull();
|
||||||
expect(availableVersions.length).toBe(manifestData.length * 2);
|
expect(availableVersions.length).toBe(manifestData.length * 2);
|
||||||
expect(spyHttpClient).toHaveBeenNthCalledWith(2, nextPageUrl);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('stops pagination after 1000 pages as a safeguard', async () => {
|
|
||||||
const nextPageUrl =
|
|
||||||
'https://api.adoptopenjdk.net/v3/assets/version/%5B1.0,100.0%5D?page=2&page_size=20';
|
|
||||||
spyHttpClient.mockReturnValue({
|
|
||||||
statusCode: 200,
|
|
||||||
headers: {link: `<${nextPageUrl}>; rel="next"`},
|
|
||||||
result: [{version_data: {semver: '17.0.1'}, binaries: []}] as any
|
|
||||||
});
|
|
||||||
|
|
||||||
const distribution = new SemeruDistribution({
|
|
||||||
version: '8',
|
|
||||||
architecture: 'x64',
|
|
||||||
packageType: 'jdk',
|
|
||||||
checkLatest: false
|
|
||||||
});
|
|
||||||
|
|
||||||
await distribution['getAvailableVersions']();
|
|
||||||
|
|
||||||
expect(spyHttpClient).toHaveBeenCalledTimes(1000);
|
|
||||||
expect(spyCoreWarning).toHaveBeenCalledWith(
|
|
||||||
expect.stringContaining('Reached pagination safeguard limit (1000 pages)')
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
|
|||||||
@ -12,7 +12,6 @@ import * as core from '@actions/core';
|
|||||||
describe('getAvailableVersions', () => {
|
describe('getAvailableVersions', () => {
|
||||||
let spyHttpClient: jest.SpyInstance;
|
let spyHttpClient: jest.SpyInstance;
|
||||||
let spyCoreError: jest.SpyInstance;
|
let spyCoreError: jest.SpyInstance;
|
||||||
let spyCoreWarning: jest.SpyInstance;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
|
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
|
||||||
@ -24,8 +23,6 @@ describe('getAvailableVersions', () => {
|
|||||||
// Mock core.error to suppress error logs
|
// Mock core.error to suppress error logs
|
||||||
spyCoreError = jest.spyOn(core, 'error');
|
spyCoreError = jest.spyOn(core, 'error');
|
||||||
spyCoreError.mockImplementation(() => {});
|
spyCoreError.mockImplementation(() => {});
|
||||||
spyCoreWarning = jest.spyOn(core, 'warning');
|
|
||||||
spyCoreWarning.mockImplementation(() => {});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@ -96,19 +93,22 @@ describe('getAvailableVersions', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
it('load available versions', async () => {
|
it('load available versions', async () => {
|
||||||
const nextPageUrl =
|
|
||||||
'https://api.adoptium.net/v3/assets/version/%5B1.0,100.0%5D?page=1&page_size=20';
|
|
||||||
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
|
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
|
||||||
spyHttpClient
|
spyHttpClient
|
||||||
.mockReturnValueOnce({
|
.mockReturnValueOnce({
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
headers: {link: `<${nextPageUrl}>; rel="next"`},
|
headers: {},
|
||||||
result: manifestData as any
|
result: manifestData as any
|
||||||
})
|
})
|
||||||
.mockReturnValueOnce({
|
.mockReturnValueOnce({
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
headers: {},
|
headers: {},
|
||||||
result: manifestData as any
|
result: manifestData as any
|
||||||
|
})
|
||||||
|
.mockReturnValueOnce({
|
||||||
|
statusCode: 200,
|
||||||
|
headers: {},
|
||||||
|
result: []
|
||||||
});
|
});
|
||||||
|
|
||||||
const distribution = new TemurinDistribution(
|
const distribution = new TemurinDistribution(
|
||||||
@ -123,34 +123,6 @@ describe('getAvailableVersions', () => {
|
|||||||
const availableVersions = await distribution['getAvailableVersions']();
|
const availableVersions = await distribution['getAvailableVersions']();
|
||||||
expect(availableVersions).not.toBeNull();
|
expect(availableVersions).not.toBeNull();
|
||||||
expect(availableVersions.length).toBe(manifestData.length * 2);
|
expect(availableVersions.length).toBe(manifestData.length * 2);
|
||||||
expect(spyHttpClient).toHaveBeenNthCalledWith(2, nextPageUrl);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('stops pagination after 1000 pages as a safeguard', async () => {
|
|
||||||
const nextPageUrl =
|
|
||||||
'https://api.adoptium.net/v3/assets/version/%5B1.0,100.0%5D?page=2&page_size=20';
|
|
||||||
spyHttpClient.mockReturnValue({
|
|
||||||
statusCode: 200,
|
|
||||||
headers: {link: `<${nextPageUrl}>; rel="next"`},
|
|
||||||
result: [{version_data: {semver: '17.0.1'}, binaries: []}] as any
|
|
||||||
});
|
|
||||||
|
|
||||||
const distribution = new TemurinDistribution(
|
|
||||||
{
|
|
||||||
version: '8',
|
|
||||||
architecture: 'x64',
|
|
||||||
packageType: 'jdk',
|
|
||||||
checkLatest: false
|
|
||||||
},
|
|
||||||
TemurinImplementation.Hotspot
|
|
||||||
);
|
|
||||||
|
|
||||||
await distribution['getAvailableVersions']();
|
|
||||||
|
|
||||||
expect(spyHttpClient).toHaveBeenCalledTimes(1000);
|
|
||||||
expect(spyCoreWarning).toHaveBeenCalledWith(
|
|
||||||
expect.stringContaining('Reached pagination safeguard limit (1000 pages)')
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
|
|||||||
@ -4,12 +4,10 @@ import * as fs from 'fs';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import {
|
import {
|
||||||
convertVersionToSemver,
|
convertVersionToSemver,
|
||||||
getNextPageUrlFromLinkHeader,
|
|
||||||
getVersionFromFileContent,
|
getVersionFromFileContent,
|
||||||
isVersionSatisfies,
|
isVersionSatisfies,
|
||||||
isCacheFeatureAvailable,
|
isCacheFeatureAvailable,
|
||||||
isGhes,
|
isGhes
|
||||||
validatePaginationUrl
|
|
||||||
} from '../src/util';
|
} from '../src/util';
|
||||||
|
|
||||||
jest.mock('@actions/cache');
|
jest.mock('@actions/cache');
|
||||||
@ -29,11 +27,7 @@ describe('isVersionSatisfies', () => {
|
|||||||
['2.5.1+3', '2.5.1+3', true],
|
['2.5.1+3', '2.5.1+3', true],
|
||||||
['2.5.1+3', '2.5.1+2', false],
|
['2.5.1+3', '2.5.1+2', false],
|
||||||
['15.0.0+14', '15.0.0+14.1.202003190635', 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',
|
'%s, %s -> %s',
|
||||||
(inputRange: string, inputVersion: string, expected: boolean) => {
|
(inputRange: string, inputVersion: string, expected: boolean) => {
|
||||||
@ -91,78 +85,6 @@ describe('convertVersionToSemver', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getNextPageUrlFromLinkHeader', () => {
|
|
||||||
it.each([
|
|
||||||
[
|
|
||||||
{
|
|
||||||
link: '<https://api.adoptium.net/v3/info/release_versions?page=1&page_size=10>; rel="next"'
|
|
||||||
},
|
|
||||||
'https://api.adoptium.net/v3/info/release_versions?page=1&page_size=10'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
Link: '<https://example.com/last?page=5>; rel="last", <https://example.com/next?page=2>; rel="next"'
|
|
||||||
},
|
|
||||||
'https://example.com/next?page=2'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
link: '<https://api.adoptium.net/v3/versions?page=3>; type="application/json"; rel="next"'
|
|
||||||
},
|
|
||||||
'https://api.adoptium.net/v3/versions?page=3'
|
|
||||||
],
|
|
||||||
[{link: '<https://example.com/last?page=5>; rel="last"'}, null],
|
|
||||||
[{link: '<https://example.com/page?p=2>; rel="nextsomething"'}, null],
|
|
||||||
[undefined, null]
|
|
||||||
])('returns %s -> %s', (headers, expected) => {
|
|
||||||
expect(getNextPageUrlFromLinkHeader(headers)).toBe(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('validatePaginationUrl', () => {
|
|
||||||
it('accepts URL with matching origin', () => {
|
|
||||||
expect(
|
|
||||||
validatePaginationUrl(
|
|
||||||
'https://api.adoptium.net/v3/assets?page=2',
|
|
||||||
'https://api.adoptium.net'
|
|
||||||
)
|
|
||||||
).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('rejects URL with different host', () => {
|
|
||||||
expect(
|
|
||||||
validatePaginationUrl(
|
|
||||||
'https://evil.example.com/steal?data=1',
|
|
||||||
'https://api.adoptium.net'
|
|
||||||
)
|
|
||||||
).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('rejects URL with different protocol', () => {
|
|
||||||
expect(
|
|
||||||
validatePaginationUrl(
|
|
||||||
'http://api.adoptium.net/v3/assets?page=2',
|
|
||||||
'https://api.adoptium.net'
|
|
||||||
)
|
|
||||||
).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns false for invalid URL', () => {
|
|
||||||
expect(validatePaginationUrl('not-a-url', 'https://api.adoptium.net')).toBe(
|
|
||||||
false
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('accepts URL with explicit default port', () => {
|
|
||||||
expect(
|
|
||||||
validatePaginationUrl(
|
|
||||||
'https://api.adoptium.net:443/v3/assets?page=2',
|
|
||||||
'https://api.adoptium.net'
|
|
||||||
)
|
|
||||||
).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getVersionFromFileContent', () => {
|
describe('getVersionFromFileContent', () => {
|
||||||
describe('.sdkmanrc', () => {
|
describe('.sdkmanrc', () => {
|
||||||
it.each([
|
it.each([
|
||||||
|
|||||||
4487
dist/cleanup/index.js
vendored
4487
dist/cleanup/index.js
vendored
File diff suppressed because one or more lines are too long
6309
dist/setup/index.js
vendored
6309
dist/setup/index.js
vendored
File diff suppressed because one or more lines are too long
223
package-lock.json
generated
223
package-lock.json
generated
@ -24,8 +24,8 @@
|
|||||||
"@types/node": "^25.9.3",
|
"@types/node": "^25.9.3",
|
||||||
"@types/semver": "^7.5.8",
|
"@types/semver": "^7.5.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.48.0",
|
"@typescript-eslint/eslint-plugin": "^8.48.0",
|
||||||
"@typescript-eslint/parser": "^8.61.1",
|
"@typescript-eslint/parser": "^8.35.1",
|
||||||
"@vercel/ncc": "^0.44.0",
|
"@vercel/ncc": "^0.38.1",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-jest": "^29.0.1",
|
"eslint-plugin-jest": "^29.0.1",
|
||||||
@ -2072,17 +2072,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/parser": {
|
"node_modules/@typescript-eslint/parser": {
|
||||||
"version": "8.61.1",
|
"version": "8.48.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.61.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.48.0.tgz",
|
||||||
"integrity": "sha512-PJ5vePq5/ognBbrIcoC5+SHO5dfpeLPzP9FpLkzWrguoYQEeeSjlJpVwOpo1JRSTEi7dRcwNy4h4dzV70PqHcg==",
|
"integrity": "sha512-jCzKdm/QK0Kg4V4IK/oMlRZlY+QOcdjv89U2NgKHZk1CYTj82/RVSx1mV/0gqCVMJ/DA+Zf/S4NBWNF8GQ+eqQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "8.61.1",
|
"@typescript-eslint/scope-manager": "8.48.0",
|
||||||
"@typescript-eslint/types": "8.61.1",
|
"@typescript-eslint/types": "8.48.0",
|
||||||
"@typescript-eslint/typescript-estree": "8.61.1",
|
"@typescript-eslint/typescript-estree": "8.48.0",
|
||||||
"@typescript-eslint/visitor-keys": "8.61.1",
|
"@typescript-eslint/visitor-keys": "8.48.0",
|
||||||
"debug": "^4.4.3"
|
"debug": "^4.3.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@ -2092,177 +2092,8 @@
|
|||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
"eslint": "^8.57.0 || ^9.0.0",
|
||||||
"typescript": ">=4.8.4 <6.1.0"
|
"typescript": ">=4.8.4 <6.0.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": {
|
"node_modules/@typescript-eslint/project-service": {
|
||||||
@ -2805,11 +2636,10 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@vercel/ncc": {
|
"node_modules/@vercel/ncc": {
|
||||||
"version": "0.44.0",
|
"version": "0.38.1",
|
||||||
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.44.0.tgz",
|
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.38.1.tgz",
|
||||||
"integrity": "sha512-pHyI+bZokSgIscTKFSmpNk5vZzmOrb9RW0Vu4SRyqUvkJ0kgg3PzaZLLDVTFXhbUiCqg0/Eu8L4fKtgViA92kg==",
|
"integrity": "sha512-IBBb+iI2NLu4VQn3Vwldyi2QwaXt5+hTyh58ggAMoCGE6DJmPvwL3KPBWcJl1m9LYPChBLE980Jw+CS4Wokqxw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"ncc": "dist/ncc/cli.js"
|
"ncc": "dist/ncc/cli.js"
|
||||||
}
|
}
|
||||||
@ -3300,12 +3130,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.4.3",
|
"version": "4.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "^2.1.3"
|
"ms": "2.1.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0"
|
"node": ">=6.0"
|
||||||
@ -5335,10 +5164,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
"license": "MIT"
|
|
||||||
},
|
},
|
||||||
"node_modules/napi-postinstall": {
|
"node_modules/napi-postinstall": {
|
||||||
"version": "0.3.4",
|
"version": "0.3.4",
|
||||||
@ -6266,11 +6094,10 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/ts-api-utils": {
|
"node_modules/ts-api-utils": {
|
||||||
"version": "2.5.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
||||||
"integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==",
|
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.12"
|
"node": ">=18.12"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -44,8 +44,8 @@
|
|||||||
"@types/node": "^25.9.3",
|
"@types/node": "^25.9.3",
|
||||||
"@types/semver": "^7.5.8",
|
"@types/semver": "^7.5.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.48.0",
|
"@typescript-eslint/eslint-plugin": "^8.48.0",
|
||||||
"@typescript-eslint/parser": "^8.61.1",
|
"@typescript-eslint/parser": "^8.35.1",
|
||||||
"@vercel/ncc": "^0.44.0",
|
"@vercel/ncc": "^0.38.1",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-jest": "^29.0.1",
|
"eslint-plugin-jest": "^29.0.1",
|
||||||
|
|||||||
@ -14,14 +14,10 @@ import {
|
|||||||
} from '../base-models';
|
} from '../base-models';
|
||||||
import {
|
import {
|
||||||
extractJdkFile,
|
extractJdkFile,
|
||||||
getNextPageUrlFromLinkHeader,
|
|
||||||
getDownloadArchiveExtension,
|
getDownloadArchiveExtension,
|
||||||
isVersionSatisfies,
|
isVersionSatisfies,
|
||||||
renameWinArchive,
|
renameWinArchive
|
||||||
MAX_PAGINATION_PAGES,
|
|
||||||
validatePaginationUrl
|
|
||||||
} from '../../util';
|
} from '../../util';
|
||||||
import {TemurinDistribution, TemurinImplementation} from '../temurin/installer';
|
|
||||||
|
|
||||||
export enum AdoptImplementation {
|
export enum AdoptImplementation {
|
||||||
Hotspot = 'Hotspot',
|
Hotspot = 'Hotspot',
|
||||||
@ -29,72 +25,15 @@ export enum AdoptImplementation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class AdoptDistribution extends JavaBase {
|
export class AdoptDistribution extends JavaBase {
|
||||||
private readonly temurinDistribution: TemurinDistribution | null;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
installerOptions: JavaInstallerOptions,
|
installerOptions: JavaInstallerOptions,
|
||||||
private readonly jvmImpl: AdoptImplementation,
|
private readonly jvmImpl: AdoptImplementation
|
||||||
temurinDistribution: TemurinDistribution | null = null
|
|
||||||
) {
|
) {
|
||||||
super(`Adopt-${jvmImpl}`, installerOptions);
|
super(`Adopt-${jvmImpl}`, installerOptions);
|
||||||
|
|
||||||
if (
|
|
||||||
temurinDistribution !== null &&
|
|
||||||
jvmImpl !== AdoptImplementation.Hotspot
|
|
||||||
) {
|
|
||||||
throw new Error('Only Hotspot JVM is supported by Temurin.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only use the temurin repo for Hotspot JVMs
|
|
||||||
this.temurinDistribution =
|
|
||||||
temurinDistribution ??
|
|
||||||
(jvmImpl === AdoptImplementation.Hotspot
|
|
||||||
? new TemurinDistribution(
|
|
||||||
installerOptions,
|
|
||||||
TemurinImplementation.Hotspot
|
|
||||||
)
|
|
||||||
: null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async findPackageForDownload(
|
protected async findPackageForDownload(
|
||||||
version: string
|
version: string
|
||||||
): Promise<JavaDownloadRelease> {
|
|
||||||
if (this.jvmImpl === AdoptImplementation.Hotspot) {
|
|
||||||
core.notice(
|
|
||||||
"AdoptOpenJDK has moved to Eclipse Temurin https://github.com/actions/setup-java#supported-distributions please consider changing to the 'temurin' distribution type in your setup-java configuration."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
this.jvmImpl === AdoptImplementation.Hotspot &&
|
|
||||||
this.temurinDistribution !== null
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
return await this.temurinDistribution.findPackageForDownload(version);
|
|
||||||
} catch (error) {
|
|
||||||
// Log the failure but always fall back to legacy AdoptOpenJDK for resilience
|
|
||||||
const errorMessage =
|
|
||||||
error instanceof Error ? error.message : String(error);
|
|
||||||
if (error instanceof Error && error.name === 'VersionNotFoundError') {
|
|
||||||
core.notice(
|
|
||||||
'The JVM you are looking for could not be found in the Temurin repository, this likely indicates ' +
|
|
||||||
'that you are using an out of date version of Java, consider updating and moving to using the Temurin distribution type in setup-java.'
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// Log other errors for debugging but gracefully fall back
|
|
||||||
core.debug(
|
|
||||||
`Temurin lookup failed: ${errorMessage}. Falling back to AdoptOpenJDK API.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// failed to find a Temurin version, so fall back to AdoptOpenJDK
|
|
||||||
return this.findPackageForDownloadOldAdoptOpenJdk(version);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async findPackageForDownloadOldAdoptOpenJdk(
|
|
||||||
version: string
|
|
||||||
): Promise<JavaDownloadRelease> {
|
): Promise<JavaDownloadRelease> {
|
||||||
const availableVersionsRaw = await this.getAvailableVersions();
|
const availableVersionsRaw = await this.getAvailableVersions();
|
||||||
const availableVersionsWithBinaries = availableVersionsRaw
|
const availableVersionsWithBinaries = availableVersionsRaw
|
||||||
@ -186,46 +125,30 @@ export class AdoptDistribution extends JavaBase {
|
|||||||
`jvm_impl=${this.jvmImpl.toLowerCase()}`
|
`jvm_impl=${this.jvmImpl.toLowerCase()}`
|
||||||
].join('&');
|
].join('&');
|
||||||
|
|
||||||
const requestArguments = `${baseRequestArguments}&page_size=20&page=0`;
|
// need to iterate through all pages to retrieve the list of all versions
|
||||||
let availableVersionsUrl: string | null =
|
// Adopt API doesn't provide way to retrieve the count of pages to iterate so infinity loop
|
||||||
`https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`;
|
let page_index = 0;
|
||||||
const availableVersions: IAdoptAvailableVersions[] = [];
|
const availableVersions: IAdoptAvailableVersions[] = [];
|
||||||
let pageCount = 0;
|
while (true) {
|
||||||
if (core.isDebug()) {
|
const requestArguments = `${baseRequestArguments}&page_size=20&page=${page_index}`;
|
||||||
core.debug(`Gathering available versions from '${availableVersionsUrl}'`);
|
const availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`;
|
||||||
}
|
if (core.isDebug() && page_index === 0) {
|
||||||
|
// url is identical except page_index so print it once for debug
|
||||||
while (availableVersionsUrl) {
|
core.debug(
|
||||||
pageCount++;
|
`Gathering available versions from '${availableVersionsUrl}'`
|
||||||
const response =
|
|
||||||
await this.http.getJson<IAdoptAvailableVersions[]>(
|
|
||||||
availableVersionsUrl
|
|
||||||
);
|
);
|
||||||
const paginationPage = response.result;
|
|
||||||
const nextUrl = getNextPageUrlFromLinkHeader(response.headers);
|
|
||||||
if (
|
|
||||||
nextUrl &&
|
|
||||||
!validatePaginationUrl(nextUrl, 'https://api.adoptopenjdk.net')
|
|
||||||
) {
|
|
||||||
core.warning(
|
|
||||||
`Ignoring pagination link with unexpected origin: ${nextUrl}`
|
|
||||||
);
|
|
||||||
availableVersionsUrl = null;
|
|
||||||
} else {
|
|
||||||
availableVersionsUrl = nextUrl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const paginationPage = (
|
||||||
|
await this.http.getJson<IAdoptAvailableVersions[]>(availableVersionsUrl)
|
||||||
|
).result;
|
||||||
if (paginationPage === null || paginationPage.length === 0) {
|
if (paginationPage === null || paginationPage.length === 0) {
|
||||||
|
// break infinity loop because we have reached end of pagination
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
availableVersions.push(...paginationPage);
|
availableVersions.push(...paginationPage);
|
||||||
|
page_index++;
|
||||||
if (pageCount >= MAX_PAGINATION_PAGES) {
|
|
||||||
core.warning(
|
|
||||||
`Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing Adopt releases.`
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (core.isDebug()) {
|
if (core.isDebug()) {
|
||||||
|
|||||||
@ -292,9 +292,7 @@ export abstract class JavaBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const error = new Error(parts.join('\n'));
|
return new Error(parts.join('\n'));
|
||||||
error.name = 'VersionNotFoundError';
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected setJavaDefault(version: string, toolPath: string) {
|
protected setJavaDefault(version: string, toolPath: string) {
|
||||||
|
|||||||
@ -7,12 +7,9 @@ import {
|
|||||||
import semver from 'semver';
|
import semver from 'semver';
|
||||||
import {
|
import {
|
||||||
extractJdkFile,
|
extractJdkFile,
|
||||||
getNextPageUrlFromLinkHeader,
|
|
||||||
getDownloadArchiveExtension,
|
getDownloadArchiveExtension,
|
||||||
isVersionSatisfies,
|
isVersionSatisfies,
|
||||||
renameWinArchive,
|
renameWinArchive
|
||||||
MAX_PAGINATION_PAGES,
|
|
||||||
validatePaginationUrl
|
|
||||||
} from '../../util';
|
} from '../../util';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as tc from '@actions/tool-cache';
|
import * as tc from '@actions/tool-cache';
|
||||||
@ -158,46 +155,32 @@ export class SemeruDistribution extends JavaBase {
|
|||||||
`jvm_impl=openj9`
|
`jvm_impl=openj9`
|
||||||
].join('&');
|
].join('&');
|
||||||
|
|
||||||
const requestArguments = `${baseRequestArguments}&page_size=20&page=0`;
|
// need to iterate through all pages to retrieve the list of all versions
|
||||||
let availableVersionsUrl: string | null =
|
// Adoptium API doesn't provide way to retrieve the count of pages to iterate so infinity loop
|
||||||
`https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`;
|
let page_index = 0;
|
||||||
const availableVersions: ISemeruAvailableVersions[] = [];
|
const availableVersions: ISemeruAvailableVersions[] = [];
|
||||||
let pageCount = 0;
|
while (true) {
|
||||||
if (core.isDebug()) {
|
const requestArguments = `${baseRequestArguments}&page_size=20&page=${page_index}`;
|
||||||
core.debug(`Gathering available versions from '${availableVersionsUrl}'`);
|
const availableVersionsUrl = `https://api.adoptopenjdk.net/v3/assets/version/${versionRange}?${requestArguments}`;
|
||||||
}
|
if (core.isDebug() && page_index === 0) {
|
||||||
|
// url is identical except page_index so print it once for debug
|
||||||
|
core.debug(
|
||||||
|
`Gathering available versions from '${availableVersionsUrl}'`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
while (availableVersionsUrl) {
|
const paginationPage = (
|
||||||
pageCount++;
|
|
||||||
const response =
|
|
||||||
await this.http.getJson<ISemeruAvailableVersions[]>(
|
await this.http.getJson<ISemeruAvailableVersions[]>(
|
||||||
availableVersionsUrl
|
availableVersionsUrl
|
||||||
);
|
)
|
||||||
const paginationPage = response.result;
|
).result;
|
||||||
const nextUrl = getNextPageUrlFromLinkHeader(response.headers);
|
|
||||||
if (
|
|
||||||
nextUrl &&
|
|
||||||
!validatePaginationUrl(nextUrl, 'https://api.adoptopenjdk.net')
|
|
||||||
) {
|
|
||||||
core.warning(
|
|
||||||
`Ignoring pagination link with unexpected origin: ${nextUrl}`
|
|
||||||
);
|
|
||||||
availableVersionsUrl = null;
|
|
||||||
} else {
|
|
||||||
availableVersionsUrl = nextUrl;
|
|
||||||
}
|
|
||||||
if (paginationPage === null || paginationPage.length === 0) {
|
if (paginationPage === null || paginationPage.length === 0) {
|
||||||
|
// break infinity loop because we have reached end of pagination
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
availableVersions.push(...paginationPage);
|
availableVersions.push(...paginationPage);
|
||||||
|
page_index++;
|
||||||
if (pageCount >= MAX_PAGINATION_PAGES) {
|
|
||||||
core.warning(
|
|
||||||
`Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing Semeru releases.`
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (core.isDebug()) {
|
if (core.isDebug()) {
|
||||||
|
|||||||
@ -14,12 +14,9 @@ import {
|
|||||||
} from '../base-models';
|
} from '../base-models';
|
||||||
import {
|
import {
|
||||||
extractJdkFile,
|
extractJdkFile,
|
||||||
getNextPageUrlFromLinkHeader,
|
|
||||||
getDownloadArchiveExtension,
|
getDownloadArchiveExtension,
|
||||||
isVersionSatisfies,
|
isVersionSatisfies,
|
||||||
renameWinArchive,
|
renameWinArchive
|
||||||
MAX_PAGINATION_PAGES,
|
|
||||||
validatePaginationUrl
|
|
||||||
} from '../../util';
|
} from '../../util';
|
||||||
|
|
||||||
export enum TemurinImplementation {
|
export enum TemurinImplementation {
|
||||||
@ -34,10 +31,7 @@ export class TemurinDistribution extends JavaBase {
|
|||||||
super(`Temurin-${jvmImpl}`, installerOptions);
|
super(`Temurin-${jvmImpl}`, installerOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected async findPackageForDownload(
|
||||||
* @internal For cross-distribution reuse only. Not intended as a public API.
|
|
||||||
*/
|
|
||||||
public async findPackageForDownload(
|
|
||||||
version: string
|
version: string
|
||||||
): Promise<JavaDownloadRelease> {
|
): Promise<JavaDownloadRelease> {
|
||||||
const availableVersionsRaw = await this.getAvailableVersions();
|
const availableVersionsRaw = await this.getAvailableVersions();
|
||||||
@ -129,47 +123,32 @@ export class TemurinDistribution extends JavaBase {
|
|||||||
`jvm_impl=${this.jvmImpl.toLowerCase()}`
|
`jvm_impl=${this.jvmImpl.toLowerCase()}`
|
||||||
].join('&');
|
].join('&');
|
||||||
|
|
||||||
const requestArguments = `${baseRequestArguments}&page_size=20&page=0`;
|
// need to iterate through all pages to retrieve the list of all versions
|
||||||
let availableVersionsUrl: string | null =
|
// Adoptium API doesn't provide way to retrieve the count of pages to iterate so infinity loop
|
||||||
`https://api.adoptium.net/v3/assets/version/${versionRange}?${requestArguments}`;
|
let page_index = 0;
|
||||||
const availableVersions: ITemurinAvailableVersions[] = [];
|
const availableVersions: ITemurinAvailableVersions[] = [];
|
||||||
let pageCount = 0;
|
while (true) {
|
||||||
if (core.isDebug()) {
|
const requestArguments = `${baseRequestArguments}&page_size=20&page=${page_index}`;
|
||||||
core.debug(`Gathering available versions from '${availableVersionsUrl}'`);
|
const availableVersionsUrl = `https://api.adoptium.net/v3/assets/version/${versionRange}?${requestArguments}`;
|
||||||
}
|
if (core.isDebug() && page_index === 0) {
|
||||||
|
// url is identical except page_index so print it once for debug
|
||||||
while (availableVersionsUrl) {
|
core.debug(
|
||||||
pageCount++;
|
`Gathering available versions from '${availableVersionsUrl}'`
|
||||||
const response =
|
|
||||||
await this.http.getJson<ITemurinAvailableVersions[]>(
|
|
||||||
availableVersionsUrl
|
|
||||||
);
|
);
|
||||||
const paginationPage = response.result;
|
|
||||||
const nextUrl = getNextPageUrlFromLinkHeader(response.headers);
|
|
||||||
if (
|
|
||||||
nextUrl &&
|
|
||||||
!validatePaginationUrl(nextUrl, 'https://api.adoptium.net')
|
|
||||||
) {
|
|
||||||
core.warning(
|
|
||||||
`Ignoring pagination link with unexpected origin: ${nextUrl}`
|
|
||||||
);
|
|
||||||
availableVersionsUrl = null;
|
|
||||||
} else {
|
|
||||||
availableVersionsUrl = nextUrl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const paginationPage = (
|
||||||
|
await this.http.getJson<ITemurinAvailableVersions[]>(
|
||||||
|
availableVersionsUrl
|
||||||
|
)
|
||||||
|
).result;
|
||||||
if (paginationPage === null || paginationPage.length === 0) {
|
if (paginationPage === null || paginationPage.length === 0) {
|
||||||
|
// break infinity loop because we have reached end of pagination
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
availableVersions.push(...paginationPage);
|
availableVersions.push(...paginationPage);
|
||||||
|
page_index++;
|
||||||
if (pageCount >= MAX_PAGINATION_PAGES) {
|
|
||||||
core.warning(
|
|
||||||
`Reached pagination safeguard limit (${MAX_PAGINATION_PAGES} pages) while listing Temurin releases.`
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (core.isDebug()) {
|
if (core.isDebug()) {
|
||||||
|
|||||||
57
src/util.ts
57
src/util.ts
@ -55,14 +55,6 @@ export function getDownloadArchiveExtension() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isVersionSatisfies(range: string, version: string): boolean {
|
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 (semver.valid(range)) {
|
||||||
// if full version with build digit is provided as a range (such as '1.2.3+4')
|
// 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
|
// we should check for exact equal via compareBuild
|
||||||
@ -209,55 +201,6 @@ export function getGitHubHttpHeaders(): OutgoingHttpHeaders {
|
|||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MAX_PAGINATION_PAGES = 1000;
|
|
||||||
|
|
||||||
export function getNextPageUrlFromLinkHeader(
|
|
||||||
headers?: Record<string, string | string[] | undefined>
|
|
||||||
): string | null {
|
|
||||||
if (!headers) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const linkHeader = headers.link ?? headers.Link;
|
|
||||||
if (!linkHeader) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const normalizedLinkHeader = Array.isArray(linkHeader)
|
|
||||||
? linkHeader.join(',')
|
|
||||||
: linkHeader;
|
|
||||||
|
|
||||||
// Split into individual link-values and find the one with rel="next"
|
|
||||||
// RFC 8288 allows rel to appear anywhere among the parameters
|
|
||||||
const linkValues = normalizedLinkHeader.split(/,(?=\s*<)/);
|
|
||||||
for (const linkValue of linkValues) {
|
|
||||||
const urlMatch = linkValue.match(/<([^>]+)>/);
|
|
||||||
if (!urlMatch) continue;
|
|
||||||
|
|
||||||
const params = linkValue.slice(urlMatch[0].length);
|
|
||||||
// Use word boundary to match "next" as a standalone relation type
|
|
||||||
// RFC 8288 allows space-separated relation types like rel="next prev"
|
|
||||||
if (/;\s*rel="?[^"]*\bnext\b/i.test(params)) {
|
|
||||||
return urlMatch[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function validatePaginationUrl(
|
|
||||||
url: string,
|
|
||||||
allowedOrigin: string
|
|
||||||
): boolean {
|
|
||||||
try {
|
|
||||||
const parsed = new URL(url);
|
|
||||||
const allowed = new URL(allowedOrigin);
|
|
||||||
return parsed.origin === allowed.origin;
|
|
||||||
} catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rename archive to add extension because after downloading
|
// Rename archive to add extension because after downloading
|
||||||
// archive does not contain extension type and it leads to some issues
|
// archive does not contain extension type and it leads to some issues
|
||||||
// on Windows runners without PowerShell Core.
|
// on Windows runners without PowerShell Core.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user