feat: bootstrap portable Node runtimes
CI / Client installer (macos-latest) (push) Canceled after 0s
CI / Client installer (ubuntu-latest) (push) Canceled after 0s
CI / Client installer (windows-latest) (push) Canceled after 0s
CI / test (22) (push) Canceled after 0s
CI / test (24) (push) Canceled after 0s
CI / release-smoke (push) Canceled after 0s

This commit is contained in:
2026-08-18 13:53:54 +00:00
parent 2e275b684d
commit dd189c2acb
22 changed files with 900 additions and 96 deletions
+17 -1
View File
@@ -80,9 +80,25 @@ try {
const install = readFileSync(join(releaseDir, "install.md"), "utf8");
if (install.includes("{{") || !install.includes(`版本:\`${version}\``)
|| !install.includes("唯一通用安装入口") || !install.includes("postInstall")
|| !install.includes("onboarding.firstRun=true") || /--host|WorkBuddy|Codex|Claude/.test(install)) {
|| !install.includes("onboarding.firstRun=true") || !install.includes("系统无需预装 Node.js")
|| /--host|WorkBuddy|Codex|Claude/.test(install)) {
throw new Error("install.md 版本、占位符或通用安装引导不正确");
}
const windowsBootstrap = readFileSync(join(releaseDir, artifactName(manifest.artifacts.bootstrapWindows, "bootstrapWindows")), "utf8");
const posixBootstrapPath = join(releaseDir, artifactName(manifest.artifacts.bootstrapPosix, "bootstrapPosix"));
const posixBootstrap = readFileSync(posixBootstrapPath, "utf8");
if (windowsBootstrap.includes("{{") || posixBootstrap.includes("{{")
|| !windowsBootstrap.includes("Save-DingDownload") || !windowsBootstrap.includes("Expand-Archive")
|| !posixBootstrap.startsWith("#!/bin/sh\nset -eu\n") || !posixBootstrap.includes("tar -xzf")
|| /latest-v|npm install -g/.test(`${windowsBootstrap}\n${posixBootstrap}`)) {
throw new Error("无 Node 安装引导无效或仍包含不安全的动态版本来源");
}
execFileSync("sh", ["-n", posixBootstrapPath]);
const managedPlatforms = [...(manifest.requirements?.managedNode?.platforms ?? [])].sort();
if (!/^\d+\.\d+\.\d+$/.test(String(manifest.requirements?.managedNode?.version ?? ""))
|| JSON.stringify(managedPlatforms) !== JSON.stringify([
"darwin-arm64", "darwin-x64", "linux-arm64", "linux-x64", "win32-arm64", "win32-x64",
])) throw new Error("清单没有完整声明三平台私有 Node 运行时");
const skill = readFileSync(join(releaseDir, artifactName(manifest.artifacts.skill, "skill")), "utf8");
if (!skill.startsWith("---\nname: dingtalk-approval\n")) throw new Error("通用 Skill artifact 无效");
} finally {