Velopack packaging on all platforms with in-app auto-updates
release / gui-build (linux, bash) (push) Failing after 50s
release / gui-build (macos, bash) (push) Successful in 1m44s
release / gui-build (windows, cmd) (push) Successful in 1m48s

- 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
This commit is contained in:
2026-09-22 23:50:50 +00:00
parent e8d2c5773a
commit 303aabc181
7 changed files with 215 additions and 81 deletions
+28 -4
View File
@@ -67,10 +67,12 @@ def load_token() -> str:
# ZIP + dist helpers
# ---------------------------------------------------------------------------
# Matches MediaHive-1.2.3-win64.zip, MediaHive-1.2.3-win64-setup.exe,
# MediaHive-1.2.3-macos-arm64.dmg, etc.
# Rejects dev/dirty versions like MediaHive-1.2.3.dev0+gabcd-win64.zip
_CLEAN_ARTIFACT_RE = re.compile(r"^MediaHive-(\d+(?:\.\d+)*)-([A-Za-z0-9._-]+)\.(?:zip|dmg|exe)$")
# Matches MediaHive-1.2.3-win64-portable.zip, MediaHive-1.2.3-win64-setup.exe,
# MediaHive-1.2.3-macos-arm64-setup.pkg, MediaHive-1.2.3-linux-x64.AppImage, etc.
# Rejects dev/dirty versions like MediaHive-1.2.3.dev0+gabcd-win64-portable.zip
_CLEAN_ARTIFACT_RE = re.compile(
r"^MediaHive-(\d+(?:\.\d+)*)-([A-Za-z0-9._-]+)\.(?:zip|dmg|exe|pkg|AppImage)$"
)
def find_releasable_artifacts() -> list[tuple[Path, str, str]]:
@@ -113,6 +115,21 @@ def find_dist_files(version: str) -> list[Path]:
return [wheel, sdist]
def find_velopack_feed_files() -> list[Path]:
"""Velopack update feed files produced by vpk pack in build/velopack/.
These keep their original names — the feed JSONs reference them — and
in-app updates (GiteaSource) download them from the latest release.
"""
releases_dir = REPO_ROOT / "build" / "velopack"
if not releases_dir.exists():
return []
files: list[Path] = []
for pattern in ("RELEASES", "releases.*.json", "assets.*.json", "*.nupkg"):
files.extend(sorted(releases_dir.glob(pattern)))
return files
# ---------------------------------------------------------------------------
# Gitea API helpers
# ---------------------------------------------------------------------------
@@ -266,6 +283,13 @@ def main() -> None:
continue
print(f"Uploading platform artifact: {platform_tag}")
upload_asset(client, base_url, repo, release_id, artifact_path)
uploaded.add(artifact_path.name)
for feed_file in find_velopack_feed_files():
if feed_file.name in uploaded:
print(f"Skipping {feed_file.name}, already on the release.")
continue
upload_asset(client, base_url, repo, release_id, feed_file)
uploaded.add(feed_file.name)
print(f"{tag} published")
print("\nDone. To publish to PyPI, run:")