Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/site/types/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ type DownloadCompatibility = {
installMethod?: Array<string>;
platform?: Array<Platform | ''>;
semver?: Array<string>;
/** At least one range must match when this field is set. */
semverAny?: Array<string>;
releases?: Array<NodeReleaseStatus>;
};

Expand Down
62 changes: 62 additions & 0 deletions apps/site/util/__tests__/download.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
PLATFORMS,
} from '#site/util/download';

import { buildReleaseArtifacts } from '../download/archive';

describe('parseCompat', () => {
it('should handle all OS, install methods, and package managers', () => {
OPERATING_SYSTEMS.forEach(os => {
Expand Down Expand Up @@ -46,6 +48,38 @@ describe('parseCompat', () => {
});
});

it('should enable x64 musl only for releases that publish the artifact', () => {
const platform = PLATFORMS.LINUX.find(({ value }) => value === 'x64-musl');
assert.ok(
platform,
'Linux x64 musl should be available as a manual option'
);

const cases = [
['v22.23.3', false],
['v22.23.2', true],
['v23.11.1', true],
['v24.20.0', false],
['v24.19.0', true],
['v25.0.0', true],
['v26.8.0', false],
['v26.7.0', true],
['v27.0.0', true],
];

for (const [version, disabled] of cases) {
const [result] = parseCompat([platform], {
os: 'LINUX',
installMethod: '',
platform: 'x64-musl',
version,
release: { status: 'LTS' },
});

assert.equal(result.disabled, disabled, `compatibility for ${version}`);
}
});

describe('extended tests', () => {
it('should disable items if OS is not supported', () => {
const items = [
Expand Down Expand Up @@ -134,6 +168,34 @@ describe('parseCompat', () => {
});
});

describe('buildReleaseArtifacts', () => {
it('should list x64 musl only for versions with published artifacts', () => {
const cases = [
['v22.23.3', true],
['v22.23.2', false],
['v23.11.1', false],
['v24.20.0', true],
['v24.19.0', false],
['v25.0.0', false],
['v26.8.0', true],
['v26.7.0', false],
['v27.0.0', false],
];

for (const [version, shouldInclude] of cases) {
const { binaries } = buildReleaseArtifacts(
{ minorVersions: [] },
version
);
const artifact = binaries.find(
({ fileName }) => fileName === `node-${version}-linux-x64-musl.tar.xz`
);

assert.equal(Boolean(artifact), shouldInclude, `artifact for ${version}`);
}
});
});

describe('nextItem', () => {
it('should find the first valid item if current is invalid', () => {
const items = [
Expand Down
12 changes: 12 additions & 0 deletions apps/site/util/__tests__/url.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@ describe('getNodeDownloadUrl', () => {
);
});

it('should return the x64 musl Linux binary URL', () => {
assert.equal(
getNodeDownloadUrl({
versionWithPrefix: 'v24.20.0',
os: 'LINUX',
platform: 'x64-musl',
kind: 'binary',
}),
'https://nodejs.org/dist/v24.20.0/node-v24.20.0-linux-x64-musl.tar.xz'
);
});

describe('MAC', () => {
it('should return .pkg link for installer', () => {
const url = getNodeDownloadUrl({
Expand Down
22 changes: 15 additions & 7 deletions apps/site/util/download/archive.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import semVer from 'semver';

import { DIST_URL } from '#site/next.constants.mjs';
import { OS_NOT_SUPPORTING_INSTALLERS, PLATFORMS } from '#site/util/download';
import { getNodeDownloadUrl } from '#site/util/url';

Expand All @@ -14,8 +15,6 @@ import type {
} from '#site/types';
import type { NodeRelease } from '#site/types/releases';

import { DIST_URL } from '#site/next.constants';

/**
* Creates a download artifact from platform data
*/
Expand Down Expand Up @@ -58,15 +57,24 @@ const getCompatiblePlatforms = (
return items
.filter(({ compatibility }) => {
// In the download constants file (apps/site/util/download/constants.json),
// if no compatibility is defined as a semver, we treat it as supporting all
// if no semver compatibility is defined, we treat it as supporting all
// versions by default.
if (!compatibility.semver) {
if (!compatibility.semver && !compatibility.semverAny) {
return true;
}

return compatibility.semver.every(version =>
semVer.satisfies(versionWithPrefix, version)
);
const satisfiesAll =
!compatibility.semver ||
compatibility.semver.every(version =>
semVer.satisfies(versionWithPrefix, version)
);
const satisfiesAny =
!compatibility.semverAny ||
compatibility.semverAny.some(version =>
semVer.satisfies(versionWithPrefix, version)
);

return satisfiesAll && satisfiesAny;
})
.map(platform => ({
os,
Expand Down
22 changes: 21 additions & 1 deletion apps/site/util/download/constants.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@
"label": "x64",
"value": "x64"
},
{
"label": "x64 (musl)",
"value": "x64-musl",
"compatibility": {
"semverAny": [
">=22.23.3 <23.0.0",
">=24.20.0 <25.0.0",
">=26.8.0 <27.0.0"
]
}
},
{
"label": "ARMv7",
"value": "armv7l",
Expand Down Expand Up @@ -238,7 +249,16 @@
}
],
"userOptions": {
"platforms": ["arm64", "armv7l", "ppc64le", "ppc64", "s390x", "x64", "x86"],
"platforms": [
"arm64",
"armv7l",
"ppc64le",
"ppc64",
"s390x",
"x64",
"x64-musl",
"x86"
],
"bitness": ["64", "32"],
"architecture": ["arm", "x86"]
},
Expand Down
2 changes: 2 additions & 0 deletions apps/site/util/download/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ export const parseCompat = <
!compatibility.platform || compatibility.platform.includes(platform),
!compatibility.semver ||
compatibility.semver.every(semver => satisfies(version, semver)),
!compatibility.semverAny ||
compatibility.semverAny.some(semver => satisfies(version, semver)),
!compatibility.releases ||
compatibility.releases.includes(release.status),
];
Expand Down