diff --git a/README.md b/README.md index 461338a9..dba72b63 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,8 @@ For more details, see the full release notes on the [releases page](https://git - `check-latest`: Setting this option makes the action to check for the latest available version for the version spec. + - `force-download`: Set to `true` to always download Java and replace any matching version in the tool cache. This can help make builds reproducible when a runner image has modified a pre-installed JDK, such as its `cacerts` file. Default value: `false`. + - `set-default`: Set to `false` to install a JDK without making it the default. When `false`, `JAVA_HOME` and `PATH` are not updated, but `JAVA_HOME__` is still set so the JDK remains discoverable. Default value: `true`. See [Installing JDK without setting as default](docs/advanced-usage.md#Installing-JDK-without-setting-as-default) for more details. - `problem-matcher`: Set to `false` to disable Java problem matcher annotations (compiler diagnostics and uncaught exceptions). Default value: `true`. See [Java problem matcher](docs/advanced-usage.md#java-problem-matcher-compiler-annotations) for details and annotation limits. diff --git a/__tests__/distributors/base-installer.test.ts b/__tests__/distributors/base-installer.test.ts index ad3b0afc..457a2b24 100644 --- a/__tests__/distributors/base-installer.test.ts +++ b/__tests__/distributors/base-installer.test.ts @@ -443,6 +443,35 @@ describe('setupJava', () => { ); }); + it('should download java when force-download is enabled, even if the version is cached', async () => { + mockJavaBase = new EmptyJavaBase({ + version: actualJavaVersion, + architecture: 'x86', + packageType: 'jdk', + checkLatest: false, + forceDownload: true + }); + const findInToolcache = jest.fn(() => ({ + version: actualJavaVersion, + path: javaPathInstalled + })); + mockJavaBase['findInToolcache'] = findInToolcache; + + await expect(mockJavaBase.setupJava()).resolves.toEqual({ + version: actualJavaVersion, + path: javaPathInstalled + }); + + expect(findInToolcache).not.toHaveBeenCalled(); + expect(spyCoreInfo).toHaveBeenCalledWith('Trying to download...'); + expect(spyCoreInfo).toHaveBeenCalledWith( + `Java ${actualJavaVersion} was downloaded` + ); + expect(spyCoreInfo).not.toHaveBeenCalledWith( + `Resolved Java ${actualJavaVersion} from tool-cache` + ); + }); + it.each([ [ { diff --git a/__tests__/distributors/local-installer.test.ts b/__tests__/distributors/local-installer.test.ts index 3266f8a8..47997888 100644 --- a/__tests__/distributors/local-installer.test.ts +++ b/__tests__/distributors/local-installer.test.ts @@ -208,6 +208,29 @@ describe('setupJava', () => { ); }); + it('java is unpacked from jdkfile when force-download is enabled', async () => { + const inputs = { + version: actualJavaVersion, + architecture: 'x86', + packageType: 'jdk', + checkLatest: false, + forceDownload: true + }; + + mockJavaBase = new LocalDistribution(inputs, expectedJdkFile); + await expect(mockJavaBase.setupJava()).resolves.toEqual({ + version: actualJavaVersion, + path: javaPath + }); + + expect(spyGetToolcachePath).not.toHaveBeenCalled(); + expect(spyUtilsExtractJdkFile).toHaveBeenCalledWith(expectedJdkFile); + expect(spyTcCacheDir).toHaveBeenCalled(); + expect(spyCoreInfo).not.toHaveBeenCalledWith( + `Resolved Java ${actualJavaVersion} from tool-cache` + ); + }); + it("java is resolved from toolcache, jdkfile doesn't exist", async () => { const inputs = { version: actualJavaVersion, diff --git a/action.yml b/action.yml index 98a95e0d..2412e840 100644 --- a/action.yml +++ b/action.yml @@ -30,6 +30,10 @@ inputs: description: 'Set this option if you want the action to check for the latest available version that satisfies the version spec' required: false default: false + force-download: + description: 'Set this option to always download Java and replace any matching version in the tool cache' + required: false + default: false set-default: description: 'Set this option to false if you want to install a JDK but not make it the default. When false, JAVA_HOME and PATH are not updated, but JAVA_HOME__ is still set.' required: false diff --git a/dist/cleanup/index.js b/dist/cleanup/index.js index fe389517..71754470 100644 --- a/dist/cleanup/index.js +++ b/dist/cleanup/index.js @@ -97311,6 +97311,7 @@ const INPUT_DISTRIBUTION = 'distribution'; const INPUT_JDK_FILE = 'jdk-file'; const INPUT_JDK_FILE_DEPRECATED = 'jdkFile'; const INPUT_CHECK_LATEST = 'check-latest'; +const INPUT_FORCE_DOWNLOAD = 'force-download'; const INPUT_SET_DEFAULT = 'set-default'; const INPUT_PROBLEM_MATCHER = 'problem-matcher'; const INPUT_VERIFY_SIGNATURE = 'verify-signature'; diff --git a/dist/setup/index.js b/dist/setup/index.js index c547ea81..10be0455 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -72088,6 +72088,7 @@ const INPUT_DISTRIBUTION = 'distribution'; const INPUT_JDK_FILE = 'jdk-file'; const INPUT_JDK_FILE_DEPRECATED = 'jdkFile'; const INPUT_CHECK_LATEST = 'check-latest'; +const INPUT_FORCE_DOWNLOAD = 'force-download'; const INPUT_SET_DEFAULT = 'set-default'; const INPUT_PROBLEM_MATCHER = 'problem-matcher'; const INPUT_VERIFY_SIGNATURE = 'verify-signature'; @@ -129290,6 +129291,7 @@ class JavaBase { stable; latest; checkLatest; + forceDownload; setDefault; verifySignature; verifySignaturePublicKey; @@ -129307,6 +129309,7 @@ class JavaBase { this.architecture = installerOptions.architecture || external_os_default().arch(); this.packageType = installerOptions.packageType; this.checkLatest = installerOptions.checkLatest; + this.forceDownload = installerOptions.forceDownload ?? false; this.setDefault = installerOptions.setDefault !== undefined ? installerOptions.setDefault @@ -129318,7 +129321,7 @@ class JavaBase { if (this.verifySignature && !this.supportsSignatureVerification()) { throw new Error(`Input 'verify-signature' is not supported for distribution '${this.distribution}'.`); } - let foundJava = this.findInToolcache(); + let foundJava = this.forceDownload ? null : this.findInToolcache(); if (foundJava && !this.checkLatest && !this.latest) { info(`Resolved Java ${foundJava.version} from tool-cache`); } @@ -129342,7 +129345,8 @@ class JavaBase { } const javaRelease = await this.findPackageForDownload(this.version); info(`Resolved latest version as ${javaRelease.version}`); - if (foundJava?.version === javaRelease.version) { + if (!this.forceDownload && + foundJava?.version === javaRelease.version) { info(`Resolved Java ${foundJava.version} from tool-cache`); } else { @@ -129617,7 +129621,7 @@ class LocalDistribution extends JavaBase { if (this.latest) { throw new Error("The 'latest' version alias is not supported for the 'jdkfile' distribution. Please specify a concrete version."); } - let foundJava = this.findInToolcache(); + let foundJava = this.forceDownload ? null : this.findInToolcache(); if (foundJava) { info(`Resolved Java ${foundJava.version} from tool-cache`); } @@ -132041,6 +132045,7 @@ async function run() { const cache = getInput(INPUT_CACHE); const cacheDependencyPath = getInput(INPUT_CACHE_DEPENDENCY_PATH); const checkLatest = util_getBooleanInput(INPUT_CHECK_LATEST, false); + const forceDownload = util_getBooleanInput(INPUT_FORCE_DOWNLOAD, false); const setDefault = util_getBooleanInput(INPUT_SET_DEFAULT, true); const verifySignature = util_getBooleanInput(INPUT_VERIFY_SIGNATURE, false); const verifySignaturePublicKey = getInput(INPUT_VERIFY_SIGNATURE_PUBLIC_KEY) || undefined; @@ -132072,6 +132077,7 @@ async function run() { architecture, packageType, checkLatest, + forceDownload, setDefault, verifySignature, verifySignaturePublicKey, @@ -132090,6 +132096,7 @@ async function run() { architecture, packageType, checkLatest, + forceDownload, setDefault, verifySignature, verifySignaturePublicKey, @@ -132124,11 +132131,12 @@ function getJdkFileInput() { return jdkFile || deprecatedJdkFile; } async function installVersion(version, options, toolchainId = 0) { - const { distributionName, jdkFile, architecture, packageType, checkLatest, setDefault, verifySignature, verifySignaturePublicKey, toolchainIds } = options; + const { distributionName, jdkFile, architecture, packageType, checkLatest, forceDownload, setDefault, verifySignature, verifySignaturePublicKey, toolchainIds } = options; const installerOptions = { architecture, packageType, checkLatest, + forceDownload, setDefault, verifySignature, verifySignaturePublicKey, diff --git a/src/constants.ts b/src/constants.ts index 145d78b4..e1688db4 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -7,6 +7,7 @@ export const INPUT_DISTRIBUTION = 'distribution'; export const INPUT_JDK_FILE = 'jdk-file'; export const INPUT_JDK_FILE_DEPRECATED = 'jdkFile'; export const INPUT_CHECK_LATEST = 'check-latest'; +export const INPUT_FORCE_DOWNLOAD = 'force-download'; export const INPUT_SET_DEFAULT = 'set-default'; export const INPUT_PROBLEM_MATCHER = 'problem-matcher'; export const INPUT_VERIFY_SIGNATURE = 'verify-signature'; diff --git a/src/distributions/base-installer.ts b/src/distributions/base-installer.ts index 07e7c444..c00d21d2 100644 --- a/src/distributions/base-installer.ts +++ b/src/distributions/base-installer.ts @@ -25,6 +25,7 @@ export abstract class JavaBase { protected stable: boolean; protected latest: boolean; protected checkLatest: boolean; + protected forceDownload: boolean; protected setDefault: boolean; protected verifySignature: boolean; protected verifySignaturePublicKey: string | undefined; @@ -46,6 +47,7 @@ export abstract class JavaBase { this.architecture = installerOptions.architecture || os.arch(); this.packageType = installerOptions.packageType; this.checkLatest = installerOptions.checkLatest; + this.forceDownload = installerOptions.forceDownload ?? false; this.setDefault = installerOptions.setDefault !== undefined ? installerOptions.setDefault @@ -68,7 +70,7 @@ export abstract class JavaBase { ); } - let foundJava = this.findInToolcache(); + let foundJava = this.forceDownload ? null : this.findInToolcache(); if (foundJava && !this.checkLatest && !this.latest) { core.info(`Resolved Java ${foundJava.version} from tool-cache`); } else { @@ -91,7 +93,10 @@ export abstract class JavaBase { } const javaRelease = await this.findPackageForDownload(this.version); core.info(`Resolved latest version as ${javaRelease.version}`); - if (foundJava?.version === javaRelease.version) { + if ( + !this.forceDownload && + foundJava?.version === javaRelease.version + ) { core.info(`Resolved Java ${foundJava.version} from tool-cache`); } else { core.info('Trying to download...'); diff --git a/src/distributions/base-models.ts b/src/distributions/base-models.ts index b2ca3f0f..3bfe4bb9 100644 --- a/src/distributions/base-models.ts +++ b/src/distributions/base-models.ts @@ -3,6 +3,7 @@ export interface JavaInstallerOptions { architecture: string; packageType: string; checkLatest: boolean; + forceDownload?: boolean; setDefault?: boolean; verifySignature?: boolean; verifySignaturePublicKey?: string; diff --git a/src/distributions/local/installer.ts b/src/distributions/local/installer.ts index 6447c429..840c19dc 100644 --- a/src/distributions/local/installer.ts +++ b/src/distributions/local/installer.ts @@ -28,7 +28,7 @@ export class LocalDistribution extends JavaBase { ); } - let foundJava = this.findInToolcache(); + let foundJava = this.forceDownload ? null : this.findInToolcache(); if (foundJava) { core.info(`Resolved Java ${foundJava.version} from tool-cache`); diff --git a/src/setup-java.ts b/src/setup-java.ts index 3efaf912..cc0f9370 100644 --- a/src/setup-java.ts +++ b/src/setup-java.ts @@ -29,6 +29,10 @@ async function run() { constants.INPUT_CACHE_DEPENDENCY_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, @@ -83,6 +87,7 @@ async function run() { architecture, packageType, checkLatest, + forceDownload, setDefault, verifySignature, verifySignaturePublicKey, @@ -102,6 +107,7 @@ async function run() { architecture, packageType, checkLatest, + forceDownload, setDefault, verifySignature, verifySignaturePublicKey, @@ -159,6 +165,7 @@ async function installVersion( architecture, packageType, checkLatest, + forceDownload, setDefault, verifySignature, verifySignaturePublicKey, @@ -169,6 +176,7 @@ async function installVersion( architecture, packageType, checkLatest, + forceDownload, setDefault, verifySignature, verifySignaturePublicKey, @@ -212,6 +220,7 @@ interface installerInputsOptions { architecture: string; packageType: string; checkLatest: boolean; + forceDownload: boolean; setDefault: boolean; verifySignature: boolean; verifySignaturePublicKey: string | undefined;