From b3618bda35be5420053b838f94afda84f3cb7b1f Mon Sep 17 00:00:00 2001 From: ethernet Date: Wed, 23 Sep 2026 15:50:58 -0400 Subject: [PATCH] fix(build): stop the runtime install stamp from staling web/desktop Install/update completion rewrites the root install-stamp.json (fresh builtAt) after products are built, and the stamp was still a shared web/desktop source input, so every install left its own web_dist "missing, stale, or damaged" and the post-install probe failed on every installer E2E leg. Nothing in either build reads the root stamp; desktop's baked stamp is already tracked as a prepared input. --- scripts/build/freshness.mjs | 4 +++- tests-js/product-builders.test.mjs | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/build/freshness.mjs b/scripts/build/freshness.mjs index 0f970daef1..5d9e244054 100644 --- a/scripts/build/freshness.mjs +++ b/scripts/build/freshness.mjs @@ -44,7 +44,9 @@ export function sourceHash(source, product) { workspace, 'apps/shared', 'package.json', 'package-lock.json', '.npmrc', 'pm/lock.json', 'scripts/build', 'scripts/generate-icons.mjs', 'scripts/generate_icons.py', - 'assets', 'pyproject.toml', 'uv.lock', 'install-stamp.json', + // The root install-stamp.json is runtime identity rewritten after every install; desktop's + // baked stamp is a prepared input. + 'assets', 'pyproject.toml', 'uv.lock', ], name => { // Build scripts are inputs; workspace build directories are outputs. const parts = name.split('/') diff --git a/tests-js/product-builders.test.mjs b/tests-js/product-builders.test.mjs index 4ad12cf460..7fb47f4f64 100644 --- a/tests-js/product-builders.test.mjs +++ b/tests-js/product-builders.test.mjs @@ -237,6 +237,9 @@ test('built web freshness follows shared sources and build inputs, not mtimes or expect(productCurrent({ source, product: 'web', out })).toBe(true) put(source, 'web/node_modules/.tmp/tsbuildinfo', 'generated') expect(productCurrent({ source, product: 'web', out })).toBe(true) + // Install completion rewrites the runtime identity after building products. + put(source, 'install-stamp.json', '{"builtAt": "later"}') + expect(productCurrent({ source, product: 'web', out })).toBe(true) put(icons, 'web/public/favicon.ico', 'changed prepared icon') expect(productCurrent({ source, product: 'web', out })).toBe(false) await buildWeb({ source, icons, out })