




















@@ -171,6 +171,7 @@ describe("resolveBuildAllSteps", () => {
171171"plugins:assets:copy",
172172"copy-hook-metadata",
173173"copy-export-html-templates",
174+"ui:build",
174175"write-build-info",
175176"write-cli-startup-metadata",
176177"write-cli-compat",
@@ -209,6 +210,39 @@ describe("resolveBuildAllSteps", () => {
209210);
210211});
211212213+it("includes ui:build in the full and ciArtifacts profiles after runtime postbuild", () => {
214+for (const profile of ["full", "ciArtifacts"]) {
215+const labels = resolveBuildAllSteps(profile).map((step) => step.label);
216+expect(labels).toContain("ui:build");
217+// Control UI bundling must run after tsdown clears dist so that
218+// dist/control-ui survives `pnpm build` without a second command.
219+expect(labels.indexOf("ui:build")).toBeGreaterThan(labels.indexOf("tsdown"));
220+expect(labels.indexOf("ui:build")).toBeGreaterThan(labels.indexOf("runtime-postbuild-stamp"));
221+// ui:build must run before write-build-info so the build manifest can
222+// see the final dist/control-ui assets.
223+expect(labels.indexOf("ui:build")).toBeLessThan(labels.indexOf("write-build-info"));
224+}
225+});
226+227+it("keeps ui:build out of minimal backend-only profiles", () => {
228+for (const profile of ["gatewayWatch", "cliStartup"]) {
229+const labels = resolveBuildAllSteps(profile).map((step) => step.label);
230+expect(labels).not.toContain("ui:build");
231+}
232+});
233+234+it("does not cache ui:build because Vite reads package.json, git HEAD, and env metadata", () => {
235+// ui/vite.config.ts derives the Control UI build ID from package.json,
236+// git HEAD, and OPENCLAW_CONTROL_UI_BUILD_ID env, so a file-input
237+// signature cannot exactly invalidate generated assets. Leaving this
238+// step uncached avoids restoring stale service-worker/app cache
239+// metadata after `tsdown` clears `dist`.
240+const step = getBuildAllStep("ui:build");
241+expect(step.kind).toBe("pnpm");
242+expect(step.pnpmArgs).toEqual(["ui:build"]);
243+expect(step.cache).toBeUndefined();
244+});
245+212246it("does not cache plugin-sdk entry shims over compiled JS", () => {
213247const step = getBuildAllStep("write-plugin-sdk-entry-dts");
214248expect(step.cache).toBeUndefined();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。