Skip to content

Commit cec33d9

Browse files
committed
add support for artifacts proxy repositories
1 parent 06db6c2 commit cec33d9

File tree

18 files changed

+497
-23
lines changed

18 files changed

+497
-23
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ The `setup-java` action provides the following functionality for GitHub Actions
1313
- Caching dependencies managed by Gradle
1414
- Caching dependencies managed by sbt
1515
- [Maven Toolchains declaration](https://maven.apache.org/guides/mini/guide-using-toolchains.html) for specified JDK versions
16+
- support for enterpries that are using a system that is proxying a repository located on a remote server.
1617

1718
This action allows you to work with Java and Scala projects.
1819

@@ -60,6 +61,12 @@ This action allows you to work with Java and Scala projects.
6061

6162
- `mvn-toolchain-vendor`: Name of Maven Toolchain Vendor if the default name of `${distribution}` is not wanted.
6263

64+
- `remote-repository-base-url`: The base url to the solution which houses and manages all the artifacts (ex: artifactory, nexus, etc.). If `remote-repository-base-url` is specified you also need to specify the `replace-download-link-base-url`.
65+
66+
- `replace-download-link-base-url`: The base url of the download link, extracted from the metadata file, which must be substituted with the remote-repository-base-url.
67+
68+
- `download-link-context`: Because the proxying of the artifacts it is higly dependent on the admin doing it, it might be that a context is needed to be postpended to the remote-repository-base-url.
69+
6370
### Basic Configuration
6471

6572
#### Eclipse Temurin
@@ -231,6 +238,8 @@ In the example above multiple JDKs are installed for the same job. The result af
231238
- [Publishing using Gradle](docs/advanced-usage.md#Publishing-using-Gradle)
232239
- [Hosted Tool Cache](docs/advanced-usage.md#Hosted-Tool-Cache)
233240
- [Modifying Maven Toolchains](docs/advanced-usage.md#Modifying-Maven-Toolchains)
241+
- [Modifying Maven Toolchains](docs/advanced-usage.md#Modifying-Maven-Toolchains)
242+
- [Fetch binaries from the artifact proxy repository](docs/advanced-usage.md#Proxy-repositores)
234243

235244
## License
236245

__tests__/distributors/adopt-installer.test.ts

Lines changed: 299 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,302 @@ describe('findPackageForDownload', () => {
217217
);
218218
});
219219
});
220+
221+
describe('getAvailableVersionsFromProxy', () => {
222+
let spyHttpClient: jest.SpyInstance;
223+
224+
beforeEach(() => {
225+
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
226+
spyHttpClient.mockReturnValue({
227+
statusCode: 200,
228+
headers: {},
229+
result: []
230+
});
231+
});
232+
233+
afterEach(() => {
234+
jest.resetAllMocks();
235+
jest.clearAllMocks();
236+
jest.restoreAllMocks();
237+
});
238+
239+
it.each([
240+
[
241+
{
242+
version: '11',
243+
architecture: 'x64',
244+
packageType: 'jdk',
245+
checkLatest: false,
246+
remoteRepositoryBaseUrl: 'https://test.artifactory.com'
247+
},
248+
AdoptImplementation.Hotspot,
249+
'os=mac&architecture=x64&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0'
250+
],
251+
[
252+
{
253+
version: '11',
254+
architecture: 'x86',
255+
packageType: 'jdk',
256+
checkLatest: false,
257+
remoteRepositoryBaseUrl: 'https://test.artifactory.com'
258+
},
259+
AdoptImplementation.Hotspot,
260+
'os=mac&architecture=x86&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0'
261+
],
262+
[
263+
{
264+
version: '11',
265+
architecture: 'x64',
266+
packageType: 'jre',
267+
checkLatest: false,
268+
remoteRepositoryBaseUrl: 'https://test.artifactory.com'
269+
},
270+
AdoptImplementation.Hotspot,
271+
'os=mac&architecture=x64&image_type=jre&release_type=ga&jvm_impl=hotspot&page_size=20&page=0'
272+
],
273+
[
274+
{
275+
version: '11-ea',
276+
architecture: 'x64',
277+
packageType: 'jdk',
278+
checkLatest: false,
279+
remoteRepositoryBaseUrl: 'https://test.artifactory.com'
280+
},
281+
AdoptImplementation.Hotspot,
282+
'os=mac&architecture=x64&image_type=jdk&release_type=ea&jvm_impl=hotspot&page_size=20&page=0'
283+
],
284+
[
285+
{
286+
version: '11',
287+
architecture: 'x64',
288+
packageType: 'jdk',
289+
checkLatest: false,
290+
remoteRepositoryBaseUrl: 'https://test.artifactory.com'
291+
},
292+
AdoptImplementation.OpenJ9,
293+
'os=mac&architecture=x64&image_type=jdk&release_type=ga&jvm_impl=openj9&page_size=20&page=0'
294+
],
295+
[
296+
{
297+
version: '11',
298+
architecture: 'x86',
299+
packageType: 'jdk',
300+
checkLatest: false,
301+
remoteRepositoryBaseUrl: 'https://test.artifactory.com'
302+
},
303+
AdoptImplementation.OpenJ9,
304+
'os=mac&architecture=x86&image_type=jdk&release_type=ga&jvm_impl=openj9&page_size=20&page=0'
305+
],
306+
[
307+
{
308+
version: '11',
309+
architecture: 'x64',
310+
packageType: 'jre',
311+
checkLatest: false,
312+
remoteRepositoryBaseUrl: 'https://test.artifactory.com'
313+
},
314+
AdoptImplementation.OpenJ9,
315+
'os=mac&architecture=x64&image_type=jre&release_type=ga&jvm_impl=openj9&page_size=20&page=0'
316+
],
317+
[
318+
{
319+
version: '11-ea',
320+
architecture: 'x64',
321+
packageType: 'jdk',
322+
checkLatest: false,
323+
remoteRepositoryBaseUrl: 'https://test.artifactory.com'
324+
},
325+
AdoptImplementation.OpenJ9,
326+
'os=mac&architecture=x64&image_type=jdk&release_type=ea&jvm_impl=openj9&page_size=20&page=0'
327+
]
328+
])(
329+
'build correct url for %s',
330+
async (
331+
installerOptions: JavaInstallerOptions,
332+
impl: AdoptImplementation,
333+
expectedParameters
334+
) => {
335+
const distribution = new AdoptDistribution(installerOptions, impl);
336+
const baseUrl = 'https://test.artifactory.com/v3/assets/version/%5B1.0,100.0%5D';
337+
const expectedUrl = `${baseUrl}?project=jdk&vendor=adoptopenjdk&heap_size=normal&sort_method=DEFAULT&sort_order=DESC&${expectedParameters}`;
338+
distribution['getPlatformOption'] = () => 'mac';
339+
340+
await distribution['getAvailableVersions']();
341+
342+
expect(spyHttpClient.mock.calls).toHaveLength(1);
343+
expect(spyHttpClient.mock.calls[0][0]).toBe(expectedUrl);
344+
}
345+
);
346+
347+
it('load available versions', async () => {
348+
spyHttpClient = jest.spyOn(HttpClient.prototype, 'getJson');
349+
spyHttpClient
350+
.mockReturnValueOnce({
351+
statusCode: 200,
352+
headers: {},
353+
result: manifestData
354+
})
355+
.mockReturnValueOnce({
356+
statusCode: 200,
357+
headers: {},
358+
result: manifestData
359+
})
360+
.mockReturnValueOnce({
361+
statusCode: 200,
362+
headers: {},
363+
result: []
364+
});
365+
366+
const distribution = new AdoptDistribution(
367+
{
368+
version: '11',
369+
architecture: 'x64',
370+
packageType: 'jdk',
371+
checkLatest: false,
372+
remoteRepositoryBaseUrl: 'https://test.artifactory.com'
373+
},
374+
AdoptImplementation.Hotspot
375+
);
376+
const availableVersions = await distribution['getAvailableVersions']();
377+
expect(availableVersions).not.toBeNull();
378+
expect(availableVersions.length).toBe(manifestData.length * 2);
379+
});
380+
381+
it.each([
382+
[AdoptImplementation.Hotspot, 'jdk', 'Java_Adopt_jdk'],
383+
[AdoptImplementation.Hotspot, 'jre', 'Java_Adopt_jre'],
384+
[AdoptImplementation.OpenJ9, 'jdk', 'Java_Adopt-OpenJ9_jdk'],
385+
[AdoptImplementation.OpenJ9, 'jre', 'Java_Adopt-OpenJ9_jre']
386+
])(
387+
'find right toolchain folder',
388+
(impl: AdoptImplementation, packageType: string, expected: string) => {
389+
const distribution = new AdoptDistribution(
390+
{
391+
version: '11',
392+
architecture: 'x64',
393+
packageType: packageType,
394+
checkLatest: false,
395+
remoteRepositoryBaseUrl: 'https://test.artifactory.com'
396+
},
397+
impl
398+
);
399+
400+
// @ts-ignore - because it is protected
401+
expect(distribution.toolcacheFolderName).toBe(expected);
402+
}
403+
);
404+
405+
it.each([
406+
['amd64', 'x64'],
407+
['arm64', 'aarch64']
408+
])(
409+
'defaults to os.arch(): %s mapped to distro arch: %s',
410+
async (osArch: string, distroArch: string) => {
411+
jest.spyOn(os, 'arch').mockReturnValue(osArch);
412+
413+
const installerOptions: JavaInstallerOptions = {
414+
version: '17',
415+
architecture: '', // to get default value
416+
packageType: 'jdk',
417+
checkLatest: false,
418+
remoteRepositoryBaseUrl: 'https://test.artifactory.com'
419+
};
420+
421+
const expectedParameters = `os=mac&architecture=${distroArch}&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0`;
422+
423+
const distribution = new AdoptDistribution(installerOptions, AdoptImplementation.Hotspot);
424+
const baseUrl = 'https://test.artifactory.com/v3/assets/version/%5B1.0,100.0%5D';
425+
const expectedUrl = `${baseUrl}?project=jdk&vendor=adoptopenjdk&heap_size=normal&sort_method=DEFAULT&sort_order=DESC&${expectedParameters}`;
426+
distribution['getPlatformOption'] = () => 'mac';
427+
428+
await distribution['getAvailableVersions']();
429+
430+
expect(spyHttpClient.mock.calls).toHaveLength(1);
431+
expect(spyHttpClient.mock.calls[0][0]).toBe(expectedUrl);
432+
}
433+
);
434+
});
435+
436+
describe('findPackageForDownload', () => {
437+
it.each([
438+
['9', '9.0.7+10'],
439+
['15', '15.0.2+7'],
440+
['15.0', '15.0.2+7'],
441+
['15.0.2', '15.0.2+7'],
442+
['15.0.1', '15.0.1+9.1'],
443+
['11.x', '11.0.10+9'],
444+
['x', '15.0.2+7'],
445+
['12', '12.0.2+10.3'], // make sure that '12.0.2+10.1', '12.0.2+10.3', '12.0.2+10.2' are sorted correctly
446+
['12.0.2+10.1', '12.0.2+10.1'],
447+
['15.0.1+9', '15.0.1+9'],
448+
['15.0.1+9.1', '15.0.1+9.1']
449+
])('version is resolved correctly %s -> %s', async (input, expected) => {
450+
const distribution = new AdoptDistribution(
451+
{
452+
version: '11',
453+
architecture: 'x64',
454+
packageType: 'jdk',
455+
checkLatest: false,
456+
remoteRepositoryBaseUrl: 'https://test.artifactory.com',
457+
replaceDownloadLinkBaseUrl: 'https://github.com/AdoptOpenJDK',
458+
downloadLinkContext: '/AdoptOpenJDK'
459+
},
460+
AdoptImplementation.Hotspot
461+
);
462+
distribution['getAvailableVersions'] = async () => manifestData;
463+
const resolvedVersion = await distribution['findPackageForDownload'](input);
464+
expect(resolvedVersion.version).toBe(expected);
465+
expect(resolvedVersion.url).toContain('https://test.artifactory.com/AdoptOpenJDK');
466+
});
467+
468+
it('version is found but binaries list is empty', async () => {
469+
const distribution = new AdoptDistribution(
470+
{
471+
version: '11',
472+
architecture: 'x64',
473+
packageType: 'jdk',
474+
checkLatest: false,
475+
remoteRepositoryBaseUrl: 'https://test.artifactory.com'
476+
},
477+
AdoptImplementation.Hotspot
478+
);
479+
distribution['getAvailableVersions'] = async () => manifestData;
480+
await expect(distribution['findPackageForDownload']('9.0.8')).rejects.toThrowError(
481+
/Could not find satisfied version for SemVer */
482+
);
483+
});
484+
485+
it('version is not found', async () => {
486+
const distribution = new AdoptDistribution(
487+
{
488+
version: '11',
489+
architecture: 'x64',
490+
packageType: 'jdk',
491+
checkLatest: false,
492+
remoteRepositoryBaseUrl: 'https://test.artifactory.com'
493+
},
494+
AdoptImplementation.Hotspot
495+
);
496+
distribution['getAvailableVersions'] = async () => manifestData;
497+
await expect(distribution['findPackageForDownload']('7.x')).rejects.toThrowError(
498+
/Could not find satisfied version for SemVer */
499+
);
500+
});
501+
502+
it('version list is empty', async () => {
503+
const distribution = new AdoptDistribution(
504+
{
505+
version: '11',
506+
architecture: 'x64',
507+
packageType: 'jdk',
508+
checkLatest: false,
509+
remoteRepositoryBaseUrl: 'https://test.artifactory.com'
510+
},
511+
AdoptImplementation.Hotspot
512+
);
513+
distribution['getAvailableVersions'] = async () => [];
514+
await expect(distribution['findPackageForDownload']('11')).rejects.toThrowError(
515+
/Could not find satisfied version for SemVer */
516+
);
517+
});
518+
});

__tests__/distributors/base-installer.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import {
1515
import os from 'os';
1616

1717
class EmptyJavaBase extends JavaBase {
18+
protected remoteMetadataBaseUrl = 'MUST STAY EMPTY';
19+
protected remoteBaseUrl = 'MUST STAY EMPTY';
1820
constructor(installerOptions: JavaInstallerOptions) {
1921
super('Empty', installerOptions);
2022
}
@@ -37,6 +39,10 @@ class EmptyJavaBase extends JavaBase {
3739
url: `some/random_url/java/${availableVersion}`
3840
};
3941
}
42+
43+
protected baseUrl(): string {
44+
throw new Error('Method already tested in all distribution installers');
45+
}
4046
}
4147

4248
describe('findInToolcache', () => {

action.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ inputs:
6868
mvn-toolchain-vendor:
6969
description: 'Name of Maven Toolchain Vendor if the default name of "${distribution}" is not wanted. See examples of supported syntax in Advanced Usage file'
7070
required: false
71+
remote-repository-base-url:
72+
description: 'The base url to the solution which houses and manages all the artifacts (ex: artifactory, nexus, etc.)'
73+
required: false
74+
replace-download-link-base-url:
75+
description: 'The base url of the download link, extracted from the metadata file, which must be substituted with the remote-repository-base-url. Sometimes you might need to specify the download link context to have a proper download link of the distribution.'
76+
required: false
77+
download-link-context:
78+
description: 'Because the proxying of the artifacts it is higly dependent on the admin doing it, it might be that a context is needed to be postpended to the remote-repository-base-url.'
79+
required: false
7180
outputs:
7281
distribution:
7382
description: 'Distribution of Java that has been installed'

dist/cleanup/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68480,7 +68480,7 @@ else {
6848068480
"use strict";
6848168481

6848268482
Object.defineProperty(exports, "__esModule", ({ value: true }));
68483-
exports.DISTRIBUTIONS_ONLY_MAJOR_VERSION = exports.INPUT_MVN_TOOLCHAIN_VENDOR = exports.INPUT_MVN_TOOLCHAIN_ID = exports.MVN_TOOLCHAINS_FILE = exports.MVN_SETTINGS_FILE = exports.M2_DIR = exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = exports.INPUT_JOB_STATUS = exports.INPUT_CACHE = exports.INPUT_DEFAULT_GPG_PASSPHRASE = exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = exports.INPUT_GPG_PASSPHRASE = exports.INPUT_GPG_PRIVATE_KEY = exports.INPUT_OVERWRITE_SETTINGS = exports.INPUT_SETTINGS_PATH = exports.INPUT_SERVER_PASSWORD = exports.INPUT_SERVER_USERNAME = exports.INPUT_SERVER_ID = exports.INPUT_CHECK_LATEST = exports.INPUT_JDK_FILE = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_PACKAGE = exports.INPUT_ARCHITECTURE = exports.INPUT_JAVA_VERSION_FILE = exports.INPUT_JAVA_VERSION = exports.MACOS_JAVA_CONTENT_POSTFIX = void 0;
68483+
exports.DOWNLOAD_LINK_CONTEXT = exports.REPLACE_DOWNLOAD_LINK_BASE_URL = exports.REMOTE_REPOSITORY_BASE_URL = exports.DISTRIBUTIONS_ONLY_MAJOR_VERSION = exports.INPUT_MVN_TOOLCHAIN_VENDOR = exports.INPUT_MVN_TOOLCHAIN_ID = exports.MVN_TOOLCHAINS_FILE = exports.MVN_SETTINGS_FILE = exports.M2_DIR = exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = exports.INPUT_JOB_STATUS = exports.INPUT_CACHE = exports.INPUT_DEFAULT_GPG_PASSPHRASE = exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = exports.INPUT_GPG_PASSPHRASE = exports.INPUT_GPG_PRIVATE_KEY = exports.INPUT_OVERWRITE_SETTINGS = exports.INPUT_SETTINGS_PATH = exports.INPUT_SERVER_PASSWORD = exports.INPUT_SERVER_USERNAME = exports.INPUT_SERVER_ID = exports.INPUT_CHECK_LATEST = exports.INPUT_JDK_FILE = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_PACKAGE = exports.INPUT_ARCHITECTURE = exports.INPUT_JAVA_VERSION_FILE = exports.INPUT_JAVA_VERSION = exports.MACOS_JAVA_CONTENT_POSTFIX = void 0;
6848468484
exports.MACOS_JAVA_CONTENT_POSTFIX = 'Contents/Home';
6848568485
exports.INPUT_JAVA_VERSION = 'java-version';
6848668486
exports.INPUT_JAVA_VERSION_FILE = 'java-version-file';
@@ -68507,6 +68507,9 @@ exports.MVN_TOOLCHAINS_FILE = 'toolchains.xml';
6850768507
exports.INPUT_MVN_TOOLCHAIN_ID = 'mvn-toolchain-id';
6850868508
exports.INPUT_MVN_TOOLCHAIN_VENDOR = 'mvn-toolchain-vendor';
6850968509
exports.DISTRIBUTIONS_ONLY_MAJOR_VERSION = ['corretto'];
68510+
exports.REMOTE_REPOSITORY_BASE_URL = 'remote-repository-base-url';
68511+
exports.REPLACE_DOWNLOAD_LINK_BASE_URL = 'replace-download-link-base-url';
68512+
exports.DOWNLOAD_LINK_CONTEXT = 'download-link-context';
6851068513

6851168514

6851268515
/***/ }),

0 commit comments

Comments
 (0)