fix(migrations): v1.65 Chromium re-fetch actually re-downloads, and success is verified before .done

The migration (renamed from the provisional v1.64.0.0 slot, which open
PR #2564 claims) deleted only the poisoned .app while Playwright's
INSTALLATION_COMPLETE marker survived in the revision dir — so the
advertised 'bunx playwright install chromium' re-fetch no-opped and the
user finished the upgrade with no browser and a success message. Now:
the whole chromium-<rev> dir goes, bunx runs cwd-pinned to the install
root, .done is gated on a verified executable, and a needs-refetch
sentinel makes re-runs retry a failed download. Stranded rev dirs
(markers without .app) also re-trigger. 6 hermetic tests, red-first.
This commit is contained in:
Garry Tan
2026-08-14 17:11:48 -07:00
parent 3f53b9e173
commit fb20ada4ac
2 changed files with 233 additions and 75 deletions
-75
View File
@@ -1,75 +0,0 @@
#!/usr/bin/env bash
# Migration: v1.64.0.0 — repair Chrome-for-Testing bundles poisoned by the
# old in-place rebrand (#2242).
#
# Why a migration: pre-v1.64 launchHeaded() rewrote the Chromium .app's
# Info.plist ("Google Chrome for Testing" → "GStack Browser") and overwrote
# its Resources/*.icns — inside the SHARED Playwright cache. That broke the
# codesign seal (GPU process exit_code=5; headed mode dead on macOS 26) and
# poisoned the cache for the user's OTHER Playwright projects too. Deleting
# the rebrand code fixes fresh installs only; every existing macOS install
# still has the mutated bundle on disk. This migration removes poisoned
# bundles and re-fetches a clean one so the upgrade doesn't leave the user
# with zero working browser (the browse launch path also self-heals, as the
# belt to this suspenders, for installs that never run migrations).
#
# Affected: macOS installs that ever ran headed mode before v1.64.
#
# Idempotent: detection is content-based (plist contains "GStack Browser");
# a clean cache is a no-op, and the .done touchfile gates re-runs. The
# re-fetch is best-effort and non-fatal per the migration contract.
set -u
GSTACK_HOME="${GSTACK_HOME:-${HOME}/.gstack}"
MIGRATION_DIR="${GSTACK_HOME}/.migrations"
DONE="${MIGRATION_DIR}/v1.64.0.0.done"
mkdir -p "${MIGRATION_DIR}" 2>/dev/null || true
[ -f "${DONE}" ] && exit 0
# macOS only: the mutation targeted .app bundle plists.
if [ "$(uname -s 2>/dev/null)" != "Darwin" ]; then
touch "${DONE}"
exit 0
fi
PW_CACHE="${PLAYWRIGHT_BROWSERS_PATH:-${HOME}/Library/Caches/ms-playwright}"
REMOVED=0
if [ -d "${PW_CACHE}" ]; then
# Every Chrome-for-Testing bundle in the cache (one per pinned chromium build).
while IFS= read -r plist; do
if grep -q "GStack Browser" "${plist}" 2>/dev/null; then
app_dir="$(dirname "$(dirname "${plist}")")"
case "${app_dir}" in
"${PW_CACHE}"/*.app|"${PW_CACHE}"/*/*.app|"${PW_CACHE}"/*/*/*.app)
echo " [v1.64.0.0] removing rebrand-poisoned bundle: ${app_dir}" >&2
rm -rf "${app_dir}"
REMOVED=1
;;
*)
echo " [v1.64.0.0] WARNING: poisoned plist outside the Playwright cache shape, skipping: ${plist}" >&2
;;
esac
fi
done < <(find "${PW_CACHE}" -maxdepth 5 -name "Info.plist" -path "*.app/Contents/Info.plist" 2>/dev/null)
fi
if [ "${REMOVED}" = "1" ]; then
# Re-fetch immediately: migrations run AFTER ./setup, so without this the
# user finishes the upgrade with no working browser at all (headless AND
# headed use the same bundle). Best-effort — a failed download leaves the
# actionable command printed and the launch-time self-heal message covers
# the rest.
echo " [v1.64.0.0] re-fetching a clean Chromium (bunx playwright install chromium)..." >&2
if command -v bunx >/dev/null 2>&1 && bunx playwright install chromium >&2; then
echo " [v1.64.0.0] clean Chromium installed." >&2
else
echo " [v1.64.0.0] WARNING: automatic re-fetch failed. Run manually: bunx playwright install chromium" >&2
fi
else
echo " [v1.64.0.0] no rebrand-poisoned bundles found — no-op." >&2
fi
touch "${DONE}"
exit 0