Files
BrowserOS/packages/browseros/build/modules/ota/__init__.py
Nikhil c1b1e53a86 feat(ota): bundle full server resources tree in Sparkle payload (#726)
* feat(ota): bundle full server resources tree (server + third_party bins)

The OTA Sparkle payload now ships the complete resources/ tree the agent
build produced, not just browseros_server. Every third-party binary (bun,
ripgrep, podman, gvproxy, vfkit, krunkit, podman-mac-helper, win-sshproxy)
flows to OTA-updated installs so podman integration works for users on the
OTA channel, matching fresh Chromium-build installs.

Extract the per-binary sign table into build/common/server_binaries.py so
the Chromium-build sign path (modules/sign/) and OTA sign path (modules/ota/)
share a single source of truth. Adding a new third-party dep is now a
one-file edit that both paths pick up automatically; unknown executables
under resources/bin/ are a hard error at release time.

* fix(ota): address review comments on bundle signing flow

- Avoid double-zipping during notarization: add notarize_macos_zip for
  pre-built Sparkle bundles so notarytool submits the zip directly
  instead of re-wrapping it through ditto --keepParent (Apple's service
  does not descend into nested archives). Keep notarize_macos_binary for
  single-binary callers. Share credential setup + submit logic via
  internal helpers.
- Fail fast on unknown executables in sign_server_bundle_macos: collect
  the unknown-files list before any codesign call so a missing shared-
  table entry aborts in seconds, not after a full signing round.
- Drop dead get_entitlements_path helper (no callers remain after the
  bundle refactor).

* fix(ota): address PR review comments (greptile + claude)

- sign_server_bundle_macos filters to executables only (p.is_file() +
  not p.is_symlink() + os.access X_OK) before applying the unknown-file
  guard. Non-Mach-O files (configs, dylibs, etc.) under resources/bin/
  no longer cause misleading 'unknown executable' hard failures.
- sign_server_bundle_windows now hard-errors on a missing expected
  binary instead of silently skipping it. Symmetric with the macOS
  guard — an incomplete bundle must not publish.
- ServerOTAModule.execute() uses tempfile.TemporaryDirectory context
  managers for both the download and staging roots so they are cleaned
  up on every path, including failures.
- Per-platform sign/notarize/Sparkle-sign failures now raise RuntimeError
  instead of silently skipping the platform — a release pipeline can no
  longer omit a target while reporting success.
- Move import os and import shutil to the top of ota/sign_binary.py.
- Drop unused log_error import from ota/server.py.

* chore: bump server
2026-04-16 12:59:49 -07:00

48 lines
1.1 KiB
Python
Generated

#!/usr/bin/env python3
"""OTA (Over-The-Air) update modules for BrowserOS Server and Browser"""
from .common import (
sparkle_sign_file,
generate_server_appcast,
parse_existing_appcast,
ExistingAppcast,
SignedArtifact,
SERVER_PLATFORMS,
APPCAST_TEMPLATE,
find_server_resources_dir,
create_server_bundle_zip,
)
from .sign_binary import (
sign_macos_binary,
notarize_macos_binary,
notarize_macos_zip,
sign_windows_binary,
sign_server_bundle_macos,
sign_server_bundle_windows,
)
from .server import ServerOTAModule
AVAILABLE_MODULES = {
"server_ota": ServerOTAModule,
}
__all__ = [
"AVAILABLE_MODULES",
"ServerOTAModule",
"sparkle_sign_file",
"generate_server_appcast",
"parse_existing_appcast",
"ExistingAppcast",
"SignedArtifact",
"find_server_resources_dir",
"create_server_bundle_zip",
"sign_macos_binary",
"notarize_macos_binary",
"notarize_macos_zip",
"sign_windows_binary",
"sign_server_bundle_macos",
"sign_server_bundle_windows",
"SERVER_PLATFORMS",
"APPCAST_TEMPLATE",
]