mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-08 02:52:15 +00:00
fix(testing): keep crabbox sync checkouts durable
This commit is contained in:
@@ -13,7 +13,7 @@ import {
|
||||
statSync,
|
||||
writeFileSync,
|
||||
} from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { homedir, tmpdir } from "node:os";
|
||||
import { delimiter, dirname, extname, isAbsolute, relative, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { resolvePathEnvKey } from "./windows-cmd-helpers.mjs";
|
||||
@@ -1540,7 +1540,9 @@ function isWindowsRemoteTarget(commandArgs) {
|
||||
}
|
||||
|
||||
function isNativeWindowsRemoteTarget(commandArgs) {
|
||||
return isWindowsRemoteTarget(commandArgs) && optionValue(commandArgs, "--windows-mode") !== "wsl2";
|
||||
return (
|
||||
isWindowsRemoteTarget(commandArgs) && optionValue(commandArgs, "--windows-mode") !== "wsl2"
|
||||
);
|
||||
}
|
||||
|
||||
function isAwsMacosRemoteTarget(commandArgs, providerName) {
|
||||
@@ -1553,14 +1555,14 @@ function isAwsMacosRemoteTarget(commandArgs, providerName) {
|
||||
|
||||
function remoteWindowsHydratedNodeModulesBootstrap() {
|
||||
return [
|
||||
'$openclawModulesDir = $env:PNPM_CONFIG_MODULES_DIR',
|
||||
'if ($openclawModulesDir) {',
|
||||
"$openclawModulesDir = $env:PNPM_CONFIG_MODULES_DIR",
|
||||
"if ($openclawModulesDir) {",
|
||||
'if (-not (Test-Path $openclawModulesDir)) { throw "PNPM_CONFIG_MODULES_DIR does not exist: $openclawModulesDir" }',
|
||||
'$openclawWorkspaceModules = Join-Path (Get-Location).Path "node_modules"',
|
||||
'$openclawSelfModules = Join-Path $openclawModulesDir "node_modules"',
|
||||
'if (-not (Test-Path $openclawSelfModules)) { cmd /c mklink /J "$openclawSelfModules" "$openclawModulesDir" | Out-Host; if ($LASTEXITCODE -ne 0) { throw "failed to link hydrated pnpm node_modules" } }',
|
||||
'if (-not (Test-Path $openclawWorkspaceModules)) { cmd /c mklink /J "$openclawWorkspaceModules" "$openclawModulesDir" | Out-Host; if ($LASTEXITCODE -ne 0) { throw "failed to link workspace node_modules" } }',
|
||||
'}',
|
||||
"}",
|
||||
].join("; ");
|
||||
}
|
||||
|
||||
@@ -1894,8 +1896,23 @@ function shouldUseFullCheckoutForCleanRemoteSync(commandArgs, _providerName) {
|
||||
return isSparseCheckout() || isChangedGateCommand(runCommandArgs(commandArgs));
|
||||
}
|
||||
|
||||
function defaultFullCheckoutSyncRoot() {
|
||||
const home = homedir();
|
||||
if (home) {
|
||||
return resolve(home, ".cache", "openclaw", "crabbox-sync");
|
||||
}
|
||||
return resolve(tmpdir(), "openclaw-crabbox-sync");
|
||||
}
|
||||
|
||||
function fullCheckoutSyncRoot() {
|
||||
const configured = process.env.OPENCLAW_CRABBOX_SYNC_TMPDIR?.trim();
|
||||
const root = configured ? resolve(configured) : defaultFullCheckoutSyncRoot();
|
||||
mkdirSync(root, { recursive: true });
|
||||
return root;
|
||||
}
|
||||
|
||||
function prepareFullCheckoutForSync(options = {}) {
|
||||
const dir = mkdtempSync(resolve(tmpdir(), "openclaw-crabbox-sync-"));
|
||||
const dir = mkdtempSync(resolve(fullCheckoutSyncRoot(), "openclaw-crabbox-sync-"));
|
||||
let active = false;
|
||||
const add = gitOutput(["worktree", "add", "--detach", dir, "HEAD"]);
|
||||
if (add.status !== 0) {
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { chmodSync, mkdirSync, mkdtempSync, rmSync, statSync, writeFileSync } from "node:fs";
|
||||
import {
|
||||
chmodSync,
|
||||
mkdirSync,
|
||||
mkdtempSync,
|
||||
readdirSync,
|
||||
rmSync,
|
||||
statSync,
|
||||
writeFileSync,
|
||||
} from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
||||
@@ -182,6 +190,7 @@ function makeFakeGit(
|
||||
" exit 0",
|
||||
"fi",
|
||||
'if [ "$1" = "worktree" ] && [ "$2" = "remove" ]; then',
|
||||
' rm -rf "$4"',
|
||||
" exit 0",
|
||||
"fi",
|
||||
...Object.entries(responses).flatMap(([key, response]) => {
|
||||
@@ -209,7 +218,7 @@ function makeFakeGit(
|
||||
"if (args[0] === 'worktree' && args[1] === 'add') { fs.mkdirSync(args[3], { recursive: true }); process.exit(0); }",
|
||||
"if (args[0] === '-C' && args[2] === 'sparse-checkout' && args[3] === 'disable') { process.exit(0); }",
|
||||
"if (args[0] === '-C' && args[2] === 'reset' && args[3] === '--mixed') { process.exit(0); }",
|
||||
"if (args[0] === 'worktree' && args[1] === 'remove') { process.exit(0); }",
|
||||
"if (args[0] === 'worktree' && args[1] === 'remove') { fs.rmSync(args[3], { recursive: true, force: true }); process.exit(0); }",
|
||||
"const key = args.join('\\u0000');",
|
||||
"const response = responses.get(key);",
|
||||
"if (!response) { process.exit(1); }",
|
||||
@@ -1517,9 +1526,7 @@ describe.concurrent("scripts/crabbox-wrapper", () => {
|
||||
expect(output.args).toContain("--shell");
|
||||
expect(remoteCommand).toContain("$openclawModulesDir = $env:PNPM_CONFIG_MODULES_DIR");
|
||||
expect(remoteCommand).toContain('mklink /J "$openclawSelfModules" "$openclawModulesDir"');
|
||||
expect(remoteCommand).toContain(
|
||||
'mklink /J "$openclawWorkspaceModules" "$openclawModulesDir"',
|
||||
);
|
||||
expect(remoteCommand).toContain('mklink /J "$openclawWorkspaceModules" "$openclawModulesDir"');
|
||||
expect(remoteCommand).toContain("corepack pnpm check:changed");
|
||||
});
|
||||
|
||||
@@ -2390,6 +2397,31 @@ describe.concurrent("scripts/crabbox-wrapper", () => {
|
||||
expect(parseFakeCrabboxOutput(result).cwd).toContain("openclaw-crabbox-sync-");
|
||||
});
|
||||
|
||||
it("creates sparse-sync temporary full checkouts under the durable cache root", () => {
|
||||
const syncRoot = path.join(repoRoot, ".crabbox-test-sync-root");
|
||||
rmSync(syncRoot, { recursive: true, force: true });
|
||||
try {
|
||||
const result = runWrapper(
|
||||
"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
|
||||
["run", "--provider", "aws", "--", "echo ok"],
|
||||
{
|
||||
env: { OPENCLAW_CRABBOX_SYNC_TMPDIR: syncRoot },
|
||||
gitResponses: {
|
||||
[GIT_CONFIG_SPARSE_KEY]: { stdout: "true\n" },
|
||||
[GIT_STATUS_PORCELAIN_KEY]: { stdout: "" },
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const output = parseFakeCrabboxOutput(result);
|
||||
expect(result.status).toBe(0);
|
||||
expect(output.cwd).toContain(`${syncRoot}${path.sep}openclaw-crabbox-sync-`);
|
||||
expect(readdirSync(syncRoot)).toEqual([]);
|
||||
} finally {
|
||||
rmSync(syncRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("uses a temporary full checkout when existing AWS leases sync clean sparse worktrees", () => {
|
||||
const result = runWrapper(
|
||||
"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
|
||||
|
||||
Reference in New Issue
Block a user