mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 10:16:44 +00:00
fix(ci): remove cross-os TypeScript loader bootstrap (#103195)
This commit is contained in:
@@ -194,7 +194,6 @@ env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
||||
NODE_VERSION: "24.15.0"
|
||||
OPENCLAW_REPOSITORY: openclaw/openclaw
|
||||
TSX_VERSION: "4.21.0"
|
||||
OPENCLAW_CROSS_OS_OPENAI_MODEL: ${{ inputs.openai_model || vars.OPENCLAW_CROSS_OS_OPENAI_MODEL || 'openai/gpt-5.5' }}
|
||||
|
||||
jobs:
|
||||
|
||||
+1
-1
@@ -1942,7 +1942,7 @@
|
||||
"test:unit:fast:audit": "node scripts/test-unit-fast-audit.mjs",
|
||||
"test:voicecall:closedloop": "node scripts/test-voicecall-closedloop.mjs",
|
||||
"test:watch": "node scripts/test-projects.mjs --watch",
|
||||
"test:windows:ci": "node scripts/test-projects.mjs src/shared/runtime-import.test.ts src/process/exec.windows.test.ts src/process/windows-command.test.ts src/infra/backup-create.windows.test.ts src/infra/windows-install-roots.test.ts src/node-host/invoke-system-run-allowlist.test.ts src/daemon/schtasks.startup-fallback.test.ts extensions/lobster/src/lobster-runner.test.ts test/scripts/format-generated-module.test.ts test/scripts/npm-runner.test.ts test/scripts/pnpm-runner.test.ts test/scripts/run-with-env.test.ts test/scripts/ui.test.ts test/scripts/vitest-process-group.test.ts",
|
||||
"test:windows:ci": "node scripts/test-projects.mjs src/shared/runtime-import.test.ts src/process/exec.windows.test.ts src/process/windows-command.test.ts src/infra/backup-create.windows.test.ts src/infra/windows-install-roots.test.ts src/node-host/invoke-system-run-allowlist.test.ts src/daemon/schtasks.startup-fallback.test.ts extensions/lobster/src/lobster-runner.test.ts test/scripts/format-generated-module.test.ts test/scripts/npm-runner.test.ts test/scripts/openclaw-cross-os-release-workflow.test.ts test/scripts/pnpm-runner.test.ts test/scripts/run-with-env.test.ts test/scripts/ui.test.ts test/scripts/vitest-process-group.test.ts",
|
||||
"tool-display:check": "node --import tsx scripts/tool-display.ts --check",
|
||||
"tool-display:write": "node --import tsx scripts/tool-display.ts --write",
|
||||
"ts-topology": "node --import tsx scripts/ts-topology.ts",
|
||||
|
||||
@@ -45,9 +45,9 @@ const ANDROID_NATIVE_RE = /^(apps\/android\/|apps\/shared\/)/;
|
||||
const NODE_SCOPE_RE =
|
||||
/^(src\/|test\/|extensions\/|packages\/|scripts\/|ui\/|\.github\/|openclaw\.mjs$|package\.json$|pnpm-lock\.yaml$|pnpm-workspace\.yaml$|tsconfig.*\.json$|vitest.*\.ts$|tsdown\.config\.ts$|\.oxlintrc\.json$|\.oxfmtrc\.jsonc$)/;
|
||||
const WINDOWS_SCOPE_RE =
|
||||
/^(src\/process\/|src\/infra\/windows-install-roots\.ts$|src\/shared\/(?:import-specifier|runtime-import)(?:\.test)?\.ts$|scripts\/(?:install\.ps1|(?:npm-runner|pnpm-runner|ui|vitest-process-group)\.(?:mjs|js)|lib\/format-generated-module\.mjs)$|test\/scripts\/(?:format-generated-module|install-ps1|npm-runner|pnpm-runner|ui|vitest-process-group)\.test\.ts$|package\.json$|pnpm-lock\.yaml$|pnpm-workspace\.yaml$|\.github\/workflows\/ci\.yml$|\.github\/actions\/setup-node-env\/action\.yml$|\.github\/actions\/setup-pnpm-store-cache\/action\.yml$)/;
|
||||
/^(src\/process\/|src\/infra\/windows-install-roots\.ts$|src\/shared\/(?:import-specifier|runtime-import)(?:\.test)?\.ts$|scripts\/(?:install\.ps1|openclaw-cross-os-release-checks\.ts|github\/run-openclaw-cross-os-release-checks\.sh|(?:npm-runner|pnpm-runner|ui|vitest-process-group)\.(?:mjs|js)|lib\/format-generated-module\.mjs)$|test\/scripts\/(?:format-generated-module|install-ps1|npm-runner|openclaw-cross-os-release-workflow|pnpm-runner|ui|vitest-process-group)\.test\.ts$|package\.json$|pnpm-lock\.yaml$|pnpm-workspace\.yaml$|\.github\/workflows\/(?:ci|openclaw-cross-os-release-checks-reusable)\.yml$|\.github\/actions\/setup-node-env\/action\.yml$|\.github\/actions\/setup-pnpm-store-cache\/action\.yml$)/;
|
||||
const WINDOWS_TEST_SCOPE_RE =
|
||||
/^(src\/process\/(?:exec\.windows|windows-command)\.test\.ts$|src\/infra\/windows-install-roots\.test\.ts$|src\/shared\/runtime-import\.test\.ts$|test\/scripts\/(?:format-generated-module|npm-runner|pnpm-runner|ui|vitest-process-group)\.test\.ts$)/;
|
||||
/^(src\/process\/(?:exec\.windows|windows-command)\.test\.ts$|src\/infra\/windows-install-roots\.test\.ts$|src\/shared\/runtime-import\.test\.ts$|test\/scripts\/(?:format-generated-module|npm-runner|openclaw-cross-os-release-workflow|pnpm-runner|ui|vitest-process-group)\.test\.ts$)/;
|
||||
const WINDOWS_DAEMON_SCOPE_RE =
|
||||
/^src\/daemon\/(?:schtasks(?:[-.][^/]+)?|runtime-hints\.windows-paths(?:\.test)?|test-helpers\/schtasks-(?:base-mocks|fixtures))\.ts$/;
|
||||
const TEST_ONLY_PATH_RE =
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
tsx_version="${OPENCLAW_RELEASE_TSX_VERSION:-${TSX_VERSION:-4.21.0}}"
|
||||
script_path="${OPENCLAW_RELEASE_CHECKS_SCRIPT:-workflow/scripts/openclaw-cross-os-release-checks.ts}"
|
||||
|
||||
if ! command -v node >/dev/null 2>&1 || ! command -v npm >/dev/null 2>&1; then
|
||||
if ! command -v node >/dev/null 2>&1; then
|
||||
if command -v cygpath >/dev/null 2>&1; then
|
||||
for node_dir in /c/hostedtoolcache/windows/node/*/x64 /c/actions-runner/_work/_tool/node/*/x64; do
|
||||
if [[ -x "${node_dir}/node.exe" ]]; then
|
||||
@@ -16,78 +15,15 @@ if ! command -v node >/dev/null 2>&1 || ! command -v npm >/dev/null 2>&1; then
|
||||
fi
|
||||
|
||||
node_cmd="node"
|
||||
npm_cmd="npm"
|
||||
npm_cli_js=""
|
||||
if command -v cygpath >/dev/null 2>&1; then
|
||||
if command -v node.exe >/dev/null 2>&1; then
|
||||
node_cmd="node.exe"
|
||||
node_path="$(command -v node.exe)"
|
||||
node_dir="$(dirname "$(cygpath -u "${node_path}")")"
|
||||
if [[ -f "${node_dir}/node_modules/npm/bin/npm-cli.js" ]]; then
|
||||
npm_cli_js="${node_dir}/node_modules/npm/bin/npm-cli.js"
|
||||
fi
|
||||
fi
|
||||
if command -v npm.cmd >/dev/null 2>&1; then
|
||||
npm_cmd="npm.cmd"
|
||||
elif command -v npm.exe >/dev/null 2>&1; then
|
||||
npm_cmd="npm.exe"
|
||||
fi
|
||||
fi
|
||||
|
||||
temp_root="${OPENCLAW_RELEASE_TSX_TOOL_ROOT:-${RUNNER_TEMP:-${TMPDIR:-/tmp}}}"
|
||||
if command -v cygpath >/dev/null 2>&1; then
|
||||
temp_root="$(cygpath -u "${temp_root}")"
|
||||
fi
|
||||
|
||||
tool_dir="${OPENCLAW_RELEASE_TSX_TOOL_DIR:-${temp_root}/openclaw-release-tsx-${tsx_version}}"
|
||||
loader_path="${tool_dir}/node_modules/tsx/dist/loader.mjs"
|
||||
npm_tool_dir="${tool_dir}"
|
||||
npm_cli_arg="${npm_cli_js}"
|
||||
loader_arg="${loader_path}"
|
||||
if command -v cygpath >/dev/null 2>&1; then
|
||||
npm_tool_dir="$(cygpath -w "${tool_dir}")"
|
||||
if [[ -n "${npm_cli_js}" ]]; then
|
||||
npm_cli_arg="$(cygpath -w "${npm_cli_js}")"
|
||||
fi
|
||||
loader_arg="$(cygpath -w "${loader_path}")"
|
||||
fi
|
||||
|
||||
command -v "${node_cmd}" >/dev/null 2>&1 || {
|
||||
echo "node is required to run cross-OS release checks." >&2
|
||||
exit 127
|
||||
}
|
||||
command -v "${npm_cmd}" >/dev/null 2>&1 || {
|
||||
echo "npm is required to install the cross-OS release-check loader." >&2
|
||||
exit 127
|
||||
}
|
||||
|
||||
if [[ ! -f "${loader_path}" ]]; then
|
||||
mkdir -p "${tool_dir}"
|
||||
# The loader only needs tsx's packaged JS and esbuild platform package.
|
||||
# Skipping lifecycle scripts avoids npm child-shell drift on Windows runners.
|
||||
if [[ -n "${npm_cli_js}" ]]; then
|
||||
if ! "${node_cmd}" "${npm_cli_arg}" install --prefix "${npm_tool_dir}" --no-save --no-package-lock --ignore-scripts "tsx@${tsx_version}" >/dev/null; then
|
||||
echo "failed to install cross-OS release-check loader with ${node_cmd} ${npm_cli_arg}." >&2
|
||||
exit 127
|
||||
fi
|
||||
elif ! "${npm_cmd}" install --prefix "${npm_tool_dir}" --no-save --no-package-lock --ignore-scripts "tsx@${tsx_version}" >/dev/null; then
|
||||
echo "failed to install cross-OS release-check loader with ${npm_cmd}." >&2
|
||||
exit 127
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! -f "${loader_path}" ]]; then
|
||||
echo "tsx loader missing after install: ${loader_path}" >&2
|
||||
find "${tool_dir}" -maxdepth 5 -type f 2>/dev/null | sort | sed 's/^/ /' >&2 || true
|
||||
exit 127
|
||||
fi
|
||||
|
||||
loader_url="$(
|
||||
"${node_cmd}" -e '
|
||||
const { resolve } = require("node:path");
|
||||
const { pathToFileURL } = require("node:url");
|
||||
process.stdout.write(pathToFileURL(resolve(process.argv[1])).href);
|
||||
' "${loader_arg}"
|
||||
)"
|
||||
|
||||
exec "${node_cmd}" --import "${loader_url}" "${script_path}" "$@"
|
||||
exec "${node_cmd}" "${script_path}" "$@"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env -S node --import tsx
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Executed directly via Node.js + tsx in the release workflow.
|
||||
// Executed directly via Node.js native type stripping in the release workflow.
|
||||
|
||||
import { spawn } from "node:child_process";
|
||||
import { randomUUID } from "node:crypto";
|
||||
|
||||
@@ -503,6 +503,23 @@ describe("detectChangedScope", () => {
|
||||
runChangedSmoke: false,
|
||||
runControlUiI18n: false,
|
||||
});
|
||||
for (const releaseCheckPath of [
|
||||
".github/workflows/openclaw-cross-os-release-checks-reusable.yml",
|
||||
"scripts/github/run-openclaw-cross-os-release-checks.sh",
|
||||
"scripts/openclaw-cross-os-release-checks.ts",
|
||||
"test/scripts/openclaw-cross-os-release-workflow.test.ts",
|
||||
]) {
|
||||
expect(detectChangedScope([releaseCheckPath]), releaseCheckPath).toEqual({
|
||||
runNode: true,
|
||||
runMacos: false,
|
||||
runIosBuild: false,
|
||||
runAndroid: false,
|
||||
runWindows: true,
|
||||
runSkillsPython: false,
|
||||
runChangedSmoke: false,
|
||||
runControlUiI18n: false,
|
||||
});
|
||||
}
|
||||
expect(detectChangedScope(["scripts/install.ps1"])).toEqual({
|
||||
runNode: true,
|
||||
runMacos: false,
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
// Openclaw Cross Os Release Workflow tests cover openclaw cross os release workflow script behavior.
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const WORKFLOW_PATH = ".github/workflows/openclaw-cross-os-release-checks-reusable.yml";
|
||||
const WRAPPER_PATH = "scripts/github/run-openclaw-cross-os-release-checks.sh";
|
||||
const SCRIPT_PATH = "scripts/openclaw-cross-os-release-checks.ts";
|
||||
const HARNESS = "bash workflow/scripts/github/run-openclaw-cross-os-release-checks.sh";
|
||||
const BASH_BIN = process.platform === "win32" ? "bash" : "/bin/bash";
|
||||
|
||||
describe("cross-OS release checks workflow", () => {
|
||||
it("runs the TypeScript release harness through the Windows-safe wrapper", () => {
|
||||
@@ -13,7 +16,7 @@ describe("cross-OS release checks workflow", () => {
|
||||
expect(workflow).toContain(HARNESS);
|
||||
expect(workflow).toContain("suite_filter:");
|
||||
expect(workflow).toContain('--suite-filter "${INPUT_SUITE_FILTER}"');
|
||||
expect(workflow).not.toContain('pnpm dlx "tsx@${TSX_VERSION}"');
|
||||
expect(workflow).not.toContain("TSX_VERSION");
|
||||
});
|
||||
|
||||
it("bounds npm baseline packing during prepare", () => {
|
||||
@@ -34,16 +37,61 @@ describe("cross-OS release checks workflow", () => {
|
||||
expect(workflow).toContain("process.stdout.write(`file_name=${fileName}\\n`);");
|
||||
});
|
||||
|
||||
it("uses Windows-safe npm resolution for the TypeScript loader bootstrap", () => {
|
||||
it("executes the release harness directly with Node", () => {
|
||||
const wrapper = readFileSync(WRAPPER_PATH, "utf8");
|
||||
const script = readFileSync(SCRIPT_PATH, "utf8");
|
||||
const packageJson = JSON.parse(readFileSync("package.json", "utf8")) as {
|
||||
scripts: Record<string, string>;
|
||||
};
|
||||
|
||||
expect(wrapper).toContain("command -v npm.cmd");
|
||||
expect(wrapper).toContain('npm_tool_dir="$(cygpath -w "${tool_dir}")"');
|
||||
expect(wrapper).toContain('npm_cli_arg="$(cygpath -w "${npm_cli_js}")"');
|
||||
expect(wrapper).toContain('loader_arg="$(cygpath -w "${loader_path}")"');
|
||||
expect(wrapper).toContain('"${node_cmd}" "${npm_cli_arg}" install --prefix "${npm_tool_dir}"');
|
||||
expect(wrapper).toContain('"${npm_cmd}" install --prefix "${npm_tool_dir}"');
|
||||
expect(wrapper.match(/--ignore-scripts/g)).toHaveLength(2);
|
||||
expect(wrapper).toContain('exec "${node_cmd}" --import "${loader_url}"');
|
||||
expect(wrapper).toContain('exec "${node_cmd}" "${script_path}" "$@"');
|
||||
expect(wrapper).not.toContain("npm");
|
||||
expect(wrapper).not.toContain("tsx");
|
||||
expect(wrapper).not.toContain("--import");
|
||||
expect(script).toMatch(/^#!\/usr\/bin\/env node$/mu);
|
||||
expect(script).not.toContain("--import tsx");
|
||||
expect(packageJson.scripts["test:windows:ci"]).toContain(
|
||||
"test/scripts/openclaw-cross-os-release-workflow.test.ts",
|
||||
);
|
||||
|
||||
const result = spawnSync(
|
||||
BASH_BIN,
|
||||
[
|
||||
WRAPPER_PATH,
|
||||
"--resolve-matrix",
|
||||
"--ref",
|
||||
"test/native-node",
|
||||
"--mode",
|
||||
"fresh",
|
||||
"--suite-filter",
|
||||
"windows/packaged-fresh",
|
||||
"--windows-runner",
|
||||
"windows-2025",
|
||||
],
|
||||
{
|
||||
cwd: process.cwd(),
|
||||
encoding: "utf8",
|
||||
env: {
|
||||
...process.env,
|
||||
OPENCLAW_RELEASE_CHECKS_SCRIPT: SCRIPT_PATH,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.stderr).toBe("");
|
||||
expect(result.status).toBe(0);
|
||||
expect(JSON.parse(result.stdout)).toEqual({
|
||||
include: [
|
||||
{
|
||||
os_id: "windows",
|
||||
display_name: "Windows",
|
||||
runner: "windows-2025",
|
||||
artifact_name: "windows",
|
||||
suite: "packaged-fresh",
|
||||
suite_label: "packaged fresh",
|
||||
lane: "fresh",
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user