import * as c from './constants' import * as httpClient from '@actions/http-client' import {downloadExtractAndCacheJDK} from './utils' import {downloadTool} from '@actions/tool-cache' import {basename} from 'path' export const MANDREL_REPO = 'mandrel' export const MANDREL_TAG_PREFIX = c.MANDREL_NAMESPACE const MANDREL_DL_BASE = 'https://github.com/graalvm/mandrel/releases/download' const DISCO_API_BASE = 'https://api.foojay.io/disco/v3.0/packages/jdks' interface JdkData { message: string /* eslint-disable @typescript-eslint/no-explicit-any */ result: any /* eslint-enable @typescript-eslint/no-explicit-any */ } export async function setUpMandrel( mandrelVersion: string, javaVersion: string ): Promise { const version = stripMandrelNamespace(mandrelVersion) let mandrelHome switch (version) { case '': // fetch latest if no version is specified mandrelHome = await setUpMandrelLatest(javaVersion) break case 'latest': mandrelHome = await setUpMandrelLatest(javaVersion) break default: mandrelHome = await setUpMandrelRelease(version, javaVersion) break } return mandrelHome } async function setUpMandrelLatest(javaVersion: string): Promise { const latest_release_url = await getLatestMandrelReleaseUrl(javaVersion) const version_tag = getTagFromURI(latest_release_url) const version = stripMandrelNamespace(version_tag) const toolName = determineToolName(javaVersion) return downloadExtractAndCacheJDK( async () => downloadTool(latest_release_url), toolName, version ) } // Download URIs are of the form https://github.com/graalvm/mandrel/releases/download// function getTagFromURI(uri: string): string { const parts = uri.split('/') try { return parts[parts.length - 2] } catch (error) { throw new Error(`Failed to extract tag from URI ${uri}: ${error}`) } } export async function getLatestMandrelReleaseUrl( javaVersion: string ): Promise { const url = `${DISCO_API_BASE}?jdk_version=${javaVersion}&distribution=${c.DISTRIBUTION_MANDREL}&architecture=${c.JDK_ARCH}&operating_system=${c.JDK_PLATFORM}&latest=per_distro` const _http = new httpClient.HttpClient() const response = await _http.getJson(url) if (response.statusCode !== 200) { throw new Error( `Failed to fetch latest Mandrel release for Java ${javaVersion} from DISCO API: ${response.result}` ) } const result = response.result?.result[0] try { const pkg_info_uri = result.links.pkg_info_uri return await getLatestMandrelReleaseUrlHelper( _http, javaVersion, pkg_info_uri ) } catch (error) { throw new Error( `Failed to get latest Mandrel release for Java ${javaVersion} from DISCO API: ${error}` ) } } async function getLatestMandrelReleaseUrlHelper( _http: httpClient.HttpClient, java_version: string, pkg_info_uri: string ): Promise { const response = await _http.getJson(pkg_info_uri) if (response.statusCode !== 200) { throw new Error( `Failed to fetch package info of latest Mandrel release for Java ${java_version} from DISCO API: ${response.result}` ) } const result = response.result?.result[0] try { return result.direct_download_uri } catch (error) { throw new Error( `Failed to get download URI of latest Mandrel release for Java ${java_version} from DISCO API: ${error}` ) } } async function setUpMandrelRelease( version: string, javaVersion: string ): Promise { const toolName = determineToolName(javaVersion) return downloadExtractAndCacheJDK( async () => downloadMandrelJDK(version, javaVersion), toolName, version ) } async function downloadMandrelJDK( version: string, javaVersion: string ): Promise { const identifier = determineMandrelIdentifier(version, javaVersion) const downloadUrl = `${MANDREL_DL_BASE}/${MANDREL_TAG_PREFIX}${version}/${identifier}${c.GRAALVM_FILE_EXTENSION}` try { return await downloadTool(downloadUrl) } catch (error) { if (error instanceof Error && error.message.includes('404')) { // Not Found throw new Error( `Failed to download ${basename( downloadUrl )}. Are you sure version: '${version}' and java-version: '${javaVersion}' are correct?` ) } throw new Error( `Failed to download ${basename(downloadUrl)} (error: ${error}).` ) } } function determineMandrelIdentifier( version: string, javaVersion: string ): string { return `mandrel-java${javaVersion}-${c.GRAALVM_PLATFORM}-${c.GRAALVM_ARCH}-${version}` } function determineToolName(javaVersion: string): string { return `mandrel-java${javaVersion}-${c.GRAALVM_PLATFORM}` } export function stripMandrelNamespace(graalVMVersion: string) { if (graalVMVersion.startsWith(c.MANDREL_NAMESPACE)) { return graalVMVersion.substring( c.MANDREL_NAMESPACE.length, graalVMVersion.length ) } else { return graalVMVersion } }