Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/web/src/components/settings/UpdateTrackSwitchDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useState } from "react";
import { AsyncResult } from "effect/reactivity";

import { APP_VERSION } from "~/branding";
import { isLocalEnvironmentDisabled } from "~/localEnvironment";
import { useDesktopUpdateState } from "~/state/desktopUpdate";
import { useEnvironments } from "~/state/environments";
import { npmReleaseAtom, npmReleaseFailureMessage } from "~/state/npmRelease";
Expand Down Expand Up @@ -91,6 +92,7 @@ function SwitchPlan({
databaseMigration: environment.serverConfig?.environment.databaseMigration,
})),
window.desktopBridge?.getLocalEnvironmentBootstraps().length ?? 0,
!isLocalEnvironmentDisabled(),
);

const run = async () => {
Expand Down
30 changes: 26 additions & 4 deletions apps/web/src/components/sidebar/updateEverything.logic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,25 +254,47 @@ describe("localSwitchBlockReason", () => {
const nightly = "0.1.4-nightly.20261027.3796";

const windows = { connected: true, databaseMigration: 69 };
expect(localSwitchBlockReason(nightly, stable, [windows], 1)).toBeNull();
expect(localSwitchBlockReason(nightly, stable, [windows], 1, true)).toBeNull();
// A WSL server's newer migration blocks the reinstall that would restart it.
expect(
localSwitchBlockReason(
nightly,
stable,
[windows, { connected: true, databaseMigration: 72 }],
2,
true,
),
).toContain("does not support yet");
// A WSL backend still starting has no client entry, so its database is unchecked.
expect(localSwitchBlockReason(nightly, stable, [windows], 2)).toBe(
expect(localSwitchBlockReason(nightly, stable, [windows], 2, true)).toBe(
"its server is not connected, so its database cannot be checked",
);
// A cached head from a disconnected server proves nothing.
expect(
localSwitchBlockReason(nightly, stable, [{ connected: false, databaseMigration: 69 }], 1),
localSwitchBlockReason(
nightly,
stable,
[{ connected: false, databaseMigration: 69 }],
1,
true,
),
).toBe("its server is not connected, so its database cannot be checked");
expect(localSwitchBlockReason("0.1.3", stable, [], 1)).toBeNull();
expect(localSwitchBlockReason("0.1.3", stable, [], 1, true)).toBeNull();
});

it("does not block an app with Local environment off, which hosts no server", () => {
const nightly = {
channel: "nightly" as const,
version: "0.1.8-nightly.20261029.1",
databaseMigration: 72,
};
const stable = "0.1.7";

expect(localSwitchBlockReason(stable, nightly, [], 0, false)).toBeNull();
// With Local environment on, a primary backend still starting has no entry or bootstrap yet.
expect(localSwitchBlockReason(stable, nightly, [], 0, true)).toBe(
"its server is not connected, so its database cannot be checked",
);
});
});

Expand Down
6 changes: 4 additions & 2 deletions apps/web/src/components/sidebar/updateEverything.logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ function channelSwitchBlockReason(

/** This app's reinstall restarts every server it hosts, so each of their databases must allow the
* switch. `backendCount` is the desktop's own inventory: a backend still starting has no client
* entry yet. A cached config can outlive its connection, so only a connected server's head counts. */
* entry yet. A cached config can outlive its connection, so only a connected server's head counts.
* With Local environment off this app runs no server, so its reinstall restarts none. */
export function localSwitchBlockReason(
appVersion: string,
release: ChannelSwitchRelease,
Expand All @@ -185,8 +186,9 @@ export function localSwitchBlockReason(
readonly databaseMigration: number | undefined;
}>,
backendCount: number,
localEnvironmentEnabled: boolean,
): string | null {
if (!crossesTrack(appVersion, release)) return null;
if (!localEnvironmentEnabled || !crossesTrack(appVersion, release)) return null;
if (
hosted.length === 0 ||
hosted.length < backendCount ||
Expand Down
Loading