diff --git a/src/infra/update-runner.test.ts b/src/infra/update-runner.test.ts index 918b0d3c8..ec9462ac8 100644 --- a/src/infra/update-runner.test.ts +++ b/src/infra/update-runner.test.ts @@ -112,7 +112,6 @@ describe("runGatewayUpdate", () => { "pnpm install": { stdout: "" }, "pnpm build": { stdout: "" }, "pnpm ui:build": { stdout: "" }, - [`git -C ${tempDir} checkout -- dist/control-ui/`]: { stdout: "" }, "pnpm openclaw doctor --non-interactive": { stdout: "" }, }); @@ -128,6 +127,38 @@ describe("runGatewayUpdate", () => { expect(calls).not.toContain(`git -C ${tempDir} checkout --detach ${betaTag}`); }); + it("does not attempt to restore gitignored dist/control-ui/ (#4546)", async () => { + await fs.mkdir(path.join(tempDir, ".git")); + await fs.writeFile( + path.join(tempDir, "package.json"), + JSON.stringify({ name: "openclaw", version: "1.0.0", packageManager: "pnpm@8.0.0" }), + "utf-8", + ); + const tag = "v2.0.0-1"; + const { runner, calls } = createRunner({ + [`git -C ${tempDir} rev-parse --show-toplevel`]: { stdout: tempDir }, + [`git -C ${tempDir} rev-parse HEAD`]: { stdout: "abc123" }, + [`git -C ${tempDir} status --porcelain -- :!dist/control-ui/`]: { stdout: "" }, + [`git -C ${tempDir} fetch --all --prune --tags`]: { stdout: "" }, + [`git -C ${tempDir} tag --list v* --sort=-v:refname`]: { stdout: `${tag}\n` }, + [`git -C ${tempDir} checkout --detach ${tag}`]: { stdout: "" }, + "pnpm install": { stdout: "" }, + "pnpm build": { stdout: "" }, + "pnpm ui:build": { stdout: "" }, + "pnpm openclaw doctor --non-interactive": { stdout: "" }, + }); + + const result = await runGatewayUpdate({ + cwd: tempDir, + runCommand: async (argv, _options) => runner(argv), + timeoutMs: 5000, + channel: "stable", + }); + + expect(result.status).toBe("ok"); + expect(calls.some((c) => c.includes("checkout -- dist/control-ui/"))).toBe(false); + }); + it("skips update when no git root", async () => { await fs.writeFile( path.join(tempDir, "package.json"), diff --git a/src/infra/update-runner.ts b/src/infra/update-runner.ts index 5136d9f78..0eef614d2 100644 --- a/src/infra/update-runner.ts +++ b/src/infra/update-runner.ts @@ -364,7 +364,7 @@ export async function runGatewayUpdate(opts: UpdateRunnerOptions = {}): Promise< const channel: UpdateChannel = opts.channel ?? "dev"; const branch = channel === "dev" ? await readBranchName(runCommand, gitRoot, timeoutMs) : null; const needsCheckoutMain = channel === "dev" && branch !== DEV_BRANCH; - gitTotalSteps = channel === "dev" ? (needsCheckoutMain ? 11 : 10) : 9; + gitTotalSteps = channel === "dev" ? (needsCheckoutMain ? 10 : 9) : 8; const statusCheck = await runStep( step( @@ -676,17 +676,6 @@ export async function runGatewayUpdate(opts: UpdateRunnerOptions = {}): Promise< ); steps.push(uiBuildStep); - // Restore dist/control-ui/ to committed state to prevent dirty repo after update - // (ui:build regenerates assets with new hashes, which would block future updates) - const restoreUiStep = await runStep( - step( - "restore control-ui", - ["git", "-C", gitRoot, "checkout", "--", "dist/control-ui/"], - gitRoot, - ), - ); - steps.push(restoreUiStep); - const doctorStep = await runStep( step( "openclaw doctor",