mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-24 19:35:28 -06:00
fix: preserve plugin update recovery after commit (#125739)
This commit is contained in:
committed by
GitHub
parent
29d6fa6eb2
commit
f0dd7eecaa
@@ -895,6 +895,7 @@ describe("plugins cli update", () => {
|
||||
expect(notifyGatewayPluginMetadataChangedMock).not.toHaveBeenCalled();
|
||||
expect(rollback).toHaveBeenCalledTimes(1);
|
||||
expect(commit).not.toHaveBeenCalled();
|
||||
expect(pluginsCliRuntimeLogs.join("\n")).not.toContain("Updated");
|
||||
});
|
||||
|
||||
it("rolls back persisted install records when included config changes during a records-only update", async () => {
|
||||
@@ -1595,24 +1596,23 @@ describe("plugins cli update", () => {
|
||||
it("keeps durable state when transaction cleanup fails after the write", async () => {
|
||||
const cfg = {
|
||||
plugins: {
|
||||
installs: {
|
||||
alpha: {
|
||||
source: "npm",
|
||||
spec: "@openclaw/alpha@1.0.0",
|
||||
},
|
||||
entries: {
|
||||
alpha: { enabled: true },
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
const nextConfig = {
|
||||
plugins: {
|
||||
installs: {
|
||||
alpha: {
|
||||
source: "npm",
|
||||
spec: "@openclaw/alpha@1.1.0",
|
||||
},
|
||||
},
|
||||
const previousRecords = {
|
||||
alpha: {
|
||||
source: "npm" as const,
|
||||
spec: "@openclaw/alpha@1.0.0",
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
};
|
||||
const nextRecords = {
|
||||
alpha: {
|
||||
source: "npm" as const,
|
||||
spec: "@openclaw/alpha@1.1.0",
|
||||
},
|
||||
};
|
||||
const runtimeConfig = {
|
||||
...cfg,
|
||||
messages: {
|
||||
@@ -1620,7 +1620,11 @@ describe("plugins cli update", () => {
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
const nextRuntimeConfig = {
|
||||
...nextConfig,
|
||||
...runtimeConfig,
|
||||
plugins: {
|
||||
...runtimeConfig.plugins,
|
||||
installs: nextRecords,
|
||||
},
|
||||
messages: runtimeConfig.messages,
|
||||
} as OpenClawConfig;
|
||||
primeUpdateConfigSnapshot({
|
||||
@@ -1630,7 +1634,7 @@ describe("plugins cli update", () => {
|
||||
"/tmp/plugins.json5": "plugins-start-hash",
|
||||
},
|
||||
});
|
||||
setInstalledPluginIndexInstallRecords(cfg.plugins?.installs ?? {});
|
||||
setInstalledPluginIndexInstallRecords(previousRecords);
|
||||
const rollback = vi.fn(async () => undefined);
|
||||
const failedCommit = vi.fn(async () => {
|
||||
throw new Error("cleanup failed");
|
||||
@@ -1651,30 +1655,35 @@ describe("plugins cli update", () => {
|
||||
config: nextRuntimeConfig,
|
||||
});
|
||||
|
||||
await expect(runPluginsCommand(["plugins", "update", "alpha"])).rejects.toThrow(
|
||||
"Plugin install transaction commit failed",
|
||||
);
|
||||
await runPluginsCommand(["plugins", "update", "alpha"]);
|
||||
|
||||
const updateParams = expectSingleCallParams(updateNpmInstalledPluginsMock);
|
||||
expect(updateParams.config).toEqual(runtimeConfig);
|
||||
expect(updateParams.config).toEqual({
|
||||
...runtimeConfig,
|
||||
plugins: {
|
||||
...runtimeConfig.plugins,
|
||||
installs: previousRecords,
|
||||
},
|
||||
});
|
||||
expect(updateParams.pluginIds).toEqual(["alpha"]);
|
||||
expect(updateParams.dryRun).toBe(false);
|
||||
expectInstallRecordsWrittenWithLease(nextConfig.plugins?.installs, {});
|
||||
expectInstallRecordsWrittenWithLease(nextRecords, cfg);
|
||||
expect(updateNpmInstalledHookPacksMock).not.toHaveBeenCalled();
|
||||
expect(configWriteMock).toHaveBeenCalledWith({});
|
||||
expect(replaceConfigFileMock).toHaveBeenCalledWith({
|
||||
nextConfig: {},
|
||||
baseHash: "update-config",
|
||||
writeOptions: expect.objectContaining({
|
||||
includeFileHashesForWrite: {
|
||||
"/tmp/plugins.json5": "plugins-start-hash",
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(configWriteMock).not.toHaveBeenCalled();
|
||||
expect(replaceConfigFileMock).not.toHaveBeenCalled();
|
||||
expect(failedCommit).toHaveBeenCalledOnce();
|
||||
expect(remainingCommit).toHaveBeenCalledOnce();
|
||||
expect(rollback).not.toHaveBeenCalled();
|
||||
expect(refreshPluginRegistryMock).not.toHaveBeenCalled();
|
||||
expect(refreshPluginRegistryMock).toHaveBeenCalledWith({
|
||||
config: cfg,
|
||||
installRecords: nextRecords,
|
||||
reason: "source-changed",
|
||||
});
|
||||
expect(notifyGatewayPluginMetadataChangedMock).toHaveBeenCalledWith(runtimeConfig);
|
||||
expect(pluginsCliRuntimeLogs.join("\n")).toContain("Plugin update committed");
|
||||
expect(pluginsCliRuntimeLogs).toContain("Updated alpha -> 1.1.0");
|
||||
expect(pluginsCliRuntimeLogs.join("\n")).toContain("Restart is required");
|
||||
expectRestartNoticeLogged();
|
||||
});
|
||||
|
||||
it("exits non-zero when a plugin update reports an error after persisting successes", async () => {
|
||||
|
||||
Reference in New Issue
Block a user