Set default signature verification for supported distributions (#1246)

* Default signature verification for supported distributions

* Delegate signature defaults to installers
This commit is contained in:
John 2026-08-24 15:08:03 +01:00 committed by GitHub
parent 1dbac3c9e1
commit b96213d9d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 82 additions and 19 deletions

View File

@ -159,7 +159,7 @@ steps:
| `force-download` | Always download Java and replace any matching version in the tool cache. | `false` | | `force-download` | Always download Java and replace any matching version in the tool cache. | `false` |
| `set-default` | Add Java to `PATH` and set `JAVA_HOME`. When `false`, only version-specific `JAVA_HOME_<major>_<arch>` variables are set. | `true` | | `set-default` | Add Java to `PATH` and set `JAVA_HOME`. When `false`, only version-specific `JAVA_HOME_<major>_<arch>` variables are set. | `true` |
| `problem-matcher` | Register Java compiler and uncaught exception problem matchers. | `true` | | `problem-matcher` | Register Java compiler and uncaught exception problem matchers. | `true` |
| `verify-signature` | Verify downloaded Java package signatures when supported. Currently supported for `temurin` and `microsoft`. | `false` | | `verify-signature` | Verify downloaded Java package signatures when supported. Defaults to `true` for `temurin` and `microsoft`, and `false` for other distributions. | Automatically enabled for `temurin` and `microsoft` |
| `verify-signature-public-key` | ASCII-armored GPG public key to use for signature verification. Overrides the bundled key. | | | `verify-signature-public-key` | ASCII-armored GPG public key to use for signature verification. Overrides the bundled key. | |
| `token` | Token for fetching GitHub.com-hosted version manifests, useful on GitHub Enterprise Server when unauthenticated requests are rate-limited. | `${{ github.token }}` on GitHub.com; empty string on GHES | | `token` | Token for fetching GitHub.com-hosted version manifests, useful on GitHub Enterprise Server when unauthenticated requests are rate-limited. | `${{ github.token }}` on GitHub.com; empty string on GHES |
| `cache` | Enable dependency caching for `maven`, `gradle`, or `sbt`. | | | `cache` | Enable dependency caching for `maven`, `gradle`, or `sbt`. | |

View File

@ -398,13 +398,12 @@ describe('downloadTool', () => {
jest.restoreAllMocks(); jest.restoreAllMocks();
}); });
it('verifies signature when enabled', async () => { it('verifies signatures by default', async () => {
const signedDistribution = new MicrosoftDistributions({ const signedDistribution = new MicrosoftDistributions({
version: '17', version: '17',
architecture: 'x64', architecture: 'x64',
packageType: 'jdk', packageType: 'jdk',
checkLatest: false, checkLatest: false
verifySignature: true
}); });
await signedDistribution['downloadTool']({ await signedDistribution['downloadTool']({

View File

@ -457,14 +457,13 @@ describe('downloadTool', () => {
jest.restoreAllMocks(); jest.restoreAllMocks();
}); });
it('verifies signature when enabled', async () => { it('verifies signatures by default', async () => {
const distribution = new TemurinDistribution( const distribution = new TemurinDistribution(
{ {
version: '17', version: '17',
architecture: 'x64', architecture: 'x64',
packageType: 'jdk', packageType: 'jdk',
checkLatest: false, checkLatest: false
verifySignature: true
}, },
TemurinImplementation.Hotspot TemurinImplementation.Hotspot
); );
@ -482,6 +481,27 @@ describe('downloadTool', () => {
); );
}); });
it('does not verify signatures when explicitly disabled', async () => {
const distribution = new TemurinDistribution(
{
version: '17',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false,
verifySignature: false
},
TemurinImplementation.Hotspot
);
await distribution['downloadTool']({
version: '17.0.14+7',
url: 'https://example.com/jdk.tar.gz',
signatureUrl: 'https://example.com/jdk.tar.gz.sig'
});
expect(spyVerifySignature).not.toHaveBeenCalled();
});
it('downloads and adds matching JMODs to the JDK', async () => { it('downloads and adds matching JMODs to the JDK', async () => {
spyDownloadTool spyDownloadTool
.mockResolvedValueOnce('/tmp/jdk.tar.gz') .mockResolvedValueOnce('/tmp/jdk.tar.gz')
@ -499,7 +519,8 @@ describe('downloadTool', () => {
version: '25', version: '25',
architecture: 'x64', architecture: 'x64',
packageType: 'jdk+jmods', packageType: 'jdk+jmods',
checkLatest: false checkLatest: false,
verifySignature: false
}, },
TemurinImplementation.Hotspot TemurinImplementation.Hotspot
); );

View File

@ -161,6 +161,37 @@ describe('setup action orchestration', () => {
expect(factory.getJavaDistribution).not.toHaveBeenCalled(); expect(factory.getJavaDistribution).not.toHaveBeenCalled();
}); });
it.each([
['temurin', undefined, undefined],
['zulu', undefined, undefined],
['temurin', false, false],
['zulu', true, true]
])(
'passes signature verification input for %s with explicit value %s as %s',
async (distribution, explicitValue, expectedValue) => {
inputs.set('distribution', distribution);
multilineInputs.set('java-version', ['21']);
if (explicitValue !== undefined) {
inputs.set('verify-signature', String(explicitValue));
booleanInputs.set('verify-signature', explicitValue);
}
(factory.getJavaDistribution as jest.Mock).mockReturnValue({
setupJava: jest.fn(async () => ({
version: '21.0.4+7',
path: '/opt/java/21'
}))
});
await run();
expect(factory.getJavaDistribution).toHaveBeenCalledWith(
distribution,
expect.objectContaining({verifySignature: expectedValue}),
''
);
}
);
it('requires distribution when it cannot be inferred from the version file', async () => { it('requires distribution when it cannot be inferred from the version file', async () => {
inputs.set('java-version-file', '.java-version'); inputs.set('java-version-file', '.java-version');
(fs.readFileSync as jest.Mock).mockReturnValue(Buffer.from('21')); (fs.readFileSync as jest.Mock).mockReturnValue(Buffer.from('21'));
@ -200,7 +231,6 @@ describe('setup action orchestration', () => {
booleanInputs.set('check-latest', true); booleanInputs.set('check-latest', true);
booleanInputs.set('force-download', true); booleanInputs.set('force-download', true);
booleanInputs.set('set-default', false); booleanInputs.set('set-default', false);
booleanInputs.set('verify-signature', true);
inputs.set('verify-signature-public-key', 'public-key'); inputs.set('verify-signature-public-key', 'public-key');
(fs.readFileSync as jest.Mock).mockReturnValue( (fs.readFileSync as jest.Mock).mockReturnValue(
Buffer.from('java=21.0.5-tem') Buffer.from('java=21.0.5-tem')
@ -232,7 +262,7 @@ describe('setup action orchestration', () => {
forceDownload: true, forceDownload: true,
cacheJdk: false, cacheJdk: false,
setDefault: false, setDefault: false,
verifySignature: true, verifySignature: undefined,
verifySignaturePublicKey: 'public-key' verifySignaturePublicKey: 'public-key'
}, },
'/tmp/java.tar.gz' '/tmp/java.tar.gz'

View File

@ -41,7 +41,6 @@ inputs:
verify-signature: verify-signature:
description: 'Verify downloaded Java package signatures when supported by the selected distribution' description: 'Verify downloaded Java package signatures when supported by the selected distribution'
required: false required: false
default: false
verify-signature-public-key: verify-signature-public-key:
description: 'ASCII-armored GPG public key used to verify the downloaded package signature. Overrides the default bundled key for the selected distribution.' description: 'ASCII-armored GPG public key used to verify the downloaded package signature. Overrides the default bundled key for the selected distribution.'
required: false required: false

View File

@ -244,7 +244,8 @@ class JavaBase {
installerOptions.setDefault !== undefined installerOptions.setDefault !== undefined
? installerOptions.setDefault ? installerOptions.setDefault
: true; : true;
this.verifySignature = installerOptions.verifySignature ?? false; this.verifySignature =
installerOptions.verifySignature ?? this.supportsSignatureVerification();
this.verifySignaturePublicKey = installerOptions.verifySignaturePublicKey; this.verifySignaturePublicKey = installerOptions.verifySignaturePublicKey;
} }
async downloadAndVerify(javaRelease) { async downloadAndVerify(javaRelease) {

8
dist/setup/index.js vendored
View File

@ -36376,7 +36376,6 @@ async function run() {
const checkLatest = (0,util/* getBooleanInput */.Vt)(constants/* INPUT_CHECK_LATEST */.YM, false); const checkLatest = (0,util/* getBooleanInput */.Vt)(constants/* INPUT_CHECK_LATEST */.YM, false);
const forceDownload = (0,util/* getBooleanInput */.Vt)(constants/* INPUT_FORCE_DOWNLOAD */.I9, false); const forceDownload = (0,util/* getBooleanInput */.Vt)(constants/* INPUT_FORCE_DOWNLOAD */.I9, false);
const setDefault = (0,util/* getBooleanInput */.Vt)(constants/* INPUT_SET_DEFAULT */.E8, true); const setDefault = (0,util/* getBooleanInput */.Vt)(constants/* INPUT_SET_DEFAULT */.E8, true);
const verifySignature = (0,util/* getBooleanInput */.Vt)(constants/* INPUT_VERIFY_SIGNATURE */.qy, false);
const verifySignaturePublicKey = setup_java_core/* getInput */.V4(constants/* INPUT_VERIFY_SIGNATURE_PUBLIC_KEY */.u) || undefined; const verifySignaturePublicKey = setup_java_core/* getInput */.V4(constants/* INPUT_VERIFY_SIGNATURE_PUBLIC_KEY */.u) || undefined;
const toolchainIds = setup_java_core/* getMultilineInput */.q3(constants/* INPUT_MVN_TOOLCHAIN_ID */.nr); const toolchainIds = setup_java_core/* getMultilineInput */.q3(constants/* INPUT_MVN_TOOLCHAIN_ID */.nr);
let actionError; let actionError;
@ -36404,6 +36403,7 @@ async function run() {
else if (!distributionName) { else if (!distributionName) {
throw new Error('distribution input is required when not specified in the version file'); throw new Error('distribution input is required when not specified in the version file');
} }
const verifySignature = getVerifySignatureInput();
const installerInputsOptions = { const installerInputsOptions = {
architecture, architecture,
packageType, packageType,
@ -36428,6 +36428,7 @@ async function run() {
if (!distributionName) { if (!distributionName) {
throw new Error('distribution input is required'); throw new Error('distribution input is required');
} }
const verifySignature = getVerifySignatureInput();
const installerInputsOptions = { const installerInputsOptions = {
architecture, architecture,
packageType, packageType,
@ -36492,6 +36493,11 @@ function getJdkFileInput() {
} }
return jdkFile || deprecatedJdkFile; return jdkFile || deprecatedJdkFile;
} }
function getVerifySignatureInput() {
return setup_java_core/* getInput */.V4(constants/* INPUT_VERIFY_SIGNATURE */.qy).trim()
? (0,util/* getBooleanInput */.Vt)(constants/* INPUT_VERIFY_SIGNATURE */.qy)
: undefined;
}
async function installVersion(version, options, toolchainId = 0) { async function installVersion(version, options, toolchainId = 0) {
const { distributionName, jdkFile, architecture, packageType, checkLatest, forceDownload, cacheJdk, setDefault, verifySignature, verifySignaturePublicKey, toolchainIds } = options; const { distributionName, jdkFile, architecture, packageType, checkLatest, forceDownload, cacheJdk, setDefault, verifySignature, verifySignaturePublicKey, toolchainIds } = options;
const installerOptions = { const installerOptions = {

View File

@ -68,7 +68,8 @@ export abstract class JavaBase {
installerOptions.setDefault !== undefined installerOptions.setDefault !== undefined
? installerOptions.setDefault ? installerOptions.setDefault
: true; : true;
this.verifySignature = installerOptions.verifySignature ?? false; this.verifySignature =
installerOptions.verifySignature ?? this.supportsSignatureVerification();
this.verifySignaturePublicKey = installerOptions.verifySignaturePublicKey; this.verifySignaturePublicKey = installerOptions.verifySignaturePublicKey;
} }

View File

@ -29,10 +29,6 @@ export async function run() {
const checkLatest = getBooleanInput(constants.INPUT_CHECK_LATEST, false); const checkLatest = getBooleanInput(constants.INPUT_CHECK_LATEST, false);
const forceDownload = getBooleanInput(constants.INPUT_FORCE_DOWNLOAD, false); const forceDownload = getBooleanInput(constants.INPUT_FORCE_DOWNLOAD, false);
const setDefault = getBooleanInput(constants.INPUT_SET_DEFAULT, true); const setDefault = getBooleanInput(constants.INPUT_SET_DEFAULT, true);
const verifySignature = getBooleanInput(
constants.INPUT_VERIFY_SIGNATURE,
false
);
const verifySignaturePublicKey = const verifySignaturePublicKey =
core.getInput(constants.INPUT_VERIFY_SIGNATURE_PUBLIC_KEY) || undefined; core.getInput(constants.INPUT_VERIFY_SIGNATURE_PUBLIC_KEY) || undefined;
const toolchainIds = core.getMultilineInput(constants.INPUT_MVN_TOOLCHAIN_ID); const toolchainIds = core.getMultilineInput(constants.INPUT_MVN_TOOLCHAIN_ID);
@ -80,6 +76,8 @@ export async function run() {
); );
} }
const verifySignature = getVerifySignatureInput();
const installerInputsOptions: installerInputsOptions = { const installerInputsOptions: installerInputsOptions = {
architecture, architecture,
packageType, packageType,
@ -107,6 +105,8 @@ export async function run() {
throw new Error('distribution input is required'); throw new Error('distribution input is required');
} }
const verifySignature = getVerifySignatureInput();
const installerInputsOptions: installerInputsOptions = { const installerInputsOptions: installerInputsOptions = {
architecture, architecture,
packageType, packageType,
@ -192,6 +192,12 @@ function getJdkFileInput(): string {
return jdkFile || deprecatedJdkFile; return jdkFile || deprecatedJdkFile;
} }
function getVerifySignatureInput(): boolean | undefined {
return core.getInput(constants.INPUT_VERIFY_SIGNATURE).trim()
? getBooleanInput(constants.INPUT_VERIFY_SIGNATURE)
: undefined;
}
async function installVersion( async function installVersion(
version: string, version: string,
options: installerInputsOptions, options: installerInputsOptions,
@ -263,7 +269,7 @@ interface installerInputsOptions {
forceDownload: boolean; forceDownload: boolean;
cacheJdk: boolean; cacheJdk: boolean;
setDefault: boolean; setDefault: boolean;
verifySignature: boolean; verifySignature: boolean | undefined;
verifySignaturePublicKey: string | undefined; verifySignaturePublicKey: string | undefined;
distributionName: string; distributionName: string;
jdkFile: string; jdkFile: string;