From e1ce3a34280a05fe99f5999dadb15554bfc49ad3 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Tue, 28 Jul 2026 23:33:41 -0400 Subject: [PATCH] Fail on mismatched Maven toolchain ID counts (#1161) * Fail on mismatched Maven toolchain IDs Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8c821981-7b21-45fe-9463-5bb375d7dce4 * Clarify Maven toolchain ID version counts Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8c821981-7b21-45fe-9463-5bb375d7dce4 --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8c821981-7b21-45fe-9463-5bb375d7dce4 --- README.md | 2 +- __tests__/toolchains.test.ts | 64 ++++++++++++++++++++++++++++++++++++ action.yml | 2 +- dist/setup/index.js | 15 ++++++--- docs/advanced-usage.md | 2 +- src/setup-java.ts | 10 +++--- src/toolchains.ts | 17 ++++++++++ 7 files changed, 100 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 2218c754..06a71287 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ For more details, see the full release notes on the [releases page](https://git - `gpg-passphrase-env-var`: Environment variable name for the GPG private key passphrase. Default is GPG\_PASSPHRASE. - - `mvn-toolchain-id`: Name of Maven Toolchain ID if the default name of `${distribution}_${java-version}` is not wanted. + - `mvn-toolchain-id`: Name of Maven Toolchain ID if the default name of `${distribution}_${java-version}` is not wanted. When supplied, the number of IDs must match the number of Java versions. - `mvn-toolchain-vendor`: Name of Maven Toolchain Vendor if the default name of `${distribution}` is not wanted. diff --git a/__tests__/toolchains.test.ts b/__tests__/toolchains.test.ts index fe523aa5..f460a053 100644 --- a/__tests__/toolchains.test.ts +++ b/__tests__/toolchains.test.ts @@ -1007,3 +1007,67 @@ describe('toolchains tests', () => { expect((contents.match(//g) || []).length).toBe(runs.length); }, 100000); }); + +describe('validateToolchainIds', () => { + it.each([ + { + name: 'uses generated IDs when no custom IDs are supplied', + versions: ['17', '21'], + versionFile: '', + toolchainIds: [] + }, + { + name: 'accepts one custom ID for a single Java version', + versions: ['21'], + versionFile: '', + toolchainIds: ['custom-21'] + }, + { + name: 'accepts one custom ID per Java version', + versions: ['17', '21'], + versionFile: '', + toolchainIds: ['custom-17', 'custom-21'] + }, + { + name: 'accepts one custom ID with java-version-file', + versions: [], + versionFile: '.java-version', + toolchainIds: ['custom-file-version'] + } + ])('$name', ({versions, versionFile, toolchainIds}) => { + expect(() => + toolchains.validateToolchainIds(versions, versionFile, toolchainIds) + ).not.toThrow(); + }); + + it.each([ + { + name: 'rejects fewer IDs than Java versions', + versions: ['17', '21'], + versionFile: '', + toolchainIds: ['custom-17'], + expectedMessage: + 'The number of Maven toolchain IDs (1) must match the number of Java versions (2)' + }, + { + name: 'rejects extra IDs for a single Java version', + versions: ['21'], + versionFile: '', + toolchainIds: ['custom-21', 'custom-extra'], + expectedMessage: + 'The number of Maven toolchain IDs (2) must match the number of Java versions (1)' + }, + { + name: 'rejects extra IDs with java-version-file', + versions: [], + versionFile: '.java-version', + toolchainIds: ['custom-file-version', 'custom-extra'], + expectedMessage: + 'The number of Maven toolchain IDs (2) must match the number of Java versions (1)' + } + ])('$name', ({versions, versionFile, toolchainIds, expectedMessage}) => { + expect(() => + toolchains.validateToolchainIds(versions, versionFile, toolchainIds) + ).toThrow(expectedMessage); + }); +}); diff --git a/action.yml b/action.yml index 901c198a..264238d3 100644 --- a/action.yml +++ b/action.yml @@ -96,7 +96,7 @@ inputs: required: false default: ${{ github.server_url == 'https://github.com' && github.token || '' }} mvn-toolchain-id: - description: 'Name of Maven Toolchain ID if the default name of "${distribution}_${java-version}" is not wanted. See examples of supported syntax in Advanced Usage file' + description: 'Name of Maven Toolchain ID if the default name of "${distribution}_${java-version}" is not wanted. When supplied, the number of IDs must match the number of Java versions. See examples of supported syntax in Advanced Usage file' required: false mvn-toolchain-vendor: description: 'Name of Maven Toolchain Vendor if the default name of "${distribution}" is not wanted. See examples of supported syntax in Advanced Usage file' diff --git a/dist/setup/index.js b/dist/setup/index.js index 0ad49eb8..a5903a09 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -128876,6 +128876,15 @@ async function write(directory, settings, overwriteSettings) { +function validateToolchainIds(versions, versionFile, toolchainIds) { + if (!toolchainIds.length) { + return; + } + const versionCount = versions.length || (versionFile ? 1 : 0); + if (versionCount !== toolchainIds.length) { + throw new Error(`The number of Maven toolchain IDs (${toolchainIds.length}) must match the number of Java versions (${versionCount})`); + } +} async function configureToolchains(version, distributionName, jdkHome, toolchainId) { const vendor = getInput(INPUT_MVN_TOOLCHAIN_VENDOR) || distributionName; const id = toolchainId || `${vendor}_${version}`; @@ -132202,14 +132211,12 @@ async function run() { 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; - let toolchainIds = getMultilineInput(INPUT_MVN_TOOLCHAIN_ID); + const toolchainIds = getMultilineInput(INPUT_MVN_TOOLCHAIN_ID); startGroup('Installed distributions'); - if (versions.length !== toolchainIds.length) { - toolchainIds = []; - } if (!versions.length && !versionFile) { throw new Error('java-version or java-version-file input expected'); } + validateToolchainIds(versions, versionFile, toolchainIds); if (!versions.length) { core_debug('java-version input is empty, looking for java-version-file input'); const content = external_fs_default().readFileSync(versionFile).toString().trim(); diff --git a/docs/advanced-usage.md b/docs/advanced-usage.md index a89dad46..0b93e5a8 100644 --- a/docs/advanced-usage.md +++ b/docs/advanced-usage.md @@ -980,7 +980,7 @@ steps: - run: java --version ``` -In case you install multiple versions of Java at once you can use the same syntax as used in `java-versions`. Please note that you have to declare an ID for all Java versions that will be installed or the `mvn-toolchain-id` instruction will be skipped wholesale due to mapping ambiguities. +When installing multiple Java versions, use the same multiline syntax as `java-version`. You must declare exactly one ID for every Java version that will be installed. The action fails before installing a JDK unless the number of `mvn-toolchain-id` entries matches the number of `java-version` entries, or is exactly one when `java-version-file` is used. ```yaml steps: diff --git a/src/setup-java.ts b/src/setup-java.ts index cc0f9370..5bfe084f 100644 --- a/src/setup-java.ts +++ b/src/setup-java.ts @@ -40,18 +40,18 @@ async function run() { ); const verifySignaturePublicKey = core.getInput(constants.INPUT_VERIFY_SIGNATURE_PUBLIC_KEY) || undefined; - let toolchainIds = core.getMultilineInput(constants.INPUT_MVN_TOOLCHAIN_ID); + const toolchainIds = core.getMultilineInput( + constants.INPUT_MVN_TOOLCHAIN_ID + ); core.startGroup('Installed distributions'); - if (versions.length !== toolchainIds.length) { - toolchainIds = []; - } - if (!versions.length && !versionFile) { throw new Error('java-version or java-version-file input expected'); } + toolchains.validateToolchainIds(versions, versionFile, toolchainIds); + if (!versions.length) { core.debug( 'java-version input is empty, looking for java-version-file input' diff --git a/src/toolchains.ts b/src/toolchains.ts index 2cdaab30..fe21a64c 100644 --- a/src/toolchains.ts +++ b/src/toolchains.ts @@ -14,6 +14,23 @@ interface JdkInfo { jdkHome: string; } +export function validateToolchainIds( + versions: string[], + versionFile: string, + toolchainIds: string[] +) { + if (!toolchainIds.length) { + return; + } + + const versionCount = versions.length || (versionFile ? 1 : 0); + if (versionCount !== toolchainIds.length) { + throw new Error( + `The number of Maven toolchain IDs (${toolchainIds.length}) must match the number of Java versions (${versionCount})` + ); + } +} + export async function configureToolchains( version: string, distributionName: string,