mirror of
https://github.com/actions/setup-java.git
synced 2026-08-06 22:19:29 +08:00
d0e61fe743
* Fix JDK resolution cache platform identity Include the effective Linux libc platform in JDK resolution cache keys so Alpine/musl and glibc runners cannot restore each other's release metadata. Bump the cache namespace and share Alpine detection with affected distributors.\n\nCo-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>\nCopilot-Session: 4f95577c-567c-47a8-92f2-b4dced527866 * Update generated action bundles Regenerate setup and cleanup distributions for the platform-aware JDK resolution cache.\n\nCo-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>\nCopilot-Session: 4f95577c-567c-47a8-92f2-b4dced527866 * Cover the platform-identity fallback and Alpine short-circuit getJavaPlatformIdentity's `?? platform` fallback and the alias path for platforms other than linux/darwin/win32 had no coverage, and isAlpineLinux had no direct test at all. Verified by mutation: replacing the fallback with a constant, and dropping the `platform === 'linux'` short-circuit from isAlpineLinux, both left the existing suite fully green. The added cases fail on each. The short-circuit case matters beyond coverage bookkeeping: it is what keeps the /etc/alpine-release probe from running on non-Linux runners, so a stray file can never make Windows or macOS resolve as musl. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 74248bb0-72af-41d8-b85d-b0f5836e68db * Carry the platform identity into the floating resolution request Merging main brought in #1219, which added getFloatingResolutionRequest as a second construction site for JdkResolutionRequest. It predates the required `platform` field, so the merged tree did not compile. The floating request already carries `source`, which pins the artifact bytes, so this changes no lookup behaviour on its own -- it keeps the two request builders consistent and the tree building. Also refreshes dist/, which the textual merge left stale. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 74248bb0-72af-41d8-b85d-b0f5836e68db --------- Co-authored-by: Bruno Borges <brborges@microsoft.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 74248bb0-72af-41d8-b85d-b0f5836e68db
159 lines
4.9 KiB
TypeScript
159 lines
4.9 KiB
TypeScript
import fs from 'fs';
|
|
import path from 'path';
|
|
import {
|
|
getJavaPlatformIdentity,
|
|
isAlpineLinux,
|
|
JAVA_PLATFORM_CAPABILITIES,
|
|
normalizeArchitecture,
|
|
validateJavaPlatform
|
|
} from '../src/distributions/platform-types.js';
|
|
import {JavaDistribution} from '../src/distributions/package-types.js';
|
|
|
|
describe('Java platform capabilities', () => {
|
|
it('declares a capability for every distribution', () => {
|
|
expect(Object.keys(JAVA_PLATFORM_CAPABILITIES).sort()).toEqual(
|
|
Object.values(JavaDistribution).sort()
|
|
);
|
|
});
|
|
|
|
it.each([
|
|
['x64', 'x64'],
|
|
['amd64', 'x64'],
|
|
['x86', 'x86'],
|
|
['ia32', 'x86'],
|
|
['arm', 'armv7'],
|
|
['aarch64', 'aarch64'],
|
|
['arm64', 'aarch64'],
|
|
['ppc64le', 'ppc64le'],
|
|
['s390x', 's390x']
|
|
])('normalizes architecture %s to %s', (input, expected) => {
|
|
expect(normalizeArchitecture(input)).toBe(expected);
|
|
});
|
|
|
|
it.each([
|
|
['linux', false, 'linux-glibc'],
|
|
['linux', true, 'linux-musl'],
|
|
['darwin', false, 'macos'],
|
|
['win32', false, 'windows'],
|
|
// Exercises the normalizePlatform alias path and the `?? platform`
|
|
// fallback for a platform that has no Java alias.
|
|
['sunos', false, 'solaris'],
|
|
['aix', false, 'aix']
|
|
] as const)(
|
|
'identifies %s with Alpine release %s as %s',
|
|
(platform, alpineReleaseExists, expected) => {
|
|
expect(getJavaPlatformIdentity(platform, alpineReleaseExists)).toBe(
|
|
expected
|
|
);
|
|
}
|
|
);
|
|
|
|
// The platform check has to short-circuit before the filesystem probe, so a
|
|
// stray /etc/alpine-release can never make a non-Linux runner look like musl.
|
|
it.each([
|
|
['linux', true, true],
|
|
['linux', false, false],
|
|
['darwin', true, false],
|
|
['win32', true, false]
|
|
] as const)(
|
|
'treats %s with Alpine release %s as Alpine: %s',
|
|
(platform, alpineReleaseExists, expected) => {
|
|
expect(isAlpineLinux(platform, alpineReleaseExists)).toBe(expected);
|
|
}
|
|
);
|
|
|
|
it('uses the normalized architecture for validation', () => {
|
|
expect(validateJavaPlatform('microsoft', 'linux', 'arm64', '25')).toBe(
|
|
'aarch64'
|
|
);
|
|
});
|
|
|
|
it('rejects OS-specific restrictions with a consistent diagnostic', () => {
|
|
expect(() =>
|
|
validateJavaPlatform('oracle', 'win32', 'arm64', '21')
|
|
).toThrow(
|
|
"Distribution 'oracle' does not support operating system 'windows' with architecture 'aarch64' for Java version '21'. Supported combinations: linux (x64, aarch64); macos (x64, aarch64); windows (x64)."
|
|
);
|
|
});
|
|
|
|
it('rejects version-dependent architecture restrictions', () => {
|
|
expect(() =>
|
|
validateJavaPlatform('corretto', 'linux', 'x86', '17')
|
|
).toThrow(/x86 \(<12\)/);
|
|
expect(() =>
|
|
validateJavaPlatform('corretto', 'linux', 'x86', '17.0.2.8.1')
|
|
).toThrow(/x86 \(<12\)/);
|
|
expect(validateJavaPlatform('corretto', 'linux', 'x86', '11')).toBe('x86');
|
|
});
|
|
|
|
it.each(['corretto', 'kona'])(
|
|
'rejects Windows aarch64 for %s',
|
|
distributionName => {
|
|
expect(() =>
|
|
validateJavaPlatform(distributionName, 'win32', 'arm64', '21')
|
|
).toThrow(/does not support operating system 'windows'/);
|
|
}
|
|
);
|
|
|
|
it('allows local archives on any platform and architecture', () => {
|
|
expect(validateJavaPlatform('jdkfile', 'aix', 'mips64', '21')).toBe(
|
|
'mips64'
|
|
);
|
|
});
|
|
|
|
it('keeps the documented architecture contract aligned', () => {
|
|
const repositoryRoot = process.cwd();
|
|
const readRepositoryFile = (filePath: string) =>
|
|
fs.readFileSync(path.join(repositoryRoot, filePath), 'utf8');
|
|
|
|
for (const filePath of ['action.yml', 'README.md']) {
|
|
const content = readRepositoryFile(filePath);
|
|
for (const architecture of [
|
|
'x86',
|
|
'x64',
|
|
'armv7',
|
|
'aarch64',
|
|
'ppc64le',
|
|
'ppc64',
|
|
's390x'
|
|
]) {
|
|
expect(content).toContain(architecture);
|
|
}
|
|
}
|
|
});
|
|
|
|
it.each(Object.entries(JAVA_PLATFORM_CAPABILITIES))(
|
|
'keeps the advanced compatibility table aligned for %s',
|
|
(distributionName, capability) => {
|
|
const advancedUsage = fs.readFileSync(
|
|
path.join(process.cwd(), 'docs/advanced-usage.md'),
|
|
'utf8'
|
|
);
|
|
const compatibilityTable = advancedUsage.slice(
|
|
advancedUsage.indexOf('## Platform and architecture compatibility')
|
|
);
|
|
const compatibilityRow = compatibilityTable
|
|
.split('\n')
|
|
.find(
|
|
line =>
|
|
line.startsWith('|') && line.includes(`\`${distributionName}\``)
|
|
);
|
|
|
|
expect(compatibilityRow).toBeDefined();
|
|
if (!('platforms' in capability)) {
|
|
expect(compatibilityRow).toContain('Any');
|
|
return;
|
|
}
|
|
|
|
const architectures = new Set(
|
|
Object.values(capability.platforms)
|
|
.flat()
|
|
.map(item => (typeof item === 'string' ? item : item.architecture))
|
|
);
|
|
for (const architecture of architectures) {
|
|
expect(compatibilityRow).toContain(`\`${architecture}\``);
|
|
}
|
|
}
|
|
);
|
|
});
|