Harden updater and add icon-based installer release pipeline
Some checks are pending
Build and Release / build (push) Waiting to run
Some checks are pending
Build and Release / build (push) Waiting to run
This commit is contained in:
parent
73ea2b9550
commit
680a5887d0
16
.github/workflows/release.yml
vendored
16
.github/workflows/release.yml
vendored
@ -25,18 +25,24 @@ jobs:
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
pip install pyinstaller
|
||||
pip install pyinstaller pillow
|
||||
|
||||
- name: Prepare release metadata
|
||||
shell: pwsh
|
||||
run: |
|
||||
$version = "${{ github.ref_name }}".TrimStart('v')
|
||||
python scripts/set_version.py $version
|
||||
python scripts/prepare_icon.py
|
||||
|
||||
- name: Build exe
|
||||
run: |
|
||||
pyinstaller --noconfirm --onefile --windowed --name "Real-Debrid-Downloader" real_debrid_downloader_gui.py
|
||||
pyinstaller --noconfirm --windowed --onedir --name "Real-Debrid-Downloader" --icon "assets/app_icon.ico" real_debrid_downloader_gui.py
|
||||
|
||||
- name: Pack release zip
|
||||
shell: pwsh
|
||||
run: |
|
||||
New-Item -ItemType Directory -Path release -Force | Out-Null
|
||||
Copy-Item "dist/Real-Debrid-Downloader.exe" "release/Real-Debrid-Downloader.exe"
|
||||
Compress-Archive -Path "release/*" -DestinationPath "Real-Debrid-Downloader-win64.zip" -Force
|
||||
Compress-Archive -Path "dist/Real-Debrid-Downloader/*" -DestinationPath "Real-Debrid-Downloader-win64.zip" -Force
|
||||
|
||||
- name: Install Inno Setup
|
||||
shell: pwsh
|
||||
@ -47,7 +53,7 @@ jobs:
|
||||
shell: pwsh
|
||||
run: |
|
||||
$version = "${{ github.ref_name }}".TrimStart('v')
|
||||
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" "/DMyAppVersion=$version" "/DMySourceExe=..\\dist\\Real-Debrid-Downloader.exe" "/DMyOutputDir=..\\release" "installer\\RealDebridDownloader.iss"
|
||||
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" "/DMyAppVersion=$version" "/DMySourceDir=..\\dist\\Real-Debrid-Downloader" "/DMyOutputDir=..\\release" "/DMyIconFile=..\\assets\\app_icon.ico" "installer\\RealDebridDownloader.iss"
|
||||
|
||||
- name: Publish GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,6 +8,7 @@ venv/
|
||||
|
||||
build/
|
||||
dist/
|
||||
release/
|
||||
*.spec
|
||||
|
||||
rd_downloader_config.json
|
||||
|
||||
@ -76,12 +76,18 @@ Danach liegt die EXE in `dist/`.
|
||||
- Bei Tag-Push wie `v1.0.1` wird automatisch eine Windows-EXE gebaut
|
||||
- Release-Asset fuer Auto-Update: `Real-Debrid-Downloader-win64.zip`
|
||||
- Zusaetzlich wird ein Installer gebaut: `Real-Debrid-Downloader-Setup-<version>.exe`
|
||||
- Installer legt automatisch eine Desktop-Verknuepfung an
|
||||
|
||||
## Auto-Installer
|
||||
|
||||
- Im GitHub Release findest du direkt die Setup-Datei (`...Setup-<version>.exe`)
|
||||
- Setup installiert die App unter `Programme/Real-Debrid Downloader`
|
||||
- Optional erstellt Setup eine Desktop-Verknuepfung
|
||||
- Setup erstellt automatisch eine Desktop-Verknuepfung mit App-Icon
|
||||
|
||||
## App-Icon
|
||||
|
||||
- Das Projekt nutzt `assets/app_icon.png` (aus deinem `Downloads/abc.png`)
|
||||
- Beim Build wird automatisch `assets/app_icon.ico` erzeugt
|
||||
|
||||
Beispiel:
|
||||
|
||||
|
||||
BIN
assets/app_icon.ico
Normal file
BIN
assets/app_icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 141 KiB |
BIN
assets/app_icon.png
Normal file
BIN
assets/app_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 358 KiB |
@ -1,6 +1,16 @@
|
||||
param(
|
||||
[string]$Version = ""
|
||||
)
|
||||
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
pip install pyinstaller
|
||||
pyinstaller --noconfirm --onefile --windowed --name "Real-Debrid-Downloader" real_debrid_downloader_gui.py
|
||||
pip install pyinstaller pillow
|
||||
|
||||
Write-Host "Build fertig: dist/Real-Debrid-Downloader.exe"
|
||||
if ($Version -ne "") {
|
||||
python scripts/set_version.py $Version
|
||||
}
|
||||
|
||||
python scripts/prepare_icon.py
|
||||
pyinstaller --noconfirm --windowed --onedir --name "Real-Debrid-Downloader" --icon "assets/app_icon.ico" real_debrid_downloader_gui.py
|
||||
|
||||
Write-Host "Build fertig: dist/Real-Debrid-Downloader/Real-Debrid-Downloader.exe"
|
||||
|
||||
@ -5,14 +5,18 @@
|
||||
#define MyAppVersion "1.0.0"
|
||||
#endif
|
||||
|
||||
#ifndef MySourceExe
|
||||
#define MySourceExe "dist\\Real-Debrid-Downloader.exe"
|
||||
#ifndef MySourceDir
|
||||
#define MySourceDir "..\\dist\\Real-Debrid-Downloader"
|
||||
#endif
|
||||
|
||||
#ifndef MyOutputDir
|
||||
#define MyOutputDir "release"
|
||||
#endif
|
||||
|
||||
#ifndef MyIconFile
|
||||
#define MyIconFile "..\\assets\\app_icon.ico"
|
||||
#endif
|
||||
|
||||
[Setup]
|
||||
AppId={{C0E95B39-389E-4D2C-8E1E-12A44E8AE8E0}
|
||||
AppName={#MyAppName}
|
||||
@ -25,23 +29,22 @@ OutputBaseFilename=Real-Debrid-Downloader-Setup-{#MyAppVersion}
|
||||
Compression=lzma
|
||||
SolidCompression=yes
|
||||
WizardStyle=modern
|
||||
PrivilegesRequired=lowest
|
||||
PrivilegesRequired=admin
|
||||
ArchitecturesInstallIn64BitMode=x64compatible
|
||||
UninstallDisplayIcon={app}\{#MyAppExeName}
|
||||
SetupIconFile={#MyIconFile}
|
||||
|
||||
[Languages]
|
||||
Name: "german"; MessagesFile: "compiler:Languages\German.isl"
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
|
||||
[Tasks]
|
||||
Name: "desktopicon"; Description: "Desktop-Verknuepfung erstellen"; GroupDescription: "Zusaetzliche Aufgaben:"; Flags: unchecked
|
||||
|
||||
[Files]
|
||||
Source: "{#MySourceExe}"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "{#MySourceDir}\\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
Source: "{#MyIconFile}"; DestDir: "{app}"; DestName: "app_icon.ico"; Flags: ignoreversion
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
||||
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
|
||||
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\app_icon.ico"
|
||||
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\app_icon.ico"
|
||||
|
||||
[Run]
|
||||
Filename: "{app}\{#MyAppExeName}"; Description: "{#MyAppName} starten"; Flags: nowait postinstall skipifsilent
|
||||
|
||||
@ -29,7 +29,7 @@ API_BASE_URL = "https://api.real-debrid.com/rest/1.0"
|
||||
CONFIG_FILE = Path(__file__).with_name("rd_downloader_config.json")
|
||||
CHUNK_SIZE = 1024 * 512
|
||||
APP_NAME = "Real-Debrid Downloader GUI"
|
||||
APP_VERSION = "1.0.0"
|
||||
APP_VERSION = "1.0.5"
|
||||
DEFAULT_UPDATE_REPO = "Sucukdeluxe/real-debrid-downloader"
|
||||
DEFAULT_RELEASE_ASSET = "Real-Debrid-Downloader-win64.zip"
|
||||
REQUEST_RETRIES = 3
|
||||
@ -223,19 +223,12 @@ def fetch_latest_release(session: requests.Session, repo: str, preferred_asset:
|
||||
|
||||
chosen = None
|
||||
for asset in assets:
|
||||
if asset.get("name") == preferred_asset:
|
||||
if str(asset.get("name", "")).strip() == preferred_asset:
|
||||
chosen = asset
|
||||
break
|
||||
|
||||
if chosen is None:
|
||||
for asset in assets:
|
||||
name = str(asset.get("name", "")).lower()
|
||||
if name.endswith(".zip"):
|
||||
chosen = asset
|
||||
break
|
||||
|
||||
if chosen is None:
|
||||
chosen = assets[0]
|
||||
raise RuntimeError(f"Release-Asset '{preferred_asset}' nicht gefunden")
|
||||
|
||||
return ReleaseInfo(
|
||||
version=normalize_version(str(payload.get("tag_name", "0.0.0"))),
|
||||
|
||||
29
scripts/prepare_icon.py
Normal file
29
scripts/prepare_icon.py
Normal file
@ -0,0 +1,29 @@
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def main() -> int:
|
||||
project_root = Path(__file__).resolve().parents[1]
|
||||
png_path = project_root / "assets" / "app_icon.png"
|
||||
ico_path = project_root / "assets" / "app_icon.ico"
|
||||
|
||||
if not png_path.exists():
|
||||
print(f"Icon PNG not found: {png_path}")
|
||||
return 1
|
||||
|
||||
try:
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
print("Pillow missing. Install with: pip install pillow")
|
||||
return 1
|
||||
|
||||
with Image.open(png_path) as image:
|
||||
image = image.convert("RGBA")
|
||||
sizes = [(16, 16), (24, 24), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)]
|
||||
image.save(ico_path, format="ICO", sizes=sizes)
|
||||
|
||||
print(f"Wrote icon: {ico_path}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
35
scripts/set_version.py
Normal file
35
scripts/set_version.py
Normal file
@ -0,0 +1,35 @@
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python scripts/set_version.py <version>")
|
||||
return 1
|
||||
|
||||
version = sys.argv[1].strip().lstrip("v")
|
||||
if not re.fullmatch(r"\d+(?:\.\d+){1,3}", version):
|
||||
print(f"Invalid version: {version}")
|
||||
return 1
|
||||
|
||||
target = Path(__file__).resolve().parents[1] / "real_debrid_downloader_gui.py"
|
||||
content = target.read_text(encoding="utf-8")
|
||||
updated, count = re.subn(
|
||||
r'^APP_VERSION\s*=\s*"[^"]+"\s*$',
|
||||
f'APP_VERSION = "{version}"',
|
||||
content,
|
||||
count=1,
|
||||
flags=re.MULTILINE,
|
||||
)
|
||||
if count != 1:
|
||||
print("APP_VERSION marker not found")
|
||||
return 1
|
||||
|
||||
target.write_text(updated, encoding="utf-8")
|
||||
print(f"Set APP_VERSION to {version}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Loading…
Reference in New Issue
Block a user