2022-12-13 12:45:14 +01:00
import fs from 'fs' ;
2019-07-10 10:54:25 -04:00
import * as core from '@actions/core' ;
2026-08-04 21:54:10 -04:00
import {
getBooleanInput ,
getVersionFromFileContent ,
isJdkCacheEnabled
} from './util.js' ;
2026-07-08 14:45:00 +05:30
import * as constants from './constants.js' ;
2019-07-11 22:57:54 -04:00
import * as path from 'path' ;
2026-07-08 14:45:00 +05:30
import { fileURLToPath } from 'url' ;
import { getJavaDistribution } from './distributions/distribution-factory.js' ;
import { JavaInstallerOptions } from './distributions/base-models.js' ;
2026-07-16 11:28:10 -04:00
import { configureProblemMatcher } from './problem-matcher.js' ;
2026-07-30 15:09:35 -04:00
import { validateToolchainIds } from './toolchain-ids.js' ;
2019-07-10 10:54:25 -04:00
2026-07-29 00:36:12 -04:00
export async function run() {
2026-07-29 17:53:33 -04:00
const versions = core . getMultilineInput ( constants . INPUT_JAVA_VERSION );
let distributionName = core . getInput ( constants . INPUT_DISTRIBUTION );
const versionFile = core . getInput ( constants . INPUT_JAVA_VERSION_FILE );
const architecture = core . getInput ( constants . INPUT_ARCHITECTURE );
const packageType = core . getInput ( constants . INPUT_JAVA_PACKAGE );
const jdkFile = getJdkFileInput ();
const cache = core . getInput ( constants . INPUT_CACHE );
2026-08-04 21:54:10 -04:00
const cacheJdk = isJdkCacheEnabled ( cache );
2026-07-29 17:53:33 -04:00
const cacheDependencyPath = core . getInput (
constants . INPUT_CACHE_DEPENDENCY_PATH
);
const cachePath = core . getMultilineInput ( constants . INPUT_CACHE_PATH );
const checkLatest = getBooleanInput ( constants . INPUT_CHECK_LATEST , false );
const forceDownload = getBooleanInput ( constants . INPUT_FORCE_DOWNLOAD , false );
const setDefault = getBooleanInput ( constants . INPUT_SET_DEFAULT , true );
const verifySignature = getBooleanInput (
constants . INPUT_VERIFY_SIGNATURE ,
false
);
const verifySignaturePublicKey =
core . getInput ( constants . INPUT_VERIFY_SIGNATURE_PUBLIC_KEY ) || undefined ;
const toolchainIds = core . getMultilineInput ( constants . INPUT_MVN_TOOLCHAIN_ID );
let actionError : Error | undefined ;
let cacheRestore : Promise < void > | undefined ;
2026-07-30 15:09:35 -04:00
const toolchainConfigurations : ToolchainConfiguration [] = [];
2026-07-29 17:53:33 -04:00
try {
2022-12-13 12:45:14 +01:00
core . startGroup ( 'Installed distributions' );
if ( ! versions . length && ! versionFile ) {
throw new Error ( 'java-version or java-version-file input expected' );
}
2021-04-05 13:02:27 +03:00
2026-07-30 15:09:35 -04:00
validateToolchainIds ( versions , versionFile , toolchainIds );
2026-07-28 23:33:41 -04:00
2022-12-13 12:45:14 +01:00
if ( ! versions . length ) {
2023-03-09 14:49:35 +02:00
core . debug (
'java-version input is empty, looking for java-version-file input'
);
const content = fs . readFileSync ( versionFile ). toString (). trim ();
2022-12-13 12:45:14 +01:00
2026-07-07 20:49:12 +02:00
const versionInfo = getVersionFromFileContent (
2024-03-12 19:15:42 +05:30
content ,
distributionName ,
versionFile
);
2026-07-07 20:49:12 +02:00
core . debug ( `Parsed version from file ' ${ versionInfo ? . version } '` );
2022-12-13 12:45:14 +01:00
2026-07-07 20:49:12 +02:00
if ( ! versionInfo ) {
2023-03-09 14:49:35 +02:00
throw new Error (
`No supported version was found in file ${ versionFile } `
);
2022-09-08 15:26:54 +02:00
}
2026-07-07 20:49:12 +02:00
// Use distribution from file if available, otherwise use the input
if ( versionInfo . distribution ) {
core . info (
`Using distribution ' ${ versionInfo . distribution } ' from ${ versionFile } `
);
distributionName = versionInfo . distribution ;
} else if ( ! distributionName ) {
throw new Error (
'distribution input is required when not specified in the version file'
);
}
2022-09-08 15:26:54 +02:00
2026-07-07 20:49:12 +02:00
const installerInputsOptions : installerInputsOptions = {
architecture ,
packageType ,
checkLatest ,
2026-07-28 14:43:47 -04:00
forceDownload ,
2026-08-04 21:54:10 -04:00
cacheJdk ,
2026-07-07 20:49:12 +02:00
setDefault ,
verifySignature ,
verifySignaturePublicKey ,
distributionName ,
jdkFile ,
toolchainIds
};
2026-07-29 17:53:33 -04:00
cacheRestore = cache
? startCacheRestore ( cache , cacheDependencyPath , cachePath )
: undefined ;
2026-07-30 15:09:35 -04:00
toolchainConfigurations . push (
await installVersion ( versionInfo . version , installerInputsOptions )
);
2026-07-07 20:49:12 +02:00
} else {
// When using java-version input, distribution is still required
if ( ! distributionName ) {
throw new Error ( 'distribution input is required' );
}
const installerInputsOptions : installerInputsOptions = {
architecture ,
packageType ,
checkLatest ,
2026-07-28 14:43:47 -04:00
forceDownload ,
2026-08-04 21:54:10 -04:00
cacheJdk ,
2026-07-07 20:49:12 +02:00
setDefault ,
verifySignature ,
verifySignaturePublicKey ,
distributionName ,
jdkFile ,
toolchainIds
};
2026-07-29 17:53:33 -04:00
cacheRestore = cache
? startCacheRestore ( cache , cacheDependencyPath , cachePath )
: undefined ;
2026-07-07 20:49:12 +02:00
for ( const [ index , version ] of versions . entries ()) {
2026-07-30 15:09:35 -04:00
toolchainConfigurations . push (
await installVersion ( version , installerInputsOptions , index )
);
2026-07-07 20:49:12 +02:00
}
2019-08-13 16:24:39 -04:00
}
2022-09-08 15:26:54 +02:00
core . endGroup ();
2026-07-08 14:45:00 +05:30
const matchersPath = path . join (
path . dirname ( fileURLToPath ( import . meta . url )),
'..' ,
'..' ,
'.github'
);
2026-07-16 11:28:10 -04:00
configureProblemMatcher ( path . join ( matchersPath , 'java.json' ));
2019-11-28 09:52:58 -08:00
2026-07-30 15:09:35 -04:00
await configureMaven ( toolchainConfigurations );
2019-07-10 23:11:48 -04:00
} catch ( error ) {
2026-07-29 17:53:33 -04:00
actionError = error as Error ;
}
if ( cacheRestore ) {
try {
await cacheRestore ;
} catch ( error ) {
if ( ! actionError ) {
actionError = error as Error ;
}
}
}
if ( actionError ) {
core . setFailed ( actionError . message );
2019-07-10 23:11:48 -04:00
}
2019-07-10 10:54:25 -04:00
}
2026-07-29 00:36:12 -04:00
if ( process . argv [ 1 ] === fileURLToPath ( import . meta . url )) {
run ();
} else {
// https://nodejs.org/api/modules.html#modules_accessing_the_main_module
core . info ( 'the script is loaded as a module, so skipping the execution' );
}
2022-12-13 12:45:14 +01:00
2026-07-08 12:44:58 -04:00
function getJdkFileInput () : string {
const jdkFile = core . getInput ( constants . INPUT_JDK_FILE );
const deprecatedJdkFile = core . getInput ( constants . INPUT_JDK_FILE_DEPRECATED );
if ( deprecatedJdkFile ) {
core . warning (
`The ' ${ constants . INPUT_JDK_FILE_DEPRECATED } ' input is deprecated and may be removed in a future release. Please use ' ${ constants . INPUT_JDK_FILE } ' instead.`
);
}
return jdkFile || deprecatedJdkFile ;
}
2023-03-09 14:49:35 +02:00
async function installVersion (
version : string ,
options : installerInputsOptions ,
toolchainId = 0
2026-07-30 15:09:35 -04:00
) : Promise < ToolchainConfiguration > {
2022-12-13 12:45:14 +01:00
const {
distributionName ,
jdkFile ,
architecture ,
packageType ,
checkLatest ,
2026-07-28 14:43:47 -04:00
forceDownload ,
2026-08-04 21:54:10 -04:00
cacheJdk ,
2026-07-07 18:38:57 +02:00
setDefault ,
2026-06-29 13:19:49 +01:00
verifySignature ,
verifySignaturePublicKey ,
2022-12-13 12:45:14 +01:00
toolchainIds
} = options ;
const installerOptions : JavaInstallerOptions = {
architecture ,
packageType ,
checkLatest ,
2026-07-28 14:43:47 -04:00
forceDownload ,
2026-08-04 21:54:10 -04:00
cacheJdk ,
2026-07-07 18:38:57 +02:00
setDefault ,
2026-06-29 13:19:49 +01:00
verifySignature ,
verifySignaturePublicKey ,
2022-12-13 12:45:14 +01:00
version
};
2026-07-29 17:53:33 -04:00
const distribution = await getJavaDistribution (
2023-03-09 14:49:35 +02:00
distributionName ,
installerOptions ,
jdkFile
);
2022-12-13 12:45:14 +01:00
if ( ! distribution ) {
2023-03-09 14:49:35 +02:00
throw new Error (
`No supported distribution was found for input ${ distributionName } `
);
2022-12-13 12:45:14 +01:00
}
const result = await distribution . setupJava ();
2026-07-09 20:11:03 -04:00
// When the `latest` alias is used, the literal input isn't a real version, so
// pass the resolved version to the toolchains configuration instead.
const isLatest = version . trim (). toLowerCase () === 'latest' ;
const toolchainVersion = isLatest ? result.version : version ;
2022-12-13 12:45:14 +01:00
core . info ( '' );
core . info ( 'Java configuration:' );
core . info ( ` Distribution: ${ distributionName } ` );
core . info ( ` Version: ${ result . version } ` );
core . info ( ` Path: ${ result . path } ` );
core . info ( '' );
2026-07-30 15:09:35 -04:00
return {
version : toolchainVersion ,
distributionName ,
path : result.path ,
toolchainId : toolchainIds [ toolchainId ]
};
2022-12-13 12:45:14 +01:00
}
interface installerInputsOptions {
architecture : string ;
packageType : string ;
checkLatest : boolean ;
2026-07-28 14:43:47 -04:00
forceDownload : boolean ;
2026-08-04 21:54:10 -04:00
cacheJdk : boolean ;
2026-07-07 18:38:57 +02:00
setDefault : boolean ;
2026-06-29 13:19:49 +01:00
verifySignature : boolean ;
verifySignaturePublicKey : string | undefined ;
2022-12-13 12:45:14 +01:00
distributionName : string ;
jdkFile : string ;
toolchainIds : Array < string >;
}
2026-07-29 17:53:33 -04:00
2026-07-30 15:09:35 -04:00
interface ToolchainConfiguration {
version : string ;
distributionName : string ;
path : string ;
toolchainId? : string ;
}
async function configureMaven (
toolchainConfigurations : ToolchainConfiguration []
) : Promise < void > {
const authentication = import ( './auth.js' ). then ( auth =>
auth . configureAuthentication ()
);
const toolchains = configureInstalledToolchains ( toolchainConfigurations );
const results = await Promise . allSettled ([ authentication , toolchains ]);
const failure = results . find (
( result ) : result is PromiseRejectedResult => result . status === 'rejected'
);
if ( failure ) {
throw failure . reason ;
}
const { configureMavenArgs } = await import ( './maven-args.js' );
configureMavenArgs ();
}
async function configureInstalledToolchains (
toolchainConfigurations : ToolchainConfiguration []
) : Promise < void > {
const toolchains = await import ( './toolchains.js' );
for ( const configuration of toolchainConfigurations ) {
await toolchains . configureToolchains (
configuration . version ,
configuration . distributionName ,
configuration . path ,
configuration . toolchainId
);
}
}
2026-07-29 17:53:33 -04:00
async function startCacheRestore (
cache : string ,
cacheDependencyPath : string ,
cachePath : string []
) : Promise < void > {
const { isCacheFeatureAvailable } = await import ( './cache-feature.js' );
if ( ! isCacheFeatureAvailable ()) {
return ;
}
const { restore } = await import ( './cache.js' );
await restore ( cache , cacheDependencyPath , cachePath );
}