test(install-e2e): accept the current checker's countless update offer and the macOS installer marker

The current source checker reports updateAvailable with behind null when GitHub
compare cannot count staged commits; the app-update predicate demanded an integer
behind and refused every HEAD->NEXT leg. Require behind > 0 only for the historical
shape without updateAvailable.

v2026.6.19's DMG bootstrap runs the same install.sh that writes .install_method,
so its macOS leg saw a dirty tree. Share the Linux driver's guarded exclude through
source-driver.sh and apply it before every app-driven macOS update.
This commit is contained in:
ethernet
2026-09-24 10:42:00 -04:00
parent 7b68fa7700
commit f43c38affc
6 changed files with 54 additions and 17 deletions

View File

@@ -74,7 +74,8 @@ test('checks the live Desktop bridge against the staged target before opening Ab
const f = fixture({ statusOverride: { supported: true, branch: 'main', currentSha: 'b'.repeat(40), targetSha: sha, behind: 1, dirty: false } })
await updateUi.assertStagedBranch(f.page, sha, f.log)
expect(f.log).toHaveBeenCalledWith(expect.stringContaining('"targetSha"'))
const current = fixture({ statusOverride: { supported: true, branch: 'main', currentSha: 'b'.repeat(40), targetSha: sha, behind: 1, updateAvailable: true } })
// The current checker's hosted shape: it cannot count staged commits via GitHub compare.
const current = fixture({ statusOverride: { supported: true, branch: 'main', currentSha: 'b'.repeat(40), targetSha: sha, behind: null, commits: [], updateAvailable: true } })
await updateUi.assertStagedBranch(current.page, sha, current.log)
const racing = fixture()
let checks = 0
@@ -90,6 +91,7 @@ test('checks the live Desktop bridge against the staged target before opening Ab
{ supported: true, branch: 'main', targetSha: sha, behind: 0 },
{ supported: true, branch: 'main', currentSha: sha, targetSha: sha, behind: 1 },
{ supported: true, branch: 'main', targetSha: sha, behind: 1, updateAvailable: false },
{ supported: true, branch: 'main', currentSha: 'b'.repeat(40), targetSha: sha, behind: null },
]) {
const refused = fixture({ statusOverride })
await expect(updateUi.assertStagedBranch(refused.page, sha, refused.log)).rejects.toThrow(/refusing to click/)

View File

@@ -20,6 +20,21 @@ source_hermes() {
printf '%s\n' "$command"
}
# v2026.6.19's install.sh (also run by its DMG bootstrap) writes .install_method
# into the checkout without ignoring it, and that release's Desktop checker
# reports git status --porcelain verbatim. Teach only this disposable clone that
# the installer's own marker is not a source edit; keep the marker for
# install-method detection and refuse any other dirty state.
accept_installer_marker() {
local root="$1" status
status="$(git -C "$root" status --porcelain --untracked-files=all)" || return 1
if [ "$status" = '?? .install_method' ] && [ "$(cat "$root/.install_method")" = git ]; then
printf '\n/.install_method\n' >> "$(git -C "$root" rev-parse --absolute-git-dir)/info/exclude"
status="$(git -C "$root" status --porcelain --untracked-files=all)" || return 1
fi
[ -z "$status" ] || { printf 'installed source has changes other than the installer marker:\n%s\n' "$status" >&2; return 1; }
}
# Hand out a command to DRIVE the next ordinary startup, even when the
# published launcher is not there yet.
#

View File

@@ -90,12 +90,16 @@ async function assertStagedBranch(page, expectedSha, log) {
await page.waitForTimeout(1_000)
}
// Historical Desktop status has no updateAvailable field: its About/overlay
// offers the button when behind > 0. Never accept an explicit false from a
// newer checker, a dirty source tree, or merely a matching remote tip.
// offers the button when behind > 0. A newer checker states updateAvailable
// and leaves behind null when it cannot count (GitHub compare does not know a
// staged commit). Never accept an explicit false, a dirty source tree, or
// merely a matching remote tip.
const offered = status.updateAvailable === undefined
? Number.isInteger(status.behind) && status.behind > 0
: status.updateAvailable === true
if (status.supported !== true || status.error || status.dirty === true ||
status.branch !== 'main' || status.targetSha !== expectedSha ||
!Number.isInteger(status.behind) || status.behind <= 0 ||
status.currentSha === expectedSha || status.updateAvailable === false) {
status.currentSha === expectedSha || !offered) {
throw new Error('Desktop source check did not offer staged Git main; refusing to click an unrelated update')
}
}

