惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
L
LangChain Blog
aimingoo的专栏
aimingoo的专栏
IT之家
IT之家
B
Blog
博客园_首页
博客园 - 司徒正美
有赞技术团队
有赞技术团队
博客园 - 聂微东
I
InfoQ
美团技术团队
GbyAI
GbyAI
阮一峰的网络日志
阮一峰的网络日志
H
Help Net Security
大猫的无限游戏
大猫的无限游戏
MyScale Blog
MyScale Blog
WordPress大学
WordPress大学
The GitHub Blog
The GitHub Blog
A
About on SuperTechFans
人人都是产品经理
人人都是产品经理
Microsoft Azure Blog
Microsoft Azure Blog
Engineering at Meta
Engineering at Meta
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Cloudflare Blog

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
fix(release): unblock full validation · openclaw/openclaw...
steipete · 2026-05-15 · via Recent Commits to openclaw:main

@@ -91,6 +91,7 @@ vi.mock("../config/config.js", () => ({

9191

},

9292

readConfigFileSnapshot: vi.fn(),

9393

readSourceConfigBestEffort: vi.fn(),

94+

mutateConfigFileWithRetry: vi.fn(),

9495

replaceConfigFile: vi.fn(),

9596

resolveGatewayPort: vi.fn(() => 18789),

9697

}));

