mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 21:00:44 +00:00
fix: propagate update timeout to plugin installs
This commit is contained in:
@@ -594,6 +594,7 @@ async function resolveCompatiblePackageVersion(params: {
|
||||
requestedVersion?: string;
|
||||
baseUrl?: string;
|
||||
token?: string;
|
||||
timeoutMs?: number;
|
||||
}): Promise<
|
||||
| {
|
||||
ok: true;
|
||||
@@ -617,6 +618,7 @@ async function resolveCompatiblePackageVersion(params: {
|
||||
version: requestedVersion,
|
||||
baseUrl: params.baseUrl,
|
||||
token: params.token,
|
||||
timeoutMs: params.timeoutMs,
|
||||
});
|
||||
} catch (error) {
|
||||
return mapClawHubRequestError(error, {
|
||||
@@ -747,6 +749,7 @@ export async function installPluginFromClawHub(
|
||||
logger?: PluginInstallLogger;
|
||||
mode?: "install" | "update";
|
||||
extensionsDir?: string;
|
||||
timeoutMs?: number;
|
||||
dryRun?: boolean;
|
||||
expectedPluginId?: string;
|
||||
},
|
||||
@@ -775,6 +778,7 @@ export async function installPluginFromClawHub(
|
||||
name: parsed.name,
|
||||
baseUrl: params.baseUrl,
|
||||
token: params.token,
|
||||
timeoutMs: params.timeoutMs,
|
||||
});
|
||||
} catch (error) {
|
||||
return mapClawHubRequestError(error, {
|
||||
@@ -787,6 +791,7 @@ export async function installPluginFromClawHub(
|
||||
requestedVersion: parsed.version,
|
||||
baseUrl: params.baseUrl,
|
||||
token: params.token,
|
||||
timeoutMs: params.timeoutMs,
|
||||
});
|
||||
if (!versionState.ok) {
|
||||
return versionState;
|
||||
@@ -821,6 +826,7 @@ export async function installPluginFromClawHub(
|
||||
version: versionState.version,
|
||||
baseUrl: params.baseUrl,
|
||||
token: params.token,
|
||||
timeoutMs: params.timeoutMs,
|
||||
});
|
||||
} catch (error) {
|
||||
return buildClawHubInstallFailure(formatErrorMessage(error));
|
||||
@@ -864,6 +870,7 @@ export async function installPluginFromClawHub(
|
||||
logger: params.logger,
|
||||
mode: params.mode,
|
||||
extensionsDir: params.extensionsDir,
|
||||
timeoutMs: params.timeoutMs,
|
||||
dryRun: params.dryRun,
|
||||
expectedPluginId: params.expectedPluginId,
|
||||
});
|
||||
|
||||
@@ -1156,6 +1156,7 @@ export async function installPluginFromMarketplace(
|
||||
logger: params.logger,
|
||||
mode: params.mode,
|
||||
extensionsDir: params.extensionsDir,
|
||||
timeoutMs: params.timeoutMs,
|
||||
dryRun: params.dryRun,
|
||||
expectedPluginId: params.expectedPluginId,
|
||||
});
|
||||
|
||||
@@ -214,12 +214,14 @@ function expectNpmUpdateCall(params: {
|
||||
spec: string;
|
||||
expectedIntegrity?: string;
|
||||
expectedPluginId?: string;
|
||||
timeoutMs?: number;
|
||||
}) {
|
||||
expect(installPluginFromNpmSpecMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
spec: params.spec,
|
||||
expectedIntegrity: params.expectedIntegrity,
|
||||
...(params.expectedPluginId ? { expectedPluginId: params.expectedPluginId } : {}),
|
||||
...(params.timeoutMs ? { timeoutMs: params.timeoutMs } : {}),
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -355,6 +357,48 @@ describe("updateNpmInstalledPlugins", () => {
|
||||
},
|
||||
);
|
||||
|
||||
it("passes timeout budget to npm plugin metadata checks and installs", async () => {
|
||||
const installPath = createInstalledPackageDir({
|
||||
name: "@martian-engineering/lossless-claw",
|
||||
version: "0.9.0",
|
||||
});
|
||||
mockNpmViewMetadata({
|
||||
name: "@martian-engineering/lossless-claw",
|
||||
version: "0.10.0",
|
||||
integrity: "sha512-next",
|
||||
});
|
||||
installPluginFromNpmSpecMock.mockResolvedValue(
|
||||
createSuccessfulNpmUpdateResult({
|
||||
pluginId: "lossless-claw",
|
||||
targetDir: installPath,
|
||||
version: "0.10.0",
|
||||
}),
|
||||
);
|
||||
|
||||
await updateNpmInstalledPlugins({
|
||||
config: createNpmInstallConfig({
|
||||
pluginId: "lossless-claw",
|
||||
spec: "@martian-engineering/lossless-claw",
|
||||
installPath,
|
||||
resolvedName: "@martian-engineering/lossless-claw",
|
||||
resolvedSpec: "@martian-engineering/lossless-claw@0.9.0",
|
||||
resolvedVersion: "0.9.0",
|
||||
}),
|
||||
pluginIds: ["lossless-claw"],
|
||||
timeoutMs: 1_800_000,
|
||||
});
|
||||
|
||||
const npmViewCall = runCommandWithTimeoutMock.mock.calls.find(
|
||||
([argv]) => Array.isArray(argv) && argv[0] === "npm" && argv[1] === "view",
|
||||
);
|
||||
expect(npmViewCall?.[1]).toEqual(expect.objectContaining({ timeoutMs: 1_800_000 }));
|
||||
expectNpmUpdateCall({
|
||||
spec: "@martian-engineering/lossless-claw",
|
||||
expectedPluginId: "lossless-claw",
|
||||
timeoutMs: 1_800_000,
|
||||
});
|
||||
});
|
||||
|
||||
it("skips npm reinstall and config rewrite when the installed artifact is unchanged", async () => {
|
||||
const installPath = createInstalledPackageDir({
|
||||
name: "@martian-engineering/lossless-claw",
|
||||
@@ -798,6 +842,7 @@ describe("updateNpmInstalledPlugins", () => {
|
||||
clawhubChannel: "official",
|
||||
}),
|
||||
pluginIds: ["demo"],
|
||||
timeoutMs: 1_800_000,
|
||||
});
|
||||
|
||||
expect(installPluginFromClawHubMock).toHaveBeenCalledWith(
|
||||
@@ -806,6 +851,7 @@ describe("updateNpmInstalledPlugins", () => {
|
||||
baseUrl: "https://clawhub.ai",
|
||||
expectedPluginId: "demo",
|
||||
mode: "update",
|
||||
timeoutMs: 1_800_000,
|
||||
}),
|
||||
);
|
||||
expect(result.config.plugins?.installs?.demo).toMatchObject({
|
||||
@@ -930,6 +976,7 @@ describe("updateNpmInstalledPlugins", () => {
|
||||
marketplacePlugin: "claude-bundle",
|
||||
}),
|
||||
pluginIds: ["claude-bundle"],
|
||||
timeoutMs: 1_800_000,
|
||||
dryRun: true,
|
||||
});
|
||||
|
||||
@@ -939,6 +986,7 @@ describe("updateNpmInstalledPlugins", () => {
|
||||
plugin: "claude-bundle",
|
||||
expectedPluginId: "claude-bundle",
|
||||
dryRun: true,
|
||||
timeoutMs: 1_800_000,
|
||||
}),
|
||||
);
|
||||
expect(result.outcomes).toEqual([
|
||||
|
||||
@@ -469,6 +469,7 @@ export async function updateNpmInstalledPlugins(params: {
|
||||
logger?: PluginUpdateLogger;
|
||||
pluginIds?: string[];
|
||||
skipIds?: Set<string>;
|
||||
timeoutMs?: number;
|
||||
dryRun?: boolean;
|
||||
dangerouslyForceUnsafeInstall?: boolean;
|
||||
specOverrides?: Record<string, string>;
|
||||
@@ -567,7 +568,10 @@ export async function updateNpmInstalledPlugins(params: {
|
||||
});
|
||||
|
||||
if (!params.dryRun && record.source === "npm" && currentVersion) {
|
||||
const metadataResult = await resolveNpmSpecMetadata({ spec: effectiveSpec! });
|
||||
const metadataResult = await resolveNpmSpecMetadata({
|
||||
spec: effectiveSpec!,
|
||||
timeoutMs: params.timeoutMs,
|
||||
});
|
||||
if (metadataResult.ok) {
|
||||
if (
|
||||
shouldSkipUnchangedNpmInstall({
|
||||
@@ -604,6 +608,7 @@ export async function updateNpmInstalledPlugins(params: {
|
||||
spec: effectiveSpec!,
|
||||
mode: "update",
|
||||
extensionsDir,
|
||||
timeoutMs: params.timeoutMs,
|
||||
dryRun: true,
|
||||
dangerouslyForceUnsafeInstall: params.dangerouslyForceUnsafeInstall,
|
||||
expectedPluginId: pluginId,
|
||||
@@ -622,6 +627,7 @@ export async function updateNpmInstalledPlugins(params: {
|
||||
baseUrl: record.clawhubUrl,
|
||||
mode: "update",
|
||||
extensionsDir,
|
||||
timeoutMs: params.timeoutMs,
|
||||
dryRun: true,
|
||||
dangerouslyForceUnsafeInstall: params.dangerouslyForceUnsafeInstall,
|
||||
expectedPluginId: pluginId,
|
||||
@@ -632,6 +638,7 @@ export async function updateNpmInstalledPlugins(params: {
|
||||
plugin: record.marketplacePlugin!,
|
||||
mode: "update",
|
||||
extensionsDir,
|
||||
timeoutMs: params.timeoutMs,
|
||||
dryRun: true,
|
||||
dangerouslyForceUnsafeInstall: params.dangerouslyForceUnsafeInstall,
|
||||
expectedPluginId: pluginId,
|
||||
@@ -708,6 +715,7 @@ export async function updateNpmInstalledPlugins(params: {
|
||||
spec: effectiveSpec!,
|
||||
mode: "update",
|
||||
extensionsDir,
|
||||
timeoutMs: params.timeoutMs,
|
||||
dangerouslyForceUnsafeInstall: params.dangerouslyForceUnsafeInstall,
|
||||
expectedPluginId: pluginId,
|
||||
expectedIntegrity,
|
||||
@@ -725,6 +733,7 @@ export async function updateNpmInstalledPlugins(params: {
|
||||
baseUrl: record.clawhubUrl,
|
||||
mode: "update",
|
||||
extensionsDir,
|
||||
timeoutMs: params.timeoutMs,
|
||||
dangerouslyForceUnsafeInstall: params.dangerouslyForceUnsafeInstall,
|
||||
expectedPluginId: pluginId,
|
||||
logger,
|
||||
@@ -734,6 +743,7 @@ export async function updateNpmInstalledPlugins(params: {
|
||||
plugin: record.marketplacePlugin!,
|
||||
mode: "update",
|
||||
extensionsDir,
|
||||
timeoutMs: params.timeoutMs,
|
||||
dangerouslyForceUnsafeInstall: params.dangerouslyForceUnsafeInstall,
|
||||
expectedPluginId: pluginId,
|
||||
logger,
|
||||
|
||||
Reference in New Issue
Block a user