2023-03-09 14:49:35 +02:00
import { JavaBase } from '../base-installer' ;
import {
JavaDownloadRelease ,
JavaInstallerOptions ,
JavaInstallerResults
} from '../base-models' ;
2023-09-20 19:22:11 +08:00
import {
extractJdkFile ,
getDownloadArchiveExtension ,
2024-10-11 03:02:25 +05:30
getGitHubHttpHeaders ,
renameWinArchive
2023-09-20 19:22:11 +08:00
} from '../../util' ;
2026-06-29 13:19:49 +01:00
import * as gpg from '../../gpg' ;
import { MICROSOFT_PUBLIC_KEY } from './microsoft-key' ;
2021-12-08 10:50:14 -08:00
import * as core from '@actions/core' ;
import * as tc from '@actions/tool-cache' ;
import fs from 'fs' ;
import path from 'path' ;
2023-11-29 19:41:46 +05:30
import { TypedResponse } from '@actions/http-client/lib/interfaces' ;
2021-12-08 10:50:14 -08:00
2026-06-29 13:19:49 +01:00
export { MICROSOFT_PUBLIC_KEY } from './microsoft-key' ;
2021-12-08 10:50:14 -08:00
export class MicrosoftDistributions extends JavaBase {
constructor ( installerOptions : JavaInstallerOptions ) {
super ( 'Microsoft' , installerOptions ) ;
}
2023-03-09 14:49:35 +02:00
protected async downloadTool (
javaRelease : JavaDownloadRelease
) : Promise < JavaInstallerResults > {
2021-12-08 10:50:14 -08:00
core . info (
` Downloading Java ${ javaRelease . version } ( ${ this . distribution } ) from ${ javaRelease . url } ... `
) ;
2024-02-28 10:41:33 +05:30
let javaArchivePath = await tc . downloadTool ( javaRelease . url ) ;
2021-12-08 10:50:14 -08:00
2026-06-29 13:19:49 +01:00
if ( this . verifySignature ) {
if ( ! javaRelease . signatureUrl ) {
throw new Error (
` Input 'verify-signature' is enabled, but no signature URL was found for Microsoft Build of OpenJDK version ${ javaRelease . version } . `
) ;
}
core . info ( ` Verifying Java package signature... ` ) ;
try {
await gpg . verifyPackageSignature (
javaArchivePath ,
javaRelease . signatureUrl ,
this . verifySignaturePublicKey ? ? MICROSOFT_PUBLIC_KEY
) ;
} catch ( error ) {
throw new Error (
` Failed to verify signature for Microsoft Build of OpenJDK version ${ javaRelease . version } . Signature URL: ${ javaRelease . signatureUrl } . Error: ${ ( error as Error ) . message } `
) ;
}
}
2021-12-08 10:50:14 -08:00
core . info ( ` Extracting Java archive... ` ) ;
const extension = getDownloadArchiveExtension ( ) ;
2024-10-11 03:02:25 +05:30
if ( process . platform === 'win32' ) {
javaArchivePath = renameWinArchive ( javaArchivePath ) ;
}
2021-12-08 10:50:14 -08:00
const extractedJavaPath = await extractJdkFile ( javaArchivePath , extension ) ;
const archiveName = fs . readdirSync ( extractedJavaPath ) [ 0 ] ;
const archivePath = path . join ( extractedJavaPath , archiveName ) ;
const javaPath = await tc . cacheDir (
archivePath ,
this . toolcacheFolderName ,
this . getToolcacheVersionName ( javaRelease . version ) ,
this . architecture
) ;
2023-03-09 14:49:35 +02:00
return { version : javaRelease.version , path : javaPath } ;
2021-12-08 10:50:14 -08:00
}
2023-03-09 14:49:35 +02:00
protected async findPackageForDownload (
range : string
) : Promise < JavaDownloadRelease > {
2022-10-10 17:47:17 -06:00
const arch = this . distributionArchitecture ( ) ;
if ( arch !== 'x64' && arch !== 'aarch64' ) {
2021-12-08 10:50:14 -08:00
throw new Error ( ` Unsupported architecture: ${ this . architecture } ` ) ;
}
2021-12-15 18:23:49 +03:00
if ( ! this . stable ) {
throw new Error ( 'Early access versions are not supported' ) ;
}
2021-12-21 13:29:16 +03:00
if ( this . packageType !== 'jdk' ) {
2023-03-09 14:49:35 +02:00
throw new Error (
'Microsoft Build of OpenJDK provides only the `jdk` package type'
) ;
2021-12-21 13:29:16 +03:00
}
2022-09-23 14:47:30 +02:00
const manifest = await this . getAvailableVersions ( ) ;
if ( ! manifest ) {
throw new Error ( 'Could not load manifest for Microsoft Build of OpenJDK' ) ;
}
2022-10-10 17:47:17 -06:00
const foundRelease = await tc . findFromManifest ( range , true , manifest , arch ) ;
2022-09-23 14:47:30 +02:00
if ( ! foundRelease ) {
2026-04-13 23:14:45 +05:30
const availableVersionStrings = manifest . map ( item = > item . version ) ;
throw this . createVersionNotFoundError ( range , availableVersionStrings ) ;
2021-12-08 10:50:14 -08:00
}
2026-06-29 13:19:49 +01:00
const file = foundRelease . files [ 0 ] as {
download_url : string ;
signature_url? : string ;
} ;
const signatureUrl = file . signature_url ? ? ` ${ file . download_url } .sig ` ;
2023-03-09 14:49:35 +02:00
return {
2026-06-29 13:19:49 +01:00
url : file.download_url ,
signatureUrl ,
2023-03-09 14:49:35 +02:00
version : foundRelease.version
} ;
2021-12-08 10:50:14 -08:00
}
2026-06-29 13:19:49 +01:00
protected supportsSignatureVerification ( ) : boolean {
return true ;
}
2022-09-23 14:47:30 +02:00
private async getAvailableVersions ( ) : Promise < tc.IToolRelease [ ] | null > {
2021-12-08 10:50:14 -08:00
// TODO get these dynamically!
// We will need Microsoft to add an endpoint where we can query for versions.
2022-09-23 14:47:30 +02:00
const owner = 'actions' ;
const repository = 'setup-java' ;
const branch = 'main' ;
2023-03-09 14:49:35 +02:00
const filePath =
'src/distributions/microsoft/microsoft-openjdk-versions.json' ;
2022-09-23 14:47:30 +02:00
let releases : tc.IToolRelease [ ] | null = null ;
const fileUrl = ` https://api.github.com/repos/ ${ owner } / ${ repository } /contents/ ${ filePath } ?ref= ${ branch } ` ;
2023-09-20 19:22:11 +08:00
const headers = getGitHubHttpHeaders ( ) ;
2022-09-23 14:47:30 +02:00
2023-11-29 19:41:46 +05:30
let response : TypedResponse < tc.IToolRelease [ ] > | null = null ;
2022-09-23 14:47:30 +02:00
2023-03-09 14:49:35 +02:00
if ( core . isDebug ( ) ) {
console . time ( 'Retrieving available versions for Microsoft took' ) ; // eslint-disable-line no-console
}
2022-09-23 14:47:30 +02:00
try {
response = await this . http . getJson < tc.IToolRelease [ ] > ( fileUrl , headers ) ;
if ( ! response . result ) {
return null ;
2021-12-08 10:50:14 -08:00
}
2022-09-23 14:47:30 +02:00
} catch ( err ) {
core . debug (
2025-07-07 13:51:25 -05:00
` Http request for microsoft-openjdk-versions.json failed with status code: ${ response ? . statusCode } . Error: ${ err } `
2022-09-23 14:47:30 +02:00
) ;
return null ;
2021-12-08 10:50:14 -08:00
}
2022-09-23 14:47:30 +02:00
if ( response . result ) {
releases = response . result ;
2021-12-08 10:50:14 -08:00
}
2023-03-09 14:49:35 +02:00
if ( core . isDebug ( ) && releases ) {
core . startGroup ( 'Print information about available versions' ) ;
console . timeEnd ( 'Retrieving available versions for Microsoft took' ) ; // eslint-disable-line no-console
core . debug ( ` Available versions: [ ${ releases . length } ] ` ) ;
core . debug ( releases . map ( item = > item . version ) . join ( ', ' ) ) ;
core . endGroup ( ) ;
}
2022-09-23 14:47:30 +02:00
return releases ;
2021-12-08 10:50:14 -08:00
}
}