authorgravatar for 75276669+Gigioxx@users.noreply.github.comGuillermo Casanova <75276669+Gigioxx@users.noreply.github.com> 2026-09-15 19:21:25-03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-15 15:21:25-07:00
logb84f63bb13f13b1d0ee8537c4d244d6f1efdb987
tree93f8ff9cb146d39b9973bfee36b23b76747ac40c
parentf0a0ead946ca3f3f310460a91b7dabb0e3fe4834
signature Signed by PGP key B5690EEEBB952194

fix(server): block updates under legacy service launchers (#11940)


2 files changed, 13 insertions(+), 5 deletions(-)

apps/server/src/cloud/servicePreflight.test.ts+10-3
...@@ -3,15 +3,22 @@ import { expect, it } from "@effect/vitest";...@@ -3,15 +3,22 @@ import { expect, it } from "@effect/vitest";
3import { runServicePreflight } from "./servicePreflight.ts";3import { runServicePreflight } from "./servicePreflight.ts";
4import { SERVICE_LAUNCHER_PROTOCOL } from "./serviceProtocol.ts";4import { SERVICE_LAUNCHER_PROTOCOL } from "./serviceProtocol.ts";
55
6it("requires the database-snapshot launcher protocol", () => {6it.each([1, 2])("blocks legacy launcher protocol %i", (launcherProtocol) => {
7 expect(7 expect(
8 runServicePreflight({8 runServicePreflight({
9 databasePath: "/missing/state.sqlite",9 databasePath: "/missing/state.sqlite",
10 launcherProtocol: SERVICE_LAUNCHER_PROTOCOL - 1,10 launcherProtocol,
11 version: "1.2.3",11 version: "1.2.3",
12 }),12 }),
13 ).toMatchObject({ status: "blocked", version: "1.2.3" });13 ).toEqual({
14 status: "blocked",
15 version: "1.2.3",
16 reason:
17 "This release requires a newer T3 Code service launcher. Update it on the server machine.",
18 });
19});
1420
21it("accepts the current launcher protocol", () => {
15 expect(22 expect(
16 runServicePreflight({23 runServicePreflight({
17 databasePath: "/missing/state.sqlite",24 databasePath: "/missing/state.sqlite",
apps/server/src/cloud/serviceProtocol.ts+3-2
...@@ -1,7 +1,8 @@...@@ -1,7 +1,8 @@
1import type { ServerSelfUpdateOutcome } from "@t3tools/contracts";1import type { ServerSelfUpdateOutcome } from "@t3tools/contracts";
22
3/** Protocol 2 snapshots SQLite before trials so migrations can be rolled back safely. */3// Protocol 3 requires the standalone executable layout. Bump when runtimePaths
4export const SERVICE_LAUNCHER_PROTOCOL = 2 as const;4// or the installed runtime tree changes incompatibly; launchers survive self-updates.
5export const SERVICE_LAUNCHER_PROTOCOL = 3 as const;
5export const SERVICE_LAUNCHER_CONTEXT_ENV = "T3_SERVICE_LAUNCHER_CONTEXT";6export const SERVICE_LAUNCHER_CONTEXT_ENV = "T3_SERVICE_LAUNCHER_CONTEXT";
6export const SERVICE_STATE_FILE = "service-state.json";7export const SERVICE_STATE_FILE = "service-state.json";
7/** Written by the launcher just before an explicit stop kills its child, so8/** Written by the launcher just before an explicit stop kills its child, so