Update: ignore dist/control-ui in dirty check (#1976)

Co-authored-by: Glucksberg <glucksberg@users.noreply.github.com>
This commit is contained in:
Shadow
2026-01-25 21:07:51 -06:00
parent 5d2ef89e03
commit 6d60c32570
4 changed files with 26 additions and 8 deletions

View File

@@ -14,6 +14,7 @@ Status: unreleased.
- CI: increase Node heap size for macOS checks. (#1890) Thanks @realZachi. - CI: increase Node heap size for macOS checks. (#1890) Thanks @realZachi.
- macOS: avoid crash when rendering code blocks by bumping Textual to 0.3.1. (#2033) Thanks @garricn. - macOS: avoid crash when rendering code blocks by bumping Textual to 0.3.1. (#2033) Thanks @garricn.
- Browser: fall back to URL matching for extension relay target resolution. (#1999) Thanks @jonit-dev. - Browser: fall back to URL matching for extension relay target resolution. (#1999) Thanks @jonit-dev.
- Update: ignore dist/control-ui for dirty checks and restore after ui builds. (#1976) Thanks @Glucksberg.
## 2026.1.24-3 ## 2026.1.24-3

View File

@@ -129,9 +129,10 @@ export async function checkGitUpdateStatus(params: {
).catch(() => null); ).catch(() => null);
const upstream = upstreamRes && upstreamRes.code === 0 ? upstreamRes.stdout.trim() : null; const upstream = upstreamRes && upstreamRes.code === 0 ? upstreamRes.stdout.trim() : null;
const dirtyRes = await runCommandWithTimeout(["git", "-C", root, "status", "--porcelain"], { const dirtyRes = await runCommandWithTimeout(
timeoutMs, ["git", "-C", root, "status", "--porcelain", "--", ":!dist/control-ui/"],
}).catch(() => null); { timeoutMs },
).catch(() => null);
const dirty = dirtyRes && dirtyRes.code === 0 ? dirtyRes.stdout.trim().length > 0 : null; const dirty = dirtyRes && dirtyRes.code === 0 ? dirtyRes.stdout.trim().length > 0 : null;
const fetchOk = params.fetch const fetchOk = params.fetch

View File

@@ -44,7 +44,7 @@ describe("runGatewayUpdate", () => {
[`git -C ${tempDir} rev-parse --show-toplevel`]: { stdout: tempDir }, [`git -C ${tempDir} rev-parse --show-toplevel`]: { stdout: tempDir },
[`git -C ${tempDir} rev-parse HEAD`]: { stdout: "abc123" }, [`git -C ${tempDir} rev-parse HEAD`]: { stdout: "abc123" },
[`git -C ${tempDir} rev-parse --abbrev-ref HEAD`]: { stdout: "main" }, [`git -C ${tempDir} rev-parse --abbrev-ref HEAD`]: { stdout: "main" },
[`git -C ${tempDir} status --porcelain`]: { stdout: " M README.md" }, [`git -C ${tempDir} status --porcelain -- :!dist/control-ui/`]: { stdout: " M README.md" },
}); });
const result = await runGatewayUpdate({ const result = await runGatewayUpdate({
@@ -69,7 +69,7 @@ describe("runGatewayUpdate", () => {
[`git -C ${tempDir} rev-parse --show-toplevel`]: { stdout: tempDir }, [`git -C ${tempDir} rev-parse --show-toplevel`]: { stdout: tempDir },
[`git -C ${tempDir} rev-parse HEAD`]: { stdout: "abc123" }, [`git -C ${tempDir} rev-parse HEAD`]: { stdout: "abc123" },
[`git -C ${tempDir} rev-parse --abbrev-ref HEAD`]: { stdout: "main" }, [`git -C ${tempDir} rev-parse --abbrev-ref HEAD`]: { stdout: "main" },
[`git -C ${tempDir} status --porcelain`]: { stdout: "" }, [`git -C ${tempDir} status --porcelain -- :!dist/control-ui/`]: { stdout: "" },
[`git -C ${tempDir} rev-parse --abbrev-ref --symbolic-full-name @{upstream}`]: { [`git -C ${tempDir} rev-parse --abbrev-ref --symbolic-full-name @{upstream}`]: {
stdout: "origin/main", stdout: "origin/main",
}, },
@@ -103,7 +103,7 @@ describe("runGatewayUpdate", () => {
const { runner, calls } = createRunner({ const { runner, calls } = createRunner({
[`git -C ${tempDir} rev-parse --show-toplevel`]: { stdout: tempDir }, [`git -C ${tempDir} rev-parse --show-toplevel`]: { stdout: tempDir },
[`git -C ${tempDir} rev-parse HEAD`]: { stdout: "abc123" }, [`git -C ${tempDir} rev-parse HEAD`]: { stdout: "abc123" },
[`git -C ${tempDir} status --porcelain`]: { stdout: "" }, [`git -C ${tempDir} status --porcelain -- :!dist/control-ui/`]: { stdout: "" },
[`git -C ${tempDir} fetch --all --prune --tags`]: { stdout: "" }, [`git -C ${tempDir} fetch --all --prune --tags`]: { stdout: "" },
[`git -C ${tempDir} tag --list v* --sort=-v:refname`]: { [`git -C ${tempDir} tag --list v* --sort=-v:refname`]: {
stdout: `${stableTag}\n${betaTag}\n`, stdout: `${stableTag}\n${betaTag}\n`,
@@ -112,6 +112,7 @@ describe("runGatewayUpdate", () => {
"pnpm install": { stdout: "" }, "pnpm install": { stdout: "" },
"pnpm build": { stdout: "" }, "pnpm build": { stdout: "" },
"pnpm ui:build": { stdout: "" }, "pnpm ui:build": { stdout: "" },
[`git -C ${tempDir} checkout -- dist/control-ui/`]: { stdout: "" },
"pnpm clawdbot doctor --non-interactive": { stdout: "" }, "pnpm clawdbot doctor --non-interactive": { stdout: "" },
}); });

View File

@@ -346,10 +346,14 @@ export async function runGatewayUpdate(opts: UpdateRunnerOptions = {}): Promise<
const channel: UpdateChannel = opts.channel ?? "dev"; const channel: UpdateChannel = opts.channel ?? "dev";
const branch = channel === "dev" ? await readBranchName(runCommand, gitRoot, timeoutMs) : null; const branch = channel === "dev" ? await readBranchName(runCommand, gitRoot, timeoutMs) : null;
const needsCheckoutMain = channel === "dev" && branch !== DEV_BRANCH; const needsCheckoutMain = channel === "dev" && branch !== DEV_BRANCH;
gitTotalSteps = channel === "dev" ? (needsCheckoutMain ? 10 : 9) : 8; gitTotalSteps = channel === "dev" ? (needsCheckoutMain ? 11 : 10) : 9;
const statusCheck = await runStep( const statusCheck = await runStep(
step("clean check", ["git", "-C", gitRoot, "status", "--porcelain"], gitRoot), step(
"clean check",
["git", "-C", gitRoot, "status", "--porcelain", "--", ":!dist/control-ui/"],
gitRoot,
),
); );
steps.push(statusCheck); steps.push(statusCheck);
const hasUncommittedChanges = const hasUncommittedChanges =
@@ -654,6 +658,17 @@ export async function runGatewayUpdate(opts: UpdateRunnerOptions = {}): Promise<
); );
steps.push(uiBuildStep); 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( const doctorStep = await runStep(
step( step(
"clawdbot doctor", "clawdbot doctor",