fix(canvas): stop stalled Git blocking A2UI builds (#109476)

* fix(canvas): bound A2UI git input discovery

* build: avoid premature A2UI Git fallback

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
mushuiyu886
2026-07-16 23:20:01 -07:00
committed by GitHub
co-authored by Peter Steinberger
parent 44ab167200
commit f80c4b95ef
2 changed files with 48 additions and 0 deletions
@@ -22,6 +22,7 @@ const outputFile =
process.env.OPENCLAW_A2UI_BUNDLE_OUT ??
path.join(pluginDir, "src", "host", "a2ui", "a2ui.bundle.js");
const a2uiAppDir = path.join(pluginDir, "src", "host", "a2ui-app");
const GIT_INPUT_DISCOVERY_TIMEOUT_MS = 5_000;
const repoInputPaths = getBundleHashRepoInputPaths(rootDir);
const relativeRepoInputPaths = repoInputPaths.map((inputPath) =>
normalizePath(path.relative(rootDir, inputPath)),
@@ -111,7 +112,9 @@ function listTrackedInputFiles() {
const result = spawnSync("git", ["ls-files", "--", ...relativeRepoInputPaths], {
cwd: rootDir,
encoding: "utf8",
killSignal: "SIGKILL",
stdio: ["ignore", "pipe", "pipe"],
timeout: GIT_INPUT_DISCOVERY_TIMEOUT_MS,
});
if (result.status !== 0) {
return null;
@@ -1,5 +1,8 @@
// Canvas tests cover bundle a2ui plugin behavior.
import { execFileSync } from "node:child_process";
import fs from "node:fs/promises";
import path from "node:path";
import { resolvePreferredOpenClawTmpDir, withTempWorkspace } from "openclaw/plugin-sdk/temp-path";
import { describe, expect, it } from "vitest";
import {
compareNormalizedPaths,
@@ -58,4 +61,46 @@ describe("scripts/bundle-a2ui.mjs", () => {
path.join(repoRoot, "ui", "node_modules", "lit", "package.json"),
);
});
it.skipIf(process.platform === "win32")(
"falls back when tracked-input discovery stalls",
async () => {
await withTempWorkspace(
{ rootDir: resolvePreferredOpenClawTmpDir(), prefix: "openclaw-a2ui-git-timeout-" },
async ({ dir }) => {
const fakeBinDir = path.join(dir, "bin");
const fakeGitPath = path.join(fakeBinDir, "git");
const outputFile = path.join(dir, "a2ui.bundle.js");
const hashFile = path.join(dir, "a2ui.bundle.hash");
await fs.mkdir(fakeBinDir, { recursive: true });
await fs.writeFile(
fakeGitPath,
`#!${process.execPath}\nsetTimeout(() => {}, 30_000);\n`,
"utf8",
);
await fs.chmod(fakeGitPath, 0o755);
execFileSync(
process.execPath,
[path.resolve("extensions/canvas/scripts/bundle-a2ui.mjs")],
{
cwd: process.cwd(),
encoding: "utf8",
env: {
...process.env,
OPENCLAW_A2UI_BUNDLE_HASH_FILE: hashFile,
OPENCLAW_A2UI_BUNDLE_OUT: outputFile,
PATH: `${fakeBinDir}${path.delimiter}${process.env.PATH ?? ""}`,
},
killSignal: "SIGKILL",
timeout: 12_000,
},
);
await expect(fs.stat(outputFile)).resolves.toBeDefined();
await expect(fs.stat(hashFile)).resolves.toBeDefined();
},
);
},
);
});