fix(FN-2462): enforce frozen-lockfile bootstrap across workflows

- Update CI, version, and test-release workflows to use pnpm install --frozen-lockfile consistently.
- Align contributor and settings documentation plus worktree init examples toward deterministic frozen-lockfile bootstrap.
- Clarify TaskExecutor worktree init guidance to distinguish dependency bootstrap failures from missing workspace dist export failures.
- Refresh workflow, executor, restart, and SettingsModal tests (including stable Node Sync tab selection) to assert the new bootstrap contract.
This commit is contained in:
Fusion
2026-04-24 11:41:10 -07:00
committed by gsxdsm
parent e480b8d411
commit 89b5b5d68c
12 changed files with 49 additions and 32 deletions

View File

@@ -2000,7 +2000,7 @@ export function SettingsModal({
<input
id="worktreeInitCommand"
type="text"
placeholder="pnpm install"
placeholder="pnpm install --frozen-lockfile"
value={form.worktreeInitCommand || ""}
onChange={(e) =>
setForm((f) => ({ ...f, worktreeInitCommand: e.target.value }))

View File

@@ -2638,7 +2638,7 @@ describe("SettingsModal", () => {
render(<SettingsModal onClose={onClose} addToast={addToast} />);
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
fireEvent.click(screen.getByText("Node Sync"));
fireEvent.click((await screen.findAllByText("Node Sync"))[0]);
expect(screen.getByText("Node Sync", { selector: "h4" })).toBeTruthy();
expect(screen.getByLabelText("Enable automatic settings sync")).toBeTruthy();
});
@@ -2652,7 +2652,7 @@ describe("SettingsModal", () => {
render(<SettingsModal onClose={onClose} addToast={addToast} />);
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
fireEvent.click(screen.getByText("Node Sync"));
fireEvent.click((await screen.findAllByText("Node Sync"))[0]);
expect(screen.queryByLabelText("Sync interval")).toBeNull();
expect(screen.queryByLabelText("Conflict resolution")).toBeNull();
});
@@ -2677,7 +2677,7 @@ describe("SettingsModal", () => {
render(<SettingsModal onClose={onClose} addToast={addToast} />);
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
fireEvent.click(screen.getByText("Node Sync"));
fireEvent.click((await screen.findAllByText("Node Sync"))[0]);
const checkbox = screen.getByLabelText("Enable automatic settings sync") as HTMLInputElement;
expect(checkbox.checked).toBe(false);
@@ -2695,7 +2695,7 @@ describe("SettingsModal", () => {
render(<SettingsModal onClose={onClose} addToast={addToast} />);
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
fireEvent.click(screen.getByText("Node Sync"));
fireEvent.click((await screen.findAllByText("Node Sync"))[0]);
const select = screen.getByLabelText("Sync interval") as HTMLSelectElement;
expect(select.value).toBe("900000");
@@ -2713,7 +2713,7 @@ describe("SettingsModal", () => {
render(<SettingsModal onClose={onClose} addToast={addToast} />);
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
fireEvent.click(screen.getByText("Node Sync"));
fireEvent.click((await screen.findAllByText("Node Sync"))[0]);
const select = screen.getByLabelText("Conflict resolution") as HTMLSelectElement;
expect(select.value).toBe("last-write-wins");
@@ -2725,7 +2725,7 @@ describe("SettingsModal", () => {
render(<SettingsModal onClose={onClose} addToast={addToast} />);
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
fireEvent.click(screen.getByText("Node Sync"));
fireEvent.click((await screen.findAllByText("Node Sync"))[0]);
const checkbox = screen.getByLabelText("Enable automatic settings sync");
fireEvent.click(checkbox);