fix(dist): first-launch env setup on clean machines (no-git, read-only, py3.14) - #16
Merged
Conversation
First-launch `uv sync` failed on real user machines in three distinct ways, each surfaced by the new setup overlay. All three fixed: 1. NO GIT (× "Failed to download and build hyperspy … Git operation failed"). The hyperspy fork is a git+https dep, so `uv sync` shells out to `git clone`; a clean Windows box has no git. Vendor a portable git into the payload (like uv): bundle-python.mjs stages electron/vendor/git/<platform>/ into resources/python/git, pythonEnv.ts prepends git/cmd|bin to PATH for the sync, and release.yml downloads official MinGit on the Windows build leg. Verified: no git on PATH reproduces "Git operation failed"; git on PATH runs the clone. (macOS/Linux ship git → no vendored copy needed.) 2. ACCESS DENIED (× "could not create 'spyde.egg-info': Access is denied"). The shipped `spyde` source lives under read-only C:\Program Files\…; an EDITABLE install writes egg-info into that tree. Add --no-editable to both uv sync calls → spyde builds a wheel in temp and installs into the venv, touching nothing in the bundle. Verified: spyde lands as a non-editable dist-info in the env, source tree untouched. 3. PYTHON 3.14 (× torch 2.6.0+cu124 has no cp314 wheels). requires-python was an open ">=3.10", so uv grabbed 3.14 on fresh machines. Cap to ">=3.10,<3.14" and ship a `.python-version` = 3.12 (staged into the payload) so the managed env resolves an interpreter every dep has wheels for. Verified: uv now resolves 3.12.10. Also drop the rosettasciio fork (was only an MRC-read speed optimisation) for upstream PyPI rosettasciio[hdf5,image]>=0.14.0 — removes one git+https dep; large .mrc files just read via the stock path. Re-locked for all of the above.
The root .python-version=3.12 broke the CI test matrix: build.yml runs `uv sync --python 3.10/3.11/3.13` then `uv run pytest` (no --python), and a root .python-version makes every `uv run` re-create the venv at 3.12 — so the 3.10/3.11/3.13 matrix jobs failed (env rebuilt to 3.12, unsynced). Fix: don't ship .python-version at the repo root. bundle-python.mjs now WRITES it directly into the staged payload (resources/python/.python-version), so it pins 3.12 for the packaged app's first-launch `uv sync` on the user's machine while dev + CI stay free to use their matrix Python. Verified: with no root file, `uv sync --python 3.10` + `uv run python -V` reports 3.10.20 (was 3.12.10).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Make first-launch env setup work on clean machines
The new setup overlay surfaced three distinct first-launch
uv syncfailures on real user machines. All fixed here; also drops the rosettasciio fork.1. No git → "Failed to download and build hyperspy … Git operation failed"
The
hyperspyfork is agit+httpsdependency, souv syncshells out togit clone. A clean Windows box has no git → setup dies.Fix: vendor a portable git into the payload (same pattern as
uv):bundle-python.mjsstageselectron/vendor/git/<platform>/→resources/python/git/pythonEnv.tsprependsgit/cmd|binto PATH for the syncrelease.ymldownloads official MinGit on the Windows build legVerified: with no git on PATH I reproduced the exact
Git operation failed; with git on PATH the clone runs (standalone clone of the fork works fine). macOS/Linux ship git, so no vendored copy needed there.2. Access denied → "could not create 'spyde.egg-info': Access is denied"
The shipped
spydesource lives under read-onlyC:\Program Files\…; an editable install writesspyde.egg-infointo that tree.Fix:
--no-editableon bothuv synccalls → spyde builds a wheel in temp and installs into the venv, touching nothing in the bundle. Verified: spyde lands as a non-editabledist-infoin the env; source tree untouched.3. Python 3.14 → torch cu124 has no cp314 wheels
requires-pythonwas open (>=3.10), so uv grabbed 3.14 on fresh machines, for which the CUDA torch wheels don't exist.Fix: cap
>=3.10,<3.14+ ship.python-version= 3.12 (staged into the payload). Verified: uv now resolves 3.12.10.Also: drop the rosettasciio fork
It was only an MRC-read speed/memory optimization. Switched to upstream
rosettasciio[hdf5,image]>=0.14.0— removes onegit+httpsdep; large.mrcfiles just read via the stock path. Re-locked for all of the above.Verification notes
Reproduced #1 (fresh uv cache + no git) and confirmed git-on-PATH resolves it; validated #2/#3 by syncing into a fresh env (non-editable install, 3.12.10). A full packaged-installer test on a truly clean machine is the remaining real-world check (needs CI + the MinGit vendoring this PR adds).