Archived
fix(runtime): align supported requirements and release hygiene
This commit is contained in:
@@ -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"] },
|
||||
|
||||
@@ -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`,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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":
|
||||
|
||||
Reference in New Issue
Block a user