mirror of
https://github.com/nexu-io/open-design.git
synced 2026-10-27 09:51:12 +01:00
fix(release): repair Windows prerelease auth smoke (#6682)
This commit is contained in:
@@ -187,6 +187,13 @@ export async function installPackedWinApp(config: ToolPackConfig): Promise<WinIn
|
||||
await invokeNsis(paths, paths.setupPath, installArgs(config, paths), "install");
|
||||
}));
|
||||
if (!(await pathExists(paths.installedExePath))) throw new Error(`installer completed but executable is missing at ${paths.installedExePath}`);
|
||||
// Portable shipping builds omit namespaceBaseRoot so end users fall back to
|
||||
// Electron userData. The tools-pack installed copy must retain its isolated
|
||||
// runtime root for OS protocol cold launches, which inherit none of the
|
||||
// OD_PACKAGED_CONFIG_PATH environment used by `tools-pack win start`.
|
||||
await measureLifecycleStep(lifecycleTimings, "pin installed packaged namespace", async () => {
|
||||
await pinInstalledPackagedConfigNamespace(config, paths.installedExePath);
|
||||
});
|
||||
const registryEntries = await measureLifecycleStep(lifecycleTimings, "query registry", async () => queryWinRegistryEntries(paths, config));
|
||||
const installPayload = await measureLifecycleStep(lifecycleTimings, "collect payload report", async () => collectInstallPayloadReport(paths));
|
||||
await measureLifecycleStep(lifecycleTimings, "write install marker", async () => writeJsonMarker(paths.installMarkerPath, {
|
||||
@@ -214,16 +221,42 @@ export async function installPackedWinApp(config: ToolPackConfig): Promise<WinIn
|
||||
};
|
||||
}
|
||||
|
||||
async function writeInstalledLaunchPackagedConfig(config: ToolPackConfig, executablePath: string): Promise<string> {
|
||||
/**
|
||||
* Pin the tools-pack runtime namespace into the installed app's packaged config
|
||||
* and write the launch override used by `tools-pack win start`.
|
||||
*
|
||||
* The installed config is the only source available to a bare executable
|
||||
* launched through the Windows protocol registry. Keeping both copies
|
||||
* identical prevents that cold launch from resolving a different daemon data
|
||||
* root than the process started by tools-pack.
|
||||
*/
|
||||
async function pinInstalledPackagedConfigNamespace(
|
||||
config: ToolPackConfig,
|
||||
executablePath: string,
|
||||
): Promise<{ installedConfigPath: string; launchConfigPath: string }> {
|
||||
const installedConfigPath = join(dirname(executablePath), "resources", "open-design-config.json");
|
||||
if (!(await pathExists(installedConfigPath))) {
|
||||
throw new Error(`installed packaged config missing at ${installedConfigPath}`);
|
||||
}
|
||||
const raw = JSON.parse(await readFile(installedConfigPath, "utf8")) as Record<string, unknown>;
|
||||
if (typeof raw !== "object" || raw == null || Array.isArray(raw)) {
|
||||
throw new Error(`installed packaged config must be a JSON object: ${installedConfigPath}`);
|
||||
}
|
||||
const pinned = {
|
||||
...raw,
|
||||
namespace: config.namespace,
|
||||
namespaceBaseRoot: config.roots.runtime.namespaceBaseRoot,
|
||||
};
|
||||
const body = `${JSON.stringify(pinned, null, 2)}\n`;
|
||||
await writeFile(installedConfigPath, body, "utf8");
|
||||
const launchConfigPath = join(config.roots.runtime.namespaceRoot, "runtime", "launch-open-design-config.json");
|
||||
await mkdir(dirname(launchConfigPath), { recursive: true });
|
||||
await writeFile(
|
||||
launchConfigPath,
|
||||
`${JSON.stringify({ ...raw, namespaceBaseRoot: config.roots.runtime.namespaceBaseRoot }, null, 2)}\n`,
|
||||
"utf8",
|
||||
);
|
||||
await writeFile(launchConfigPath, body, "utf8");
|
||||
return { installedConfigPath, launchConfigPath };
|
||||
}
|
||||
|
||||
async function writeInstalledLaunchPackagedConfig(config: ToolPackConfig, executablePath: string): Promise<string> {
|
||||
const { launchConfigPath } = await pinInstalledPackagedConfigNamespace(config, executablePath);
|
||||
return launchConfigPath;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { access, mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
||||
import { access, mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { dirname, join } from "node:path";
|
||||
|
||||
@@ -110,6 +110,40 @@ async function writeFakeUnpackedExe(config: ToolPackConfig): Promise<void> {
|
||||
}
|
||||
|
||||
describe("installPackedWinApp", () => {
|
||||
it("pins the installed portable config to the tools-pack namespace for bare protocol launches", async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), "open-design-win-lifecycle-"));
|
||||
const config = { ...createConfig(root), portable: true };
|
||||
const paths = resolveWinPaths(config);
|
||||
const installedConfigPath = join(paths.installDir, "resources", "open-design-config.json");
|
||||
|
||||
try {
|
||||
await mkdir(dirname(paths.setupPath), { recursive: true });
|
||||
await writeFile(paths.setupPath, "", "utf8");
|
||||
invokeNsis.mockReset();
|
||||
invokeNsis.mockImplementation(async () => {
|
||||
await mkdir(dirname(installedConfigPath), { recursive: true });
|
||||
await writeFile(paths.installedExePath, "", "utf8");
|
||||
await writeFile(
|
||||
installedConfigPath,
|
||||
`${JSON.stringify({ channel: "prerelease", namespace: "baked-default" }, null, 2)}\n`,
|
||||
"utf8",
|
||||
);
|
||||
});
|
||||
|
||||
const result = await installPackedWinApp(config);
|
||||
const installedConfig = JSON.parse(await readFile(installedConfigPath, "utf8")) as Record<string, unknown>;
|
||||
|
||||
expect(installedConfig).toMatchObject({
|
||||
channel: "prerelease",
|
||||
namespace: config.namespace,
|
||||
namespaceBaseRoot: config.roots.runtime.namespaceBaseRoot,
|
||||
});
|
||||
expect(result.lifecycleTimings.map(({ step }) => step)).toContain("pin installed packaged namespace");
|
||||
} finally {
|
||||
await rm(root, { force: true, recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("creates the exact fresh install directory before invoking transactional NSIS", async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), "open-design-win-lifecycle-"));
|
||||
const config = createConfig(root);
|
||||
@@ -121,7 +155,10 @@ describe("installPackedWinApp", () => {
|
||||
invokeNsis.mockReset();
|
||||
invokeNsis.mockImplementation(async () => {
|
||||
await expect(access(paths.installDir)).resolves.toBeUndefined();
|
||||
const installedConfigPath = join(paths.installDir, "resources", "open-design-config.json");
|
||||
await mkdir(dirname(installedConfigPath), { recursive: true });
|
||||
await writeFile(paths.installedExePath, "", "utf8");
|
||||
await writeFile(installedConfigPath, "{}\n", "utf8");
|
||||
});
|
||||
|
||||
const result = await installPackedWinApp(config);
|
||||
|
||||
Reference in New Issue
Block a user