diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 3f7141e..38e6405 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -14,7 +14,7 @@ body: attributes: label: ProtonShift version description: "Check the app's About dialog or `electron/package.json`." - placeholder: "0.8.5" + placeholder: "0.8.6" validations: required: true @@ -101,6 +101,8 @@ body: options: - AppImage - .deb package + - .rpm package + - Flatpak - Running from source (pnpm dev) - Other validations: diff --git a/.gitignore b/.gitignore index d5218b5..928c1e1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ node_modules/ .pnpm-store/ +# Vendored Python wheels for packaged Electron (generated by pnpm run vendor-python) +electron/python-vendor/ + # Build outputs — Electron electron/dist/ electron/out/ diff --git a/README.md b/README.md index 522e9a4..afb1057 100644 --- a/README.md +++ b/README.md @@ -212,24 +212,37 @@ Multiple visual themes with light and dark variants, switchable from the nav bar ## Installation -**Target:** Pop!_OS, Ubuntu 22.04+, Linux Mint, elementary OS. +Grab the latest package for your distro from the [Releases](https://github.com/I4cTime/protonshift/releases) page. -Grab the latest **AppImage** or **.deb** from the [Releases](https://github.com/I4cTime/protonshift/releases) page. - -### AppImage +### AppImage (any distro) ```bash chmod +x ProtonShift-*.AppImage ./ProtonShift-*.AppImage ``` -### .deb +### .deb (Ubuntu, Pop!_OS, Mint, elementary OS) ```bash sudo dpkg -i ProtonShift-*.deb ``` -Requires Python 3.12+ (included as a dependency in the .deb). +### .rpm (Fedora, openSUSE, RHEL) + +```bash +sudo dnf install ProtonShift-*.rpm +# or on openSUSE: +sudo zypper install ProtonShift-*.rpm +``` + +### Flatpak + +```bash +flatpak install ProtonShift-*.flatpak +flatpak run io.github.protonshift +``` + +Official builds bundle the Python API stack (FastAPI, Uvicorn, VDF, etc.) beside the app. You only need **Python 3.12+** available as `python3` (the `.deb` already depends on it). --- diff --git a/assets/io.github.protonshift.metainfo.xml b/assets/io.github.protonshift.metainfo.xml index 04c6698..8d31acb 100644 --- a/assets/io.github.protonshift.metainfo.xml +++ b/assets/io.github.protonshift.metainfo.xml @@ -26,6 +26,7 @@ io.github.protonshift.desktop https://github.com/I4cTime/protonshift + diff --git a/electron/main.ts b/electron/main.ts index 253a71f..3e6b12d 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -42,7 +42,13 @@ function getPythonCommand(): { cmd: string; args: string[]; env: NodeJS.ProcessE const resourcesPath = process.resourcesPath; const srcDir = path.join(resourcesPath, "python", "src"); - env.PYTHONPATH = srcDir + (env.PYTHONPATH ? `:${env.PYTHONPATH}` : ""); + const vendorDir = path.join(resourcesPath, "python", "vendor"); + const pyPathParts: string[] = []; + if (fs.existsSync(vendorDir)) { + pyPathParts.push(vendorDir); + } + pyPathParts.push(srcDir); + env.PYTHONPATH = pyPathParts.join(":") + (env.PYTHONPATH ? `:${env.PYTHONPATH}` : ""); return { cmd: "python3", args: ["-m", "game_setup_hub.api", "--port", "0"], @@ -69,9 +75,7 @@ function startPython(): Promise { }); pythonProcess.stderr?.on("data", (data: Buffer) => { - if (isDev) { - console.error("[python]", data.toString().trim()); - } + console.error("[python]", data.toString().trim()); }); pythonProcess.on("error", (err) => { diff --git a/electron/package.json b/electron/package.json index 3220897..8042260 100644 --- a/electron/package.json +++ b/electron/package.json @@ -1,6 +1,6 @@ { "name": "protonshift", - "version": "0.8.5", + "version": "0.8.6", "description": "Linux game configuration toolkit", "main": "dist/main.js", "scripts": { @@ -9,9 +9,12 @@ "build:renderer": "pnpm --filter protonshift-renderer build", "build:electron": "tsc", "build": "pnpm run build:renderer && pnpm run build:electron", - "dist": "pnpm run build && electron-builder --publish never", - "dist:appimage": "pnpm run build && electron-builder --linux AppImage --publish never", - "dist:deb": "pnpm run build && electron-builder --linux deb --publish never" + "vendor-python": "bash scripts/vendor-python-deps.sh", + "dist": "pnpm run vendor-python && pnpm run build && electron-builder --publish never", + "dist:appimage": "pnpm run vendor-python && pnpm run build && electron-builder --linux AppImage --publish never", + "dist:deb": "pnpm run vendor-python && pnpm run build && electron-builder --linux deb --publish never", + "dist:rpm": "pnpm run vendor-python && pnpm run build && electron-builder --linux rpm --publish never", + "dist:flatpak": "pnpm run vendor-python && pnpm run build && electron-builder --linux flatpak --publish never" }, "packageManager": "pnpm@10.32.1", "pnpm": { @@ -62,10 +65,15 @@ { "from": "../assets", "to": "assets" + }, + { + "from": "python-vendor", + "to": "python/vendor", + "filter": ["**/*"] } ], "linux": { - "target": ["AppImage", "deb"], + "target": ["AppImage", "deb", "rpm", "flatpak"], "category": "Game", "icon": "../assets", "desktop": { @@ -79,6 +87,33 @@ "deb": { "depends": ["python3 (>= 3.12)"], "maintainer": "I4cTime " + }, + "rpm": { + "depends": ["python3 >= 3.12"], + "fpm": ["--rpm-summary", "Linux game configuration toolkit"] + }, + "flatpak": { + "baseVersion": "24.08", + "runtime": "org.freedesktop.Platform", + "runtimeVersion": "24.08", + "sdk": "org.freedesktop.Sdk", + "finishArgs": [ + "--share=ipc", + "--share=network", + "--socket=x11", + "--socket=wayland", + "--socket=pulseaudio", + "--filesystem=home:ro", + "--filesystem=~/.steam:ro", + "--filesystem=~/.local/share/Steam:ro", + "--filesystem=~/.config/heroic:ro", + "--filesystem=~/.local/share/lutris:ro", + "--filesystem=~/.config/MangoHud", + "--filesystem=~/.config/environment.d", + "--filesystem=~/.config/protonshift", + "--device=dri", + "--talk-name=org.freedesktop.Flatpak" + ] } } } diff --git a/electron/python-runtime-requirements.txt b/electron/python-runtime-requirements.txt new file mode 100644 index 0000000..6e318a9 --- /dev/null +++ b/electron/python-runtime-requirements.txt @@ -0,0 +1,4 @@ +# Bundled into the AppImage/deb for packaged runs (see scripts/vendor-python-deps.sh). +fastapi>=0.115,<1 +uvicorn[standard]>=0.34,<1 +vdf>=1.2 diff --git a/electron/renderer/package.json b/electron/renderer/package.json index 564b5da..3eb1011 100644 --- a/electron/renderer/package.json +++ b/electron/renderer/package.json @@ -1,6 +1,6 @@ { "name": "protonshift-renderer", - "version": "0.8.5", + "version": "0.8.6", "private": true, "scripts": { "dev": "next dev --turbopack", diff --git a/electron/scripts/vendor-python-deps.sh b/electron/scripts/vendor-python-deps.sh new file mode 100755 index 0000000..90b5328 --- /dev/null +++ b/electron/scripts/vendor-python-deps.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +TARGET="${ROOT}/python-vendor" +REQ="${ROOT}/python-runtime-requirements.txt" +rm -rf "${TARGET}" +python3 -m pip install -r "${REQ}" -t "${TARGET}" --upgrade +echo "Vendored Python deps into ${TARGET}" diff --git a/pyproject.toml b/pyproject.toml index 76bc343..0131dff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "protonshift" -version = "0.8.5" +version = "0.8.6" description = "Linux game configuration toolkit: GPU, launch options, Proton, env vars" readme = "README.md" requires-python = ">=3.12" diff --git a/src/game_setup_hub/__init__.py b/src/game_setup_hub/__init__.py index 520cc5f..e972e93 100644 --- a/src/game_setup_hub/__init__.py +++ b/src/game_setup_hub/__init__.py @@ -1,3 +1,3 @@ """ProtonShift — game configuration for Pop!_OS, Ubuntu, and related distros.""" -__version__ = "0.8.5" +__version__ = "0.8.6" diff --git a/src/game_setup_hub/api.py b/src/game_setup_hub/api.py index dc53fc8..2979c17 100644 --- a/src/game_setup_hub/api.py +++ b/src/game_setup_hub/api.py @@ -324,7 +324,7 @@ class StatusResponse(BaseModel): # App setup # --------------------------------------------------------------------------- -app = FastAPI(title="ProtonShift API", version="0.8.5") +app = FastAPI(title="ProtonShift API", version="0.8.6") app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"]) # Locks for serializing writes to shared resources diff --git a/src/game_setup_hub/app.py b/src/game_setup_hub/app.py index 9331f14..4642910 100644 --- a/src/game_setup_hub/app.py +++ b/src/game_setup_hub/app.py @@ -1032,7 +1032,7 @@ def on_about(_action, _param): about = Adw.AboutWindow( transient_for=win, application_name="ProtonShift", - version="0.8.5", + version="0.8.6", developer_name="ProtonShift", website="https://github.com/protonshift/protonshift", application_icon="io.github.protonshift",