@@ -268,7 +269,7 @@ vi.mock("../runtime.js", () => ({

268269

const { runGatewayUpdate } = await import("../infra/update-runner.js");

269270

const { resolveOpenClawPackageRoot } = await import("../infra/openclaw-root.js");

270271

const {

271-

ConfigMutationConflictError,

272+

mutateConfigFileWithRetry,

272273

readConfigFileSnapshot,

273274

readSourceConfigBestEffort,

274275

replaceConfigFile,

@@ -426,6 +427,31 @@ describe("update-cli", () => {

426427

const replaceConfigCall = (index = 0) => vi.mocked(replaceConfigFile).mock.calls[index]?.[0];

427428

const lastReplaceConfigCall = () =>

428429

replaceConfigCall(vi.mocked(replaceConfigFile).mock.calls.length - 1);

430+

const setupConfigMutationWithRetryMock = () => {

431+

vi.mocked(mutateConfigFileWithRetry).mockImplementation(async (params) => {

432+

const snapshot = await readConfigFileSnapshot();

433+

const nextConfig = structuredClone(snapshot.sourceConfig) as OpenClawConfig;

434+

await params.mutate(nextConfig, {

435+

snapshot,

436+

previousHash: snapshot.hash ?? null,

437+

attempt: 0,

438+

});

439+

await replaceConfigFile({

440+

nextConfig,

441+

...(snapshot.hash !== undefined ? { baseHash: snapshot.hash } : {}),

442+

});

443+

return {

444+

path: snapshot.path,

445+

previousHash: snapshot.hash ?? null,

446+

snapshot,

447+

nextConfig,

448+

result: undefined,

449+

attempts: 1,

450+

afterWrite: { mode: "none", reason: "test" },

451+

followUp: { mode: "none", reason: "test", requiresRestart: false },

452+

};

453+

});

454+

};

429455430456

const writeJsonCall = (index = 0) => vi.mocked(defaultRuntime.writeJson).mock.calls[index]?.[0];

431457

const lastWriteJsonCall = () =>

@@ -562,6 +588,7 @@ describe("update-cli", () => {

562588

vi.mocked(resolveOpenClawPackageRoot).mockResolvedValue(process.cwd());

563589

vi.mocked(readConfigFileSnapshot).mockResolvedValue(baseSnapshot);

564590

vi.mocked(readSourceConfigBestEffort).mockResolvedValue(baseSnapshot.config);

591+

setupConfigMutationWithRetryMock();

565592

vi.mocked(fetchNpmTagVersion).mockResolvedValue({

566593

tag: "latest",

567594

version: "9999.0.0",

@@ -1118,47 +1145,57 @@ describe("update-cli", () => {

11181145

});

1119114611201147

it("post-core resume mode retries update channel persistence after config hash drift", async () => {

1121-

vi.mocked(readConfigFileSnapshot)

1122-

.mockResolvedValueOnce({

1123-

...baseSnapshot,

1124-

parsed: { update: { channel: "stable" } },

1125-

resolved: { update: { channel: "stable" } } as OpenClawConfig,

1126-

sourceConfig: { update: { channel: "stable" } } as OpenClawConfig,

1127-

runtimeConfig: { update: { channel: "stable" } } as OpenClawConfig,

1128-

config: { update: { channel: "stable" } } as OpenClawConfig,

1129-

hash: "stable-hash",

1130-

})

1131-

.mockResolvedValueOnce({

1132-

...baseSnapshot,

1133-

parsed: {

1134-

meta: { lastTouchedVersion: "2026.4.30" },

1135-

update: { channel: "stable" },

1136-

},

1137-

resolved: {

1138-

meta: { lastTouchedVersion: "2026.4.30" },

1139-

update: { channel: "stable" },

1140-

} as OpenClawConfig,

1141-

sourceConfig: {

1142-

meta: { lastTouchedVersion: "2026.4.30" },

1143-

update: { channel: "stable" },

1144-

} as OpenClawConfig,

1145-

runtimeConfig: {

1146-

meta: { lastTouchedVersion: "2026.4.30" },

1147-

update: { channel: "stable" },

1148-

} as OpenClawConfig,

1149-

config: {

1150-

meta: { lastTouchedVersion: "2026.4.30" },

1151-

update: { channel: "stable" },

1152-

} as OpenClawConfig,

1153-

hash: "newer-hash",

1148+

vi.mocked(readConfigFileSnapshot).mockResolvedValueOnce({

1149+

...baseSnapshot,

1150+

parsed: { update: { channel: "stable" } },

1151+

resolved: { update: { channel: "stable" } } as OpenClawConfig,

1152+

sourceConfig: { update: { channel: "stable" } } as OpenClawConfig,

1153+

runtimeConfig: { update: { channel: "stable" } } as OpenClawConfig,

1154+

config: { update: { channel: "stable" } } as OpenClawConfig,

1155+

hash: "stable-hash",

1156+

});

1157+

const newerSnapshot = {

1158+

...baseSnapshot,

1159+

parsed: {

1160+

meta: { lastTouchedVersion: "2026.4.30" },

1161+

update: { channel: "stable" },

1162+

},

1163+

resolved: {

1164+

meta: { lastTouchedVersion: "2026.4.30" },

1165+

update: { channel: "stable" },

1166+

} as OpenClawConfig,

1167+

sourceConfig: {

1168+

meta: { lastTouchedVersion: "2026.4.30" },

1169+

update: { channel: "stable" },

1170+

} as OpenClawConfig,

1171+

runtimeConfig: {

1172+

meta: { lastTouchedVersion: "2026.4.30" },

1173+

update: { channel: "stable" },

1174+

} as OpenClawConfig,

1175+

config: {

1176+

meta: { lastTouchedVersion: "2026.4.30" },

1177+

update: { channel: "stable" },

1178+

} as OpenClawConfig,

1179+

hash: "newer-hash",

1180+

};

1181+

vi.mocked(mutateConfigFileWithRetry).mockImplementationOnce(async (params) => {

1182+

const nextConfig = structuredClone(newerSnapshot.sourceConfig);

1183+

await params.mutate(nextConfig, {

1184+

snapshot: newerSnapshot,

1185+

previousHash: newerSnapshot.hash,

1186+

attempt: 1,

11541187

});

1155-

vi.mocked(replaceConfigFile)

1156-

.mockRejectedValueOnce(

1157-

new ConfigMutationConflictError("config changed since last load", {

1158-

currentHash: "newer-hash",

1159-

}),

1160-

)

1161-

.mockResolvedValueOnce({} as Awaited<ReturnType<typeof replaceConfigFile>>);

1188+

return {

1189+

path: newerSnapshot.path,

1190+

previousHash: newerSnapshot.hash,

1191+

snapshot: newerSnapshot,

1192+

nextConfig,

1193+

result: undefined,

1194+

attempts: 2,

1195+

afterWrite: { mode: "none", reason: "test" },

1196+

followUp: { mode: "none", reason: "test", requiresRestart: false },

1197+

};

1198+

});

1162119911631200

await withEnvAsync(

11641201

{

@@ -1171,14 +1208,7 @@ describe("update-cli", () => {

11711208

},

11721209

);

117312101174-

expect(replaceConfigFile).toHaveBeenCalledTimes(2);

1175-

expect(replaceConfigFile).toHaveBeenLastCalledWith({

1176-

nextConfig: {

1177-

meta: { lastTouchedVersion: "2026.4.30" },

1178-

update: { channel: "dev" },

1179-

},

1180-

baseHash: "newer-hash",

1181-

});

1211+

expect(mutateConfigFileWithRetry).toHaveBeenCalledTimes(1);

11821212

expect(syncPluginCall()?.config?.meta?.lastTouchedVersion).toBe("2026.4.30");

11831213

expect(syncPluginCall()?.config?.update?.channel).toBe("dev");

11841214

});

@@ -2717,6 +2747,16 @@ describe("update-cli", () => {

27172747

},

27182748

],

27192749

})

2750+

.mockResolvedValueOnce({

2751+

...baseSnapshot,

2752+

parsed: migratedConfig,

2753+

resolved: migratedConfig,

2754+

sourceConfig: migratedConfig,

2755+

config: migratedConfig,

2756+

runtimeConfig: migratedConfig,

2757+

valid: true,

2758+

hash: "migrated-hash",

2759+

})

27202760

.mockResolvedValueOnce({

27212761

...baseSnapshot,

27222762

parsed: migratedConfig,