diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..484abb1 --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,95 @@ +name: Release + +# Baut Playtube (Qt-Version) fuer Windows und veroeffentlicht Setup, ZIP und Patch als Release +# auf dem eigenen Gitea-Server, sobald ein Tag im Format "vX.Y.Z" gepusht wird +# (z.B. durch packaging/release.ps1). Playtube.exe auf den Nutzer-Rechnern erkennt neue +# Releases danach automatisch (siehe playtube/updater.py) und bietet die Installation an. +# +# Voraussetzungen (einmalig, siehe README "Releases bauen"): +# - Ein Gitea-Actions-Runner (act_runner) unter Windows mit dem Label "windows" (Host-Modus), +# auf dem Python 3.12, git, Inno Setup 6 und PowerShell installiert sind. +# - Im Repo unter Einstellungen > Actions > Secrets ein Secret "RELEASE_TOKEN" (Zugriffstoken +# mit Schreibrecht auf das Repo); ersatzweise wird der automatische Token benutzt. +# Bewusst KEINE "uses:"-Aktionen: die wuerden standardmaessig von github.com geladen. + +on: + push: + tags: + - "v*.*.*" + +jobs: + release: + runs-on: windows + steps: + - name: Quellcode holen + shell: pwsh + run: | + git clone "${{ gitea.server_url }}/${{ gitea.repository }}.git" src + git -C src checkout "${{ gitea.ref_name }}" + + - name: Abhaengigkeiten installieren + shell: pwsh + working-directory: src + run: | + python -m venv .venv + .\.venv\Scripts\python.exe -m pip install --upgrade pip + .\.venv\Scripts\python.exe -m pip install -r requirements.txt pyinstaller + + - name: Playtube.exe bauen + shell: pwsh + working-directory: src + run: .\.venv\Scripts\python.exe -m PyInstaller packaging\playtube.spec --noconfirm --distpath dist --workpath build + + - name: Setup-Installer bauen (Inno Setup) + # Der Installer ist der empfohlene Download fuer Neueinsteiger UND das, was Playtube + # fuer volle Updates benutzt (siehe playtube/updater.py): eine einzige Installation, + # die jedes Update an Ort und Stelle ueberschreibt (feste AppId in packaging/playtube.iss). + shell: pwsh + working-directory: src + run: | + $version = (Select-String -Path playtube\__init__.py -Pattern '__version__\s*=\s*"([^"]+)"').Matches[0].Groups[1].Value + $candidates = @( + (Get-Command iscc -ErrorAction SilentlyContinue | ForEach-Object { $_.Source }), + (Join-Path $env:LOCALAPPDATA "Programs\Inno Setup 6\ISCC.exe"), + (Join-Path ${env:ProgramFiles(x86)} "Inno Setup 6\ISCC.exe"), + (Join-Path $env:ProgramFiles "Inno Setup 6\ISCC.exe") + ) + $iscc = $candidates | Where-Object { $_ -and (Test-Path $_) } | Select-Object -First 1 + if (-not $iscc) { throw "Inno Setup 6 ist auf dem Runner nicht installiert." } + & $iscc "/DAppVersion=$version" packaging\playtube.iss + if ($LASTEXITCODE -ne 0) { throw "Inno-Setup-Build fehlgeschlagen." } + + - name: ZIP und Patch packen + # .play statt .zip: eigene Dateiendung, die Playtube nach dem ersten Start als + # Windows-Dateizuordnung registriert (siehe shortcuts.py). Technisch ein normales ZIP. + # Die PySide6-Version steht im Dateinamen: hat sich die Laufzeit gegenueber der + # installierten App geaendert, nimmt der Updater stattdessen den Setup-Installer. + shell: pwsh + working-directory: src + run: | + $tag = "${{ gitea.ref_name }}" + Compress-Archive -Path dist\Playtube -DestinationPath "Playtube-$tag-win64.zip" + $pyside = .\.venv\Scripts\python.exe -c "import PySide6; print(PySide6.__version__)" + $name = "Playtube-$tag-win64-pyside$pyside-patch" + Compress-Archive -Path dist\Playtube\Playtube.exe -DestinationPath "$name.zip" + Rename-Item -Path "$name.zip" -NewName "$name.play" + + - name: Release-Notizen aus den Commits + shell: pwsh + working-directory: src + run: | + $previous = git describe --tags --abbrev=0 "HEAD^" 2>$null + $range = if ($previous) { "$previous..HEAD" } else { "HEAD" } + $lines = git log $range --pretty="- %s" -n 30 + Set-Content -Path release_notes.md -Encoding UTF8 -Value (@("## Aenderungen", "") + $lines) + + - name: Release auf Gitea veroeffentlichen + shell: pwsh + working-directory: src + env: + GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }} + run: | + $tag = "${{ gitea.ref_name }}" + $files = @((Get-ChildItem dist\installer\Playtube-Setup-v*.exe).FullName) + @((Get-ChildItem "Playtube-*.zip", "Playtube-*.play").FullName) + .\packaging\publish_release.ps1 -Tag $tag -Title $tag -NotesFile release_notes.md -Files $files ` + -Server "${{ gitea.server_url }}" -Repo "${{ gitea.repository }}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 3bb34bf..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,141 +0,0 @@ -name: Release - -# Baut Playtube fuer Windows und Linux und veroeffentlicht beide als Assets an einem -# GitHub Release, sobald ein Tag im Format "vX.Y.Z" gepusht wird (z.B. durch -# packaging/release.ps1). Playtube.exe/Playtube auf den Nutzer-Rechnern erkennt neue -# Releases danach automatisch (siehe playtube/updater.py) und bietet die Installation an. - -on: - push: - tags: - - "v*.*.*" - workflow_dispatch: {} - -permissions: - contents: write - -jobs: - build-windows: - runs-on: windows-latest - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Abhaengigkeiten installieren - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install pyinstaller - - - name: Playtube.exe bauen - run: pyinstaller packaging\playtube.spec --noconfirm --distpath dist --workpath build - - - name: Setup-Installer bauen (Inno Setup) - # Der Installer ist der empfohlene Download fuer Neueinsteiger UND das, was - # Playtube fuer volle Updates benutzt (siehe playtube/updater.py): eine einzige - # Installation, die jedes Update an Ort und Stelle ueberschreibt (feste AppId in - # packaging/playtube.iss) - keine parallelen Versionsordner mehr. - shell: pwsh - run: | - $version = (Select-String -Path playtube\__init__.py -Pattern '__version__\s*=\s*"([^"]+)"').Matches[0].Groups[1].Value - $iscc = Join-Path ${env:ProgramFiles(x86)} "Inno Setup 6\ISCC.exe" - if (-not (Test-Path $iscc)) { - choco install innosetup -y --no-progress - } - & $iscc "/DAppVersion=$version" packaging\playtube.iss - if ($LASTEXITCODE -ne 0) { throw "Inno-Setup-Build fehlgeschlagen." } - - - uses: actions/upload-artifact@v4 - with: - name: windows-setup - path: dist/installer/Playtube-Setup-v*.exe - - - name: Als .zip packen (volles Paket, portabel) - run: Compress-Archive -Path dist\Playtube -DestinationPath Playtube-${{ github.ref_name }}-win64.zip - - - uses: actions/upload-artifact@v4 - with: - name: windows-build - path: Playtube-${{ github.ref_name }}-win64.zip - - - name: Patch-Paket packen (nur Playtube.exe, fuer schnelle Updates) - # .play statt .zip: eigene Dateiendung, die Playtube nach dem ersten Start als - # Windows-Dateizuordnung registriert (siehe shortcuts.py) - ein manuell - # heruntergeladenes Patch laesst sich so auch per Doppelklick installieren. - # Technisch bleibt es ein ganz normales ZIP-Archiv. - # Die PySide6-Version steht im Dateinamen: hat sich die Laufzeit gegenueber der - # installierten App geaendert, ist ein reines .exe-Patch nicht mehr kompatibel und - # der Updater nimmt stattdessen den Setup-Installer (siehe _patch_is_compatible). - shell: pwsh - run: | - $pyside = python -c "import PySide6; print(PySide6.__version__)" - $name = "Playtube-${{ github.ref_name }}-win64-pyside${pyside}-patch" - Compress-Archive -Path dist\Playtube\Playtube.exe -DestinationPath "$name.zip" - Rename-Item -Path "$name.zip" -NewName "$name.play" - - - uses: actions/upload-artifact@v4 - with: - name: windows-patch - path: Playtube-*-win64-pyside*-patch.play - - build-linux: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Qt-WebEngine-Laufzeitabhaengigkeiten installieren - run: | - sudo apt-get update - sudo apt-get install -y \ - libxkbcommon0 libegl1 libopengl0 libnss3 libnspr4 \ - libxcomposite1 libxdamage1 libxrandr2 libxtst6 libxcursor1 \ - libgbm1 libasound2t64 libatk-bridge2.0-0 libatk1.0-0 libcups2 \ - libdbus-1-3 libdrm2 libpango-1.0-0 libpangocairo-1.0-0 \ - libxfixes3 libxi6 libxext6 fonts-liberation - - - name: Abhaengigkeiten installieren - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install pyinstaller - - - name: Playtube-Binary bauen - run: pyinstaller packaging/playtube.spec --noconfirm --distpath dist --workpath build - - - name: Als .tar.gz packen (volles Paket) - run: tar -C dist -czf Playtube-${{ github.ref_name }}-linux-x86_64.tar.gz Playtube - - - uses: actions/upload-artifact@v4 - with: - name: linux-build - path: Playtube-${{ github.ref_name }}-linux-x86_64.tar.gz - - - name: Patch-Paket packen (nur Playtube-Binary, fuer schnelle Updates) - run: tar -C dist/Playtube -czf Playtube-${{ github.ref_name }}-linux-x86_64-patch.tar.gz Playtube - - - uses: actions/upload-artifact@v4 - with: - name: linux-patch - path: Playtube-${{ github.ref_name }}-linux-x86_64-patch.tar.gz - - publish-release: - needs: [build-windows, build-linux] - runs-on: ubuntu-latest - steps: - - uses: actions/download-artifact@v4 - with: - path: artifacts - merge-multiple: true - - - name: GitHub Release veroeffentlichen - uses: softprops/action-gh-release@v2 - with: - files: artifacts/* - generate_release_notes: true diff --git a/README.md b/README.md index 3aa74f5..6bd7e85 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Erweiterung) mit: ## Installation (Windows) -Lade auf der [Releases-Seite](https://github.com/fojadrachi/Playtube/releases) +Lade auf der [Releases-Seite](https://git.fojadrachi.de/Fojadrachi/Playtube/releases) `Playtube-Setup-vX.Y.Z.exe` herunter und starte sie. Der Installer - installiert Playtube **pro Benutzer** nach `%LOCALAPPDATA%\Programs\Playtube` (keine @@ -152,7 +152,7 @@ o.ä. umgehen). Playtube prüft beim Start und danach alle `updates.check_interval_hours` Stunden (Standard 6, im **Einstellungen-Tab** oder in `config.json` einstellbar) die -[GitHub Releases](https://github.com/fojadrachi/Playtube/releases) des Projekts. Im +[Releases](https://git.fojadrachi.de/Fojadrachi/Playtube/releases) auf dem eigenen Gitea-Server. Im Einstellungen-Tab gibt es zusätzlich einen "Jetzt nach Updates suchen"-Button mit Status-Anzeige und Fortschrittsbalken für den Download. Gibt es eine neuere Version, fragt ein Dialog, ob sie installiert werden soll: @@ -193,7 +193,7 @@ Windows-Patch-Pakete tragen die eigene Dateiendung `.play` statt `.zip` (technis weiterhin ein ganz normales ZIP-Archiv). Playtube registriert `.play` beim ersten Start automatisch als Windows-Dateizuordnung - eine manuell heruntergeladene `Playtube-vX.Y.Z-win64-patch.play` (z.B. von der -[Releases-Seite](https://github.com/fojadrachi/Playtube/releases)) lässt sich also +[Releases-Seite](https://git.fojadrachi.de/Fojadrachi/Playtube/releases)) lässt sich also einfach per Doppelklick installieren, ohne dass Playtube selbst etwas herunterladen muss. @@ -204,12 +204,32 @@ powershell -ExecutionPolicy Bypass -File packaging\release.ps1 -Version 1.1.0 ``` Das Skript setzt die Versionsnummer, committet, erstellt Git-Tag `v1.1.0` und pusht zu -`origin` (dein Repo unter https://github.com/fojadrachi/Playtube). Der gepushte Tag -löst automatisch die GitHub-Actions-Pipeline -([.github/workflows/release.yml](.github/workflows/release.yml)) aus, die **sowohl -eine Windows- als auch eine Linux-Version baut** und beide als Assets an einem GitHub -Release veröffentlicht - Fortschritt unter -https://github.com/fojadrachi/Playtube/actions. +`origin` (dein Gitea unter https://git.fojadrachi.de/Fojadrachi/Playtube). Der gepushte +Tag löst automatisch die Gitea-Actions-Pipeline +([.gitea/workflows/release.yml](.gitea/workflows/release.yml)) aus, die die +Windows-Pakete baut und als Release auf dem Gitea veröffentlicht - Fortschritt unter +https://git.fojadrachi.de/Fojadrachi/Playtube/actions. + +#### Releases bauen (einmalige Einrichtung) + +GitHub wird nirgends mehr benutzt. Die Pipeline braucht: + +1. **Einen Gitea-Actions-Runner unter Windows** (`act_runner`, Label `windows`, Host-Modus) + mit Python 3.12, git, PowerShell und [Inno Setup 6](https://jrsoftware.org/isinfo.php). + Registrierung z. B.: + `act_runner register --instance https://git.fojadrachi.de --token --labels windows:host` +2. **Ein Secret `RELEASE_TOKEN`** im Repo (Einstellungen → Actions → Secrets): ein + Zugriffstoken (Gitea → Einstellungen → Anwendungen) mit Schreibrecht auf das Repo. +3. In Gitea **Actions für das Repo aktivieren** (Einstellungen → Erweitert → Repository-Einheiten). + +**Ohne Runner** kannst du selbst bauen und veröffentlichen: + +```powershell +powershell -ExecutionPolicy Bypass -File packaging\build.ps1 +$env:GITEA_TOKEN = "" +powershell -ExecutionPolicy Bypass -File packaging\publish_release.ps1 -Tag v1.1.0 ` + -Files dist\installer\Playtube-Setup-v1.1.0.exe +``` Für Windows entstehen dabei drei Dateien: `Playtube-Setup-vX.Y.Z.exe` (Installer, für Neueinsteiger und volle Updates), `Playtube-vX.Y.Z-win64.zip` (portabel) und das kleine @@ -221,9 +241,10 @@ neue Version danach automatisch angeboten. ## Native Linux-Version -Playtube läuft genauso unter Linux (gleicher Code, gleiches PySide6/QtWebEngine) und -wird bei jedem Release automatisch als `Playtube-vX.Y.Z-linux-x86_64.tar.gz` unter -https://github.com/fojadrachi/Playtube/releases mitgebaut. +Playtube läuft genauso unter Linux (gleicher Code, gleiches PySide6/QtWebEngine). Die +Pipeline auf dem Gitea baut derzeit nur Windows-Pakete; Linux-Pakete (`.tar.gz`) entstehen +nur, wenn du zusätzlich einen Linux-Runner einrichtest oder sie selbst mit PyInstaller baust +(`pyinstaller packaging/playtube.spec`). **Fertiges Release installieren** (richtet Startmenü-Eintrag + Icon ein): @@ -244,8 +265,7 @@ python3 -m venv .venv ``` QtWebEngine benötigt unter Linux ein paar System-Bibliotheken (auf Debian/Ubuntu): -`sudo apt install libxkbcommon0 libegl1 libnss3 libxcomposite1 libxdamage1 libxrandr2 libgbm1 libasound2t64 libatk-bridge2.0-0 libcups2` (siehe auch die vollstaendige Liste in -[.github/workflows/release.yml](.github/workflows/release.yml)). +`sudo apt install libxkbcommon0 libegl1 libnss3 libxcomposite1 libxdamage1 libxrandr2 libgbm1 libasound2t64 libatk-bridge2.0-0 libcups2 libxtst6 libxcursor1 libatk1.0-0 libdbus-1-3 libdrm2 libpango-1.0-0 libpangocairo-1.0-0 libxfixes3 libxi6 libxext6 fonts-liberation`. ## Hinweise diff --git a/packaging/playtube.iss b/packaging/playtube.iss index efbde28..ed5917b 100644 --- a/packaging/playtube.iss +++ b/packaging/playtube.iss @@ -33,9 +33,9 @@ AppName={#AppName} AppVersion={#AppVersion} AppVerName={#AppName} {#AppVersion} AppPublisher=Playtube -AppPublisherURL=https://github.com/fojadrachi/Playtube -AppSupportURL=https://github.com/fojadrachi/Playtube/issues -AppUpdatesURL=https://github.com/fojadrachi/Playtube/releases +AppPublisherURL=https://git.fojadrachi.de/Fojadrachi/Playtube +AppSupportURL=https://git.fojadrachi.de/Fojadrachi/Playtube/issues +AppUpdatesURL=https://git.fojadrachi.de/Fojadrachi/Playtube/releases VersionInfoVersion={#AppVersion} DefaultDirName={localappdata}\Programs\{#AppName} DisableProgramGroupPage=yes diff --git a/packaging/publish_release.ps1 b/packaging/publish_release.ps1 new file mode 100644 index 0000000..903a22d --- /dev/null +++ b/packaging/publish_release.ps1 @@ -0,0 +1,67 @@ +# Veroeffentlicht ein Release auf dem eigenen Gitea-Server (Installer, ZIP, Patch als Anhaenge). +# Wird von der Pipeline (.gitea/workflows/release.yml) benutzt und laesst sich auch von Hand +# aufrufen, z.B. nach einem lokalen Build (packaging\build.ps1): +# +# $env:GITEA_TOKEN = "" +# powershell -ExecutionPolicy Bypass -File packaging\publish_release.ps1 ` +# -Tag v4.6.0 -Files dist\installer\Playtube-Setup-v4.6.0.exe,Playtube-v4.6.0-win64.zip +# +# Der Token wird in Gitea unter Einstellungen > Anwendungen erzeugt (Recht "repository: Lesen und +# Schreiben"). Er steht NIE im Skript, sondern nur in der Umgebungsvariable GITEA_TOKEN. +# Gab es zum selben Tag schon ein Release, wird es vorher entfernt (der Git-Tag bleibt). + +param( + [Parameter(Mandatory = $true)] [string]$Tag, + [Parameter(Mandatory = $true)] [string[]]$Files, + [string]$Title = "", + [string]$NotesFile = "", + [switch]$Prerelease, + [string]$Server = "https://git.fojadrachi.de", + [string]$Repo = "Fojadrachi/Playtube" +) + +$ErrorActionPreference = "Stop" + +$token = $env:GITEA_TOKEN +if (-not $token) { + throw "GITEA_TOKEN ist nicht gesetzt (Zugriffstoken aus Gitea > Einstellungen > Anwendungen)." +} +if (-not $Title) { $Title = $Tag } +foreach ($file in $Files) { + if (-not (Test-Path $file)) { throw "Datei nicht gefunden: $file" } +} + +$api = "$Server/api/v1/repos/$Repo" +$headers = @{ Authorization = "token $token" } + +# Vorhandenes Release zum selben Tag entfernen (404 = gab keins). +try { + $old = Invoke-RestMethod -Headers $headers -Uri "$api/releases/tags/$Tag" + Invoke-RestMethod -Method Delete -Headers $headers -Uri "$api/releases/$($old.id)" | Out-Null + Write-Host "Vorhandenes Release zu $Tag ersetzt." +} catch { + if ($_.Exception.Response -and [int]$_.Exception.Response.StatusCode -ne 404) { throw } +} + +$notes = "" +if ($NotesFile -and (Test-Path $NotesFile)) { $notes = Get-Content -Raw -Encoding UTF8 $NotesFile } + +$payload = @{ + tag_name = $Tag + name = $Title + body = $notes + draft = $false + prerelease = [bool]$Prerelease +} | ConvertTo-Json +$release = Invoke-RestMethod -Method Post -Headers $headers -Uri "$api/releases" ` + -ContentType "application/json; charset=utf-8" -Body ([Text.Encoding]::UTF8.GetBytes($payload)) + +foreach ($file in $Files) { + $name = Split-Path $file -Leaf + Write-Host "Lade hoch: $name" + & curl.exe -sS --fail -X POST -H "Authorization: token $token" -F "attachment=@$file" ` + "$api/releases/$($release.id)/assets?name=$([uri]::EscapeDataString($name))" | Out-Null + if ($LASTEXITCODE -ne 0) { throw "Upload fehlgeschlagen: $name" } +} + +Write-Host "Fertig: $Server/$Repo/releases/tag/$Tag" -ForegroundColor Green diff --git a/packaging/release.ps1 b/packaging/release.ps1 index 4cb936c..15b69ef 100644 --- a/packaging/release.ps1 +++ b/packaging/release.ps1 @@ -1,13 +1,14 @@ # Veroeffentlicht eine neue Playtube-Version: setzt die Versionsnummer, committet, -# taggt und pusht. Der eigentliche Build fuer Windows UND Linux sowie die -# Veroeffentlichung als GitHub Release passiert danach automatisch per GitHub Actions -# (.github/workflows/release.yml), ausgeloest durch den gepushten Tag. +# taggt und pusht. Der eigentliche Build und die Veroeffentlichung als Release auf dem +# eigenen Gitea-Server passiert danach automatisch per Gitea Actions +# (.gitea/workflows/release.yml), ausgeloest durch den gepushten Tag. # # Aufruf (im Projekt-Root): # powershell -ExecutionPolicy Bypass -File packaging\release.ps1 -Version 1.1.0 # -# Voraussetzung: git remote "origin" zeigt auf https://github.com/fojadrachi/Playtube -# und du bist dort push-berechtigt. +# Voraussetzung: git remote "origin" zeigt auf https://git.fojadrachi.de/Fojadrachi/Playtube +# und du bist dort push-berechtigt. Ohne Actions-Runner kannst du lokal bauen +# (packaging\build.ps1) und mit packaging\publish_release.ps1 selbst veroeffentlichen. param( [Parameter(Mandatory = $true)] @@ -37,6 +38,6 @@ git push origin HEAD git push origin $tag Write-Host "" -Write-Host "Fertig. GitHub Actions baut jetzt Windows- und Linux-Pakete und" -ForegroundColor Green -Write-Host "veroeffentlicht sie als Release $tag - Fortschritt unter:" -ForegroundColor Green -Write-Host "https://github.com/fojadrachi/Playtube/actions" -ForegroundColor Green +Write-Host "Fertig. Gitea Actions baut jetzt das Windows-Paket und" -ForegroundColor Green +Write-Host "veroeffentlicht es als Release $tag - Fortschritt unter:" -ForegroundColor Green +Write-Host "https://git.fojadrachi.de/Fojadrachi/Playtube/actions" -ForegroundColor Green diff --git a/playtube/mainwindow.py b/playtube/mainwindow.py index 7a31e51..1286671 100644 --- a/playtube/mainwindow.py +++ b/playtube/mainwindow.py @@ -392,7 +392,7 @@ class MainWindow(QMainWindow): def _on_update_check_failed(self) -> None: self._settings_tab.set_check_done() self._settings_tab.set_update_status( - "Update-Prüfung fehlgeschlagen (keine Internetverbindung oder GitHub nicht erreichbar)." + "Update-Prüfung fehlgeschlagen (keine Internetverbindung oder Update-Server nicht erreichbar)." ) def _on_update_available(self, version: str, notes: str, download_url: str) -> None: diff --git a/playtube/settings_tab.py b/playtube/settings_tab.py index 48a64a4..c120d7a 100644 --- a/playtube/settings_tab.py +++ b/playtube/settings_tab.py @@ -26,7 +26,7 @@ from PySide6.QtWidgets import ( from . import __version__ as APP_VERSION from .audio_routing import SYSTEM_DEFAULT_LABEL, list_output_devices from .config import APP_NAME, save_config -from .updater import GITHUB_REPO +from .updater import REPO_URL # Helle Schrift fuer Versionsnummer, Update-Status und GitHub-Link. palette(text) ist die # Standard-Textfarbe (im dunklen Design weiss, im hellen dunkel) - das fruehere @@ -180,7 +180,7 @@ class SettingsTab(QWidget): button_row.addStretch(1) outer.addLayout(button_row) - info = QLabel(f"github.com/{GITHUB_REPO}") + info = QLabel(REPO_URL.removeprefix("https://")) info.setStyleSheet(_LIGHT_TEXT_STYLE) outer.addWidget(info) diff --git a/playtube/updater.py b/playtube/updater.py index c8bc627..b884cc9 100644 --- a/playtube/updater.py +++ b/playtube/updater.py @@ -1,7 +1,7 @@ -"""Auto-Update ueber GitHub Releases (https://github.com/fojadrachi/Playtube). +"""Auto-Update ueber die Releases des eigenen Gitea-Servers (siehe UPDATE_SERVER). Ablauf: - 1. UpdateChecker prueft im Hintergrund die GitHub-Releases-API auf eine neuere + 1. UpdateChecker prueft im Hintergrund die Gitea-Releases-API auf eine neuere Version als die aktuell laufende (playtube.__version__). 2. Bei Fund fragt die UI (siehe mainwindow.py) nach Bestaetigung. 3. UpdateInstaller installiert das Update: @@ -53,9 +53,15 @@ from PySide6.QtCore import QThread, Signal from . import __version__ as CURRENT_VERSION -GITHUB_REPO = "fojadrachi/Playtube" -_API_URL = f"https://api.github.com/repos/{GITHUB_REPO}/releases/latest" +# Eigener Gitea-Server (kein GitHub). Die Releases dort (Setup, Patch, ZIP) werden von der +# Pipeline .gitea/workflows/release.yml bzw. packaging/publish_release.ps1 veroeffentlicht. +UPDATE_SERVER = "https://git.fojadrachi.de" +REPO_SLUG = "Fojadrachi/Playtube" +REPO_URL = f"{UPDATE_SERVER}/{REPO_SLUG}" +_API_URL = f"{UPDATE_SERVER}/api/v1/repos/{REPO_SLUG}/releases?limit=30" _USER_AGENT = "Playtube-Updater" +# Releases der Edge-Variante (Tag "...-edge") gehoeren nicht zur normalen Playtube. +_EDGE_TAG_SUFFIX = "-edge" _LINUX_BINARY_NAME = "Playtube" _WINDOWS_BINARY_NAME = "Playtube.exe" @@ -100,14 +106,21 @@ def cleanup_old_staging() -> None: def fetch_latest_release() -> dict[str, Any] | None: - req = urllib.request.Request( - _API_URL, headers={"User-Agent": _USER_AGENT, "Accept": "application/vnd.github+json"} - ) + req = urllib.request.Request(_API_URL, headers={"User-Agent": _USER_AGENT, "Accept": "application/json"}) try: with urllib.request.urlopen(req, timeout=10) as resp: - return json.loads(resp.read().decode("utf-8")) + releases = json.loads(resp.read().decode("utf-8")) except (urllib.error.URLError, TimeoutError, json.JSONDecodeError, OSError, ValueError): return None + if not isinstance(releases, list): + return None + # Neueste stabile Version: keine Entwuerfe/Vorabversionen und nie ein Edge-Release. + stable = [ + release for release in releases + if isinstance(release, dict) and not release.get("draft") and not release.get("prerelease") + and not str(release.get("tag_name", "")).endswith(_EDGE_TAG_SUFFIX) + ] + return max(stable, key=lambda r: _parse_version(str(r.get("tag_name", ""))), default=None) def is_installed_via_setup() -> bool: