Add versions-manifest.json for Microsoft Build of OpenJDK (#383)
This commit is contained in:
		| @ -1,7 +1,13 @@ | ||||
| import { MicrosoftDistributions } from '../../src/distributions/microsoft/installer'; | ||||
| import * as tc from '@actions/tool-cache'; | ||||
| import data from '../../src/distributions/microsoft/microsoft-openjdk-versions.json'; | ||||
| import * as httpm from '@actions/http-client'; | ||||
| import * as core from '@actions/core'; | ||||
|  | ||||
| describe('findPackageForDownload', () => { | ||||
|   let distribution: MicrosoftDistributions; | ||||
|   let spyGetManifestFromRepo: jest.SpyInstance; | ||||
|   let spyDebug: jest.SpyInstance; | ||||
|  | ||||
|   beforeEach(() => { | ||||
|     distribution = new MicrosoftDistributions({ | ||||
| @ -10,12 +16,22 @@ describe('findPackageForDownload', () => { | ||||
|       packageType: 'jdk', | ||||
|       checkLatest: false | ||||
|     }); | ||||
|  | ||||
|     spyGetManifestFromRepo = jest.spyOn(httpm.HttpClient.prototype, 'getJson'); | ||||
|     spyGetManifestFromRepo.mockReturnValue({ | ||||
|       result: data, | ||||
|       statusCode: 200, | ||||
|       headers: {} | ||||
|     }); | ||||
|  | ||||
|     spyDebug = jest.spyOn(core, 'debug'); | ||||
|     spyDebug.mockImplementation(() => {}); | ||||
|   }); | ||||
|  | ||||
|   it.each([ | ||||
|     [ | ||||
|       '17.0.1', | ||||
|       '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}}' | ||||
|     ], | ||||
|     [ | ||||
| @ -25,12 +41,12 @@ describe('findPackageForDownload', () => { | ||||
|     ], | ||||
|     [ | ||||
|       '16.0.x', | ||||
|       '16.0.2', | ||||
|       '16.0.2+7.1', | ||||
|       'https://aka.ms/download-jdk/microsoft-jdk-16.0.2.7.1-{{OS_TYPE}}-x64.{{ARCHIVE_TYPE}}' | ||||
|     ], | ||||
|     [ | ||||
|       '11.0.13', | ||||
|       '11.0.13', | ||||
|       '11.0.13+8.1', | ||||
|       'https://aka.ms/download-jdk/microsoft-jdk-11.0.13.8.1-{{OS_TYPE}}-x64.{{ARCHIVE_TYPE}}' | ||||
|     ], | ||||
|     [ | ||||
| @ -67,32 +83,3 @@ describe('findPackageForDownload', () => { | ||||
|     ); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('getPlatformOption', () => { | ||||
|   const distributions = new MicrosoftDistributions({ | ||||
|     architecture: 'x64', | ||||
|     version: '11', | ||||
|     packageType: 'jdk', | ||||
|     checkLatest: false | ||||
|   }); | ||||
|  | ||||
|   it.each([ | ||||
|     ['linux', 'tar.gz', 'linux'], | ||||
|     ['darwin', 'tar.gz', 'macos'], | ||||
|     ['win32', 'zip', 'windows'] | ||||
|   ])('os version %s -> %s', (input, expectedArchive, expectedOs) => { | ||||
|     const actual = distributions['getPlatformOption'](input as NodeJS.Platform); | ||||
|  | ||||
|     expect(actual.archive).toEqual(expectedArchive); | ||||
|     expect(actual.os).toEqual(expectedOs); | ||||
|   }); | ||||
|  | ||||
|   it.each(['aix', 'android', 'freebsd', 'openbsd', 'netbsd', 'solaris', 'cygwin'])( | ||||
|     'not support os version %s', | ||||
|     input => { | ||||
|       expect(() => distributions['getPlatformOption'](input as NodeJS.Platform)).toThrow( | ||||
|         /Platform '\w+' is not supported\. Supported platforms: .+/ | ||||
|       ); | ||||
|     } | ||||
|   ); | ||||
| }); | ||||
|  | ||||
| @ -59,6 +59,9 @@ inputs: | ||||
|   job-status: | ||||
|     description: 'Workaround to pass job status to post job step. This variable is not intended for manual setting' | ||||
|     default: ${{ job.status }} | ||||
|   token: | ||||
|     description: Used to pull java versions from setup-java. Since there is a default value, token is typically not supplied by the user. | ||||
|     default: ${{ github.token }} | ||||
| outputs: | ||||
|   distribution: | ||||
|     description: 'Distribution of Java that has been installed' | ||||
|  | ||||
							
								
								
									
										88
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										88
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							| @ -104405,7 +104405,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) { | ||||
| Object.defineProperty(exports, "__esModule", ({ value: true })); | ||||
| exports.MicrosoftDistributions = void 0; | ||||
| const base_installer_1 = __nccwpck_require__(9741); | ||||
| const semver_1 = __importDefault(__nccwpck_require__(1383)); | ||||
| const util_1 = __nccwpck_require__(2629); | ||||
| const core = __importStar(__nccwpck_require__(2186)); | ||||
| const tc = __importStar(__nccwpck_require__(7784)); | ||||
| @ -104439,70 +104438,51 @@ class MicrosoftDistributions extends base_installer_1.JavaBase { | ||||
|             if (this.packageType !== 'jdk') { | ||||
|                 throw new Error('Microsoft Build of OpenJDK provides only the `jdk` package type'); | ||||
|             } | ||||
|             const availableVersionsRaw = yield this.getAvailableVersions(); | ||||
|             const opts = this.getPlatformOption(); | ||||
|             const availableVersions = availableVersionsRaw.map(item => ({ | ||||
|                 url: `https://aka.ms/download-jdk/microsoft-jdk-${item.version.join('.')}-${opts.os}-${this.architecture}.${opts.archive}`, | ||||
|                 version: this.convertVersionToSemver(item) | ||||
|             })); | ||||
|             const satisfiedVersion = availableVersions | ||||
|                 .filter(item => util_1.isVersionSatisfies(range, item.version)) | ||||
|                 .sort((a, b) => -semver_1.default.compareBuild(a.version, b.version))[0]; | ||||
|             if (!satisfiedVersion) { | ||||
|                 const availableOptions = availableVersions.map(item => item.version).join(', '); | ||||
|                 const availableOptionsMessage = availableOptions | ||||
|                     ? `\nAvailable versions: ${availableOptions}` | ||||
|                     : ''; | ||||
|                 throw new Error(`Could not find satisfied version for SemVer ${range}. ${availableOptionsMessage}`); | ||||
|             const manifest = yield this.getAvailableVersions(); | ||||
|             if (!manifest) { | ||||
|                 throw new Error('Could not load manifest for Microsoft Build of OpenJDK'); | ||||
|             } | ||||
|             return satisfiedVersion; | ||||
|             const foundRelease = yield tc.findFromManifest(range, true, manifest, this.architecture); | ||||
|             if (!foundRelease) { | ||||
|                 throw new Error(`Could not find satisfied version for SemVer ${range}. ${manifest | ||||
|                     .map(item => item.version) | ||||
|                     .join(', ')}`);
 | ||||
|             } | ||||
|             return { url: foundRelease.files[0].download_url, version: foundRelease.version }; | ||||
|         }); | ||||
|     } | ||||
|     getAvailableVersions() { | ||||
|         return __awaiter(this, void 0, void 0, function* () { | ||||
|             // TODO get these dynamically!
 | ||||
|             // We will need Microsoft to add an endpoint where we can query for versions.
 | ||||
|             const jdkVersions = [ | ||||
|                 { | ||||
|                     version: [17, 0, 3] | ||||
|                 }, | ||||
|                 { | ||||
|                     version: [17, 0, 1, 12, 1] | ||||
|                 }, | ||||
|                 { | ||||
|                     version: [16, 0, 2, 7, 1] | ||||
|                 }, | ||||
|                 { | ||||
|                     version: [11, 0, 15] | ||||
|             const token = core.getInput('token'); | ||||
|             const owner = 'actions'; | ||||
|             const repository = 'setup-java'; | ||||
|             const branch = 'main'; | ||||
|             const filePath = 'src/distributions/microsoft/microsoft-openjdk-versions.json'; | ||||
|             let releases = null; | ||||
|             const fileUrl = `https://api.github.com/repos/${owner}/${repository}/contents/${filePath}?ref=${branch}`; | ||||
|             const headers = { | ||||
|                 authorization: token, | ||||
|                 accept: 'application/vnd.github.VERSION.raw' | ||||
|             }; | ||||
|             let response = null; | ||||
|             try { | ||||
|                 response = yield this.http.getJson(fileUrl, headers); | ||||
|                 if (!response.result) { | ||||
|                     return null; | ||||
|                 } | ||||
|             ]; | ||||
|             // M1 is only supported for Java 16 & 17
 | ||||
|             if (process.platform !== 'darwin' || this.architecture !== 'aarch64') { | ||||
|                 jdkVersions.push({ | ||||
|                     version: [11, 0, 13, 8, 1] | ||||
|                 }); | ||||
|             } | ||||
|             return jdkVersions; | ||||
|             catch (err) { | ||||
|                 core.debug(`Http request for microsoft-openjdk-versions.json failed with status code: ${response === null || response === void 0 ? void 0 : response.statusCode}`); | ||||
|                 return null; | ||||
|             } | ||||
|             if (response.result) { | ||||
|                 releases = response.result; | ||||
|             } | ||||
|             return releases; | ||||
|         }); | ||||
|     } | ||||
|     getPlatformOption(platform = process.platform /* for testing */) { | ||||
|         switch (platform) { | ||||
|             case 'darwin': | ||||
|                 return { archive: 'tar.gz', os: 'macos' }; | ||||
|             case 'win32': | ||||
|                 return { archive: 'zip', os: 'windows' }; | ||||
|             case 'linux': | ||||
|                 return { archive: 'tar.gz', os: 'linux' }; | ||||
|             default: | ||||
|                 throw new Error(`Platform '${platform}' is not supported. Supported platforms: 'darwin', 'linux', 'win32'`); | ||||
|         } | ||||
|     } | ||||
|     convertVersionToSemver(version) { | ||||
|         const major = version.version[0]; | ||||
|         const minor = version.version[1]; | ||||
|         const patch = version.version[2]; | ||||
|         return `${major}.${minor}.${patch}`; | ||||
|     } | ||||
| } | ||||
| exports.MicrosoftDistributions = MicrosoftDistributions; | ||||
| 
 | ||||
|  | ||||
| @ -1,12 +1,12 @@ | ||||
| import { JavaBase } from '../base-installer'; | ||||
| import { JavaDownloadRelease, JavaInstallerOptions, JavaInstallerResults } from '../base-models'; | ||||
| import semver from 'semver'; | ||||
| import { extractJdkFile, getDownloadArchiveExtension, isVersionSatisfies } from '../../util'; | ||||
| import { extractJdkFile, getDownloadArchiveExtension } from '../../util'; | ||||
| import * as core from '@actions/core'; | ||||
| import { MicrosoftVersion, PlatformOptions } from './models'; | ||||
| import * as tc from '@actions/tool-cache'; | ||||
| import { OutgoingHttpHeaders } from 'http'; | ||||
| import fs from 'fs'; | ||||
| import path from 'path'; | ||||
| import { ITypedResponse } from '@actions/http-client/interfaces'; | ||||
|  | ||||
| export class MicrosoftDistributions extends JavaBase { | ||||
|   constructor(installerOptions: JavaInstallerOptions) { | ||||
| @ -49,82 +49,60 @@ export class MicrosoftDistributions extends JavaBase { | ||||
|       throw new Error('Microsoft Build of OpenJDK provides only the `jdk` package type'); | ||||
|     } | ||||
|  | ||||
|     const availableVersionsRaw = await this.getAvailableVersions(); | ||||
|     const manifest = await this.getAvailableVersions(); | ||||
|  | ||||
|     const opts = this.getPlatformOption(); | ||||
|     const availableVersions = availableVersionsRaw.map(item => ({ | ||||
|       url: `https://aka.ms/download-jdk/microsoft-jdk-${item.version.join('.')}-${opts.os}-${ | ||||
|         this.architecture | ||||
|       }.${opts.archive}`, | ||||
|       version: this.convertVersionToSemver(item) | ||||
|     })); | ||||
|     if (!manifest) { | ||||
|       throw new Error('Could not load manifest for Microsoft Build of OpenJDK'); | ||||
|     } | ||||
|  | ||||
|     const satisfiedVersion = availableVersions | ||||
|       .filter(item => isVersionSatisfies(range, item.version)) | ||||
|       .sort((a, b) => -semver.compareBuild(a.version, b.version))[0]; | ||||
|     const foundRelease = await tc.findFromManifest(range, true, manifest, this.architecture); | ||||
|  | ||||
|     if (!satisfiedVersion) { | ||||
|       const availableOptions = availableVersions.map(item => item.version).join(', '); | ||||
|       const availableOptionsMessage = availableOptions | ||||
|         ? `\nAvailable versions: ${availableOptions}` | ||||
|         : ''; | ||||
|     if (!foundRelease) { | ||||
|       throw new Error( | ||||
|         `Could not find satisfied version for SemVer ${range}. ${availableOptionsMessage}` | ||||
|         `Could not find satisfied version for SemVer ${range}. ${manifest | ||||
|           .map(item => item.version) | ||||
|           .join(', ')}` | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     return satisfiedVersion; | ||||
|     return { url: foundRelease.files[0].download_url, version: foundRelease.version }; | ||||
|   } | ||||
|  | ||||
|   private async getAvailableVersions(): Promise<MicrosoftVersion[]> { | ||||
|   private async getAvailableVersions(): Promise<tc.IToolRelease[] | null> { | ||||
|     // TODO get these dynamically! | ||||
|     // We will need Microsoft to add an endpoint where we can query for versions. | ||||
|     const jdkVersions = [ | ||||
|       { | ||||
|         version: [17, 0, 3] | ||||
|       }, | ||||
|       { | ||||
|         version: [17, 0, 1, 12, 1] | ||||
|       }, | ||||
|       { | ||||
|         version: [16, 0, 2, 7, 1] | ||||
|       }, | ||||
|       { | ||||
|         version: [11, 0, 15] | ||||
|     const token = core.getInput('token'); | ||||
|     const owner = 'actions'; | ||||
|     const repository = 'setup-java'; | ||||
|     const branch = 'main'; | ||||
|     const filePath = 'src/distributions/microsoft/microsoft-openjdk-versions.json'; | ||||
|  | ||||
|     let releases: tc.IToolRelease[] | null = null; | ||||
|     const fileUrl = `https://api.github.com/repos/${owner}/${repository}/contents/${filePath}?ref=${branch}`; | ||||
|  | ||||
|     const headers: OutgoingHttpHeaders = { | ||||
|       authorization: token, | ||||
|       accept: 'application/vnd.github.VERSION.raw' | ||||
|     }; | ||||
|  | ||||
|     let response: ITypedResponse<tc.IToolRelease[]> | null = null; | ||||
|  | ||||
|     try { | ||||
|       response = await this.http.getJson<tc.IToolRelease[]>(fileUrl, headers); | ||||
|       if (!response.result) { | ||||
|         return null; | ||||
|       } | ||||
|     ]; | ||||
|  | ||||
|     // M1 is only supported for Java 16 & 17 | ||||
|     if (process.platform !== 'darwin' || this.architecture !== 'aarch64') { | ||||
|       jdkVersions.push({ | ||||
|         version: [11, 0, 13, 8, 1] | ||||
|       }); | ||||
|     } catch (err) { | ||||
|       core.debug( | ||||
|         `Http request for microsoft-openjdk-versions.json failed with status code: ${response?.statusCode}` | ||||
|       ); | ||||
|       return null; | ||||
|     } | ||||
|  | ||||
|     return jdkVersions; | ||||
|   } | ||||
|  | ||||
|   private getPlatformOption( | ||||
|     platform: NodeJS.Platform = process.platform /* for testing */ | ||||
|   ): PlatformOptions { | ||||
|     switch (platform) { | ||||
|       case 'darwin': | ||||
|         return { archive: 'tar.gz', os: 'macos' }; | ||||
|       case 'win32': | ||||
|         return { archive: 'zip', os: 'windows' }; | ||||
|       case 'linux': | ||||
|         return { archive: 'tar.gz', os: 'linux' }; | ||||
|       default: | ||||
|         throw new Error( | ||||
|           `Platform '${platform}' is not supported. Supported platforms: 'darwin', 'linux', 'win32'` | ||||
|         ); | ||||
|     if (response.result) { | ||||
|       releases = response.result; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private convertVersionToSemver(version: MicrosoftVersion): string { | ||||
|     const major = version.version[0]; | ||||
|     const minor = version.version[1]; | ||||
|     const patch = version.version[2]; | ||||
|     return `${major}.${minor}.${patch}`; | ||||
|     return releases; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,12 +1,2 @@ | ||||
| type OsVersions = 'linux' | 'macos' | 'windows'; | ||||
| type ArchiveType = 'tar.gz' | 'zip'; | ||||
|  | ||||
| export interface PlatformOptions { | ||||
|   archive: ArchiveType; | ||||
|   os: OsVersions; | ||||
| } | ||||
|  | ||||
| export interface MicrosoftVersion { | ||||
|   downloadUrl?: string; | ||||
|   version: Array<number>; | ||||
| } | ||||
|  | ||||
| @ -6,6 +6,7 @@ | ||||
|     "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ | ||||
|     // "allowJs": true,                       /* Allow javascript files to be compiled. */ | ||||
|     // "checkJs": true,                       /* Report errors in .js files. */ | ||||
|     "resolveJsonModule": true, | ||||
|     // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ | ||||
|     // "declaration": true,                   /* Generates corresponding '.d.ts' file. */ | ||||
|     // "declarationMap": true,                /* Generates a sourcemap for each corresponding '.d.ts' file. */ | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Dmitry Shibanov
					Dmitry Shibanov