View File

@@ -452,18 +452,7 @@ case "$UPDATE_METHOD" in
# fixup) runs for real in the installed code.
EXPECT_DESKTOP=present
HERMES="$(source_hermes "$INSTALL_DIR")" || fail "no installed desktop command"
# v2026.6.19's installer writes this marker into its checkout without
# ignoring it. Its Electron checker reports git status --porcelain verbatim;
# teach only this disposable clone that the installer's own state is not
# a source edit. Keep the marker for install-method detection and refuse
# any other dirty state rather than masking it for the GUI update.
marker_status="$(git -C "$INSTALL_DIR" status --porcelain --untracked-files=all)"
if [ "$marker_status" = '?? .install_method' ] &&
[ "$(cat "$INSTALL_DIR/.install_method")" = git ]; then
printf '\n/.install_method\n' >> "$(git -C "$INSTALL_DIR" rev-parse --absolute-git-dir)/info/exclude"
ok "ignored only the installer's generated .install_method in local Git exclude"
fi
[ -z "$(git -C "$INSTALL_DIR" status --porcelain --untracked-files=all)" ] \
accept_installer_marker "$INSTALL_DIR" \
|| fail "installed source has changes other than the generated install marker"
ASSETS="$REPO_ROOT/tests/install/e2e-assets"
SPEC="$WORK_ROOT/launch-spec.json"

View File

@@ -271,6 +271,8 @@ run_playwright_update() {
# $1: spec file to launch from.
local spec="$1"
local rc=0
accept_installer_marker "$INSTALL_DIR" \
|| fail "installed source has changes other than the generated install marker"
(cd "$WORK_ROOT" && "$HERMES_E2E_NODE" "$ASSETS/launch-from-spec.mjs" \
--spec "$spec" \
--old-sha "$OLD_SHA" --chat-out "$LOG_DIR/update-window" --mock-url "$HERMES_E2E_MOCK_URL" \

View File

@@ -47,6 +47,31 @@ if source_hermes "$INSTALL_DIR"; then exit 92; fi
assert result.stdout.splitlines() == ["published:literal argument", "legacy"]
@pytest.mark.platforms("posix")
def test_installer_marker_is_the_only_dirty_state_a_driver_accepts(tmp_path):
root = tmp_path / "installed source"
root.mkdir()
git = ["git", "-C", str(root), "-c", "user.name=t", "-c", "user.email=t@t"]
subprocess.run([*git, "init", "-q"], check=True)
(root / "tracked").write_text("v1\n", encoding="utf-8")
subprocess.run([*git, "add", "tracked"], check=True)
subprocess.run([*git, "commit", "-qm", "base"], check=True)
(root / ".install_method").write_text("git\n", encoding="utf-8")
env = dict(os.environ, INSTALL_DIR=str(root), ASSETS=str(ASSETS), HOME=str(tmp_path))
def accept():
return subprocess.run(["bash", "-euc", 'source "$ASSETS/source-driver.sh"; accept_installer_marker "$INSTALL_DIR"'],
env=env, capture_output=True, text=True, timeout=30)
assert accept().returncode == 0
assert (root / ".install_method").read_text(encoding="utf-8") == "git\n"
assert subprocess.run([*git, "status", "--porcelain", "--untracked-files=all"],
capture_output=True, text=True, check=True).stdout == ""
(root / "tracked").write_text("edited\n", encoding="utf-8")
refused = accept()
assert refused.returncode != 0 and "M tracked" in refused.stderr
@pytest.mark.platforms("windows", "posix")
def test_powershell_selects_exact_exe_or_cmd_and_legacy_fallback(tmp_path):
# These are file-selection rules, not Windows execution emulation. Run