Replace _platform_zip_suffix() and its overrides with a _Platform
NamedTuple (tag/rid/dist_dir/icon/main_exe/setup_ext) plus
setup_artifact_name(). create_zip() is Windows-only in practice, so it
is now create_portable_zip() with a fixed -win64-portable.zip name
instead of a generic name patched by string replace.
- macOS: .pkg installer replaces the DMG; Linux: .AppImage replaces the ZIP
- winmain runs velopack.App() first (proper hook handling) and checks for
updates in the background; downloads are applied on next launch
- release.py uploads the vpk update feed (releases.<channel>.json, nupkgs)
so GiteaSource finds updates on the latest release
- guibuild.py bootstraps a .NET runtime into build/dotnet when the runner
host lacks one
vpk runs on the machine's modern .NET runtime (WiX 3.11's .NET Framework
shim fails under the SYSTEM account) and produces a per-user Setup.exe
that needs no runtime on end-user machines.
Files extracted from a downloaded ZIP carry a Zone.Identifier stream and the
.NET Framework CLR refuses to load such assemblies, so pythonnet failed with
'Failed to resolve Python.Runtime.Loader.Initialize'. MSI-installed files have
no MOTW; the winmain strip fixes the ZIP distribution.
pywebview[qt] no longer depends on PyQtWebEngine, so fresh CI builds
produced a macOS app without its Chromium engine that crashed on launch.
Package MediaHive.app as a compressed DMG instead of zipping the raw
onedir folder; release.py accepts .dmg artifacts.
Build the GUI app on macos/windows/linux host runners on v* tag pushes.
All platform jobs converge on one Gitea release; release.py now reuses an
existing release, skips duplicate assets, and supports --no-dist so only
the linux job uploads the wheel/sdist.