fix(runtime): align supported requirements and release hygiene

This commit is contained in:
Federico Jaramillo Martinez
2026-07-18 00:10:47 +02:00
parent 1f13bab58a
commit aca168a311
21 changed files with 77 additions and 1204 deletions
+5 -5
View File
@@ -100,7 +100,7 @@ describe("production native service planning", () => {
wants: [],
prerequisites: [
{ id: "sessiond.command.pi-web-sessiond", kind: "command-available", command: "pi-web-sessiond" },
{ id: "sessiond.node", kind: "node-version", command: "node", minimumMajor: 22 },
{ id: "sessiond.node", kind: "node-version", command: "node", minimumVersion: "22.19.0" },
],
},
{
@@ -111,7 +111,7 @@ describe("production native service planning", () => {
wants: ["sessiond"],
prerequisites: [
{ id: "web.command.pi-web-server", kind: "command-available", command: "pi-web-server" },
{ id: "web.node", kind: "node-version", command: "node", minimumMajor: 22 },
{ id: "web.node", kind: "node-version", command: "node", minimumVersion: "22.19.0" },
],
},
],
@@ -196,7 +196,7 @@ describe("production native service planning", () => {
namedCommandFailure: "command not found",
},
prerequisites: [
{ id: "sessiond.node", kind: "node-version", command: "node", minimumMajor: 22 },
{ id: "sessiond.node", kind: "node-version", command: "node", minimumVersion: "22.19.0" },
{ id: "sessiond.entrypoint", kind: "readable-file", path: "/package with space/sessiond's entry.js" },
],
});
@@ -324,7 +324,7 @@ describe("development native service planning", () => {
environment: { PI_WEB_CONFIG: "/tmp/config.json" },
workingDirectory: "/checkout with space",
prerequisites: [
{ id: "sessiond.node", kind: "node-version", minimumMajor: 22 },
{ id: "sessiond.node", kind: "node-version", minimumVersion: "22.19.0" },
{ id: "sessiond.command.npm", kind: "command-available", command: "npm" },
{ id: "sessiond.package-scripts", kind: "package-scripts", scripts: ["start:sessiond"] },
],
@@ -338,7 +338,7 @@ describe("development native service planning", () => {
after: ["sessiond"],
wants: ["sessiond"],
prerequisites: [
{ id: "uiDev.node", kind: "node-version", minimumMajor: 22 },
{ id: "uiDev.node", kind: "node-version", minimumVersion: "22.19.0" },
{ id: "uiDev.command.npm", kind: "command-available", command: "npm" },
{ id: "uiDev.command.bash", kind: "command-available", command: "bash" },
{ id: "uiDev.package-scripts", kind: "package-scripts", scripts: ["dev:web", "dev:client"] },
+5 -3
View File
@@ -1,3 +1,5 @@
export const minimumSupportedNodeVersion = "22.19.0";
export type NativeServiceBackendKind = "systemd" | "launchd";
export type NativeServiceMode = "production" | "development";
export type NativeServiceId = "sessiond" | "web" | "uiDev";
@@ -64,7 +66,7 @@ export type NativeServicePrerequisite =
id: string;
kind: "node-version";
command: "node";
minimumMajor: number;
minimumVersion: string;
description: string;
}
| {
@@ -571,8 +573,8 @@ function nodeRequirement(serviceId: NativeServiceId): NativeServicePrerequisite
id: `${serviceId}.node`,
kind: "node-version",
command: "node",
minimumMajor: 22,
description: "node >= 22 is available to the service shell",
minimumVersion: minimumSupportedNodeVersion,
description: `node >= ${minimumSupportedNodeVersion} is available to the service shell`,
};
}
+17 -2
View File
@@ -1,3 +1,4 @@
import { spawnSync } from "node:child_process";
import { describe, expect, it, vi } from "vitest";
import {
LaunchdNativeServiceProbe,
@@ -5,6 +6,7 @@ import {
SystemdNativeServiceProbe,
launchdProbePlist,
nativeServicePrerequisiteShellCheck,
nodeVersionCheckScript,
systemdRunArguments,
type LaunchdProbeFileSystem,
type ProbeCommandResult,
@@ -433,13 +435,26 @@ describe("probe service definitions", () => {
id: "sessiond.node",
kind: "node-version",
command: "node",
minimumMajor: 22,
description: "node >= 22",
minimumVersion: "22.19.0",
description: "node >= 22.19.0",
});
expect(check).toContain("\"$pi_web_probe_executable\" '-e'");
expect(check).toContain("22.19.0");
expect(check).not.toContain("&& node -e");
});
it.each([
{ version: "21.99.99", accepted: false },
{ version: "22.18.99", accepted: false },
{ version: "22.19.0", accepted: true },
{ version: "22.19.1", accepted: true },
{ version: "23.0.0", accepted: true },
])("checks the complete Node version for $version", ({ version, accepted }) => {
const result = spawnSync(process.execPath, ["-e", nodeVersionCheckScript("22.19.0"), version]);
expect(result.error).toBeUndefined();
expect(result.status).toBe(accepted ? 0 : 1);
});
it("requires bundled entrypoints to be readable regular files", () => {
const check = nativeServicePrerequisiteShellCheck("bash", {
id: "sessiond.entrypoint",
+8 -5
View File
@@ -434,10 +434,8 @@ export function nativeServicePrerequisiteShellCheck(shell: NativeServiceShellNam
switch (prerequisite.kind) {
case "command-available":
return externalExecutableShellCheck(shell, prerequisite.command);
case "node-version": {
const script = `const major=Number(process.versions.node.split('.')[0]);process.exit(major>=${String(prerequisite.minimumMajor)}?0:1)`;
return externalExecutableShellCheck(shell, "node", ["-e", script]);
}
case "node-version":
return externalExecutableShellCheck(shell, "node", ["-e", nodeVersionCheckScript(prerequisite.minimumVersion)]);
case "readable-file": {
const path = shellQuote(shell, prerequisite.path);
return `test -f ${path} && test -r ${path}`;
@@ -449,6 +447,11 @@ export function nativeServicePrerequisiteShellCheck(shell: NativeServiceShellNam
}
}
export function nodeVersionCheckScript(minimumVersion: string): string {
const encodedMinimum = JSON.stringify(minimumVersion);
return `const version=process.argv[1]??process.versions.node;console.log(process.version);const current=version.split('.').map(Number);const minimum=${encodedMinimum}.split('.').map(Number);const length=Math.max(current.length,minimum.length);let comparison=0;for(let index=0;index<length;index+=1){const left=current[index]??0;const right=minimum[index]??0;if(left!==right){comparison=left>right?1:-1;break}}process.exit(comparison>=0?0:1)`;
}
function externalExecutableShellCheck(
shell: NativeServiceShellName,
command: string,
@@ -518,7 +521,7 @@ function unsatisfiedDetail(prerequisite: NativeServicePrerequisite): string {
case "command-available":
return `${prerequisite.command} did not resolve to an external executable in the native service environment.`;
case "node-version":
return `node >= ${String(prerequisite.minimumMajor)} was not available in the native service environment.`;
return `node >= ${prerequisite.minimumVersion} was not available in the native service environment.`;
case "readable-file":
return `${prerequisite.path} was not a readable regular file in the native service environment.`;
case "package-scripts":