feat: per-platform Chromium versioning and build number support

- Add PLATFORM_CHROMIUM_VERSIONS map (Linux=v145, macOS=v142)
- Add get_chromium_version()/getChromiumVersion() for platform-specific version
- Make auto-update check release assets before offering updates
- Scope version markers per-platform (latest_version_linux-x64)
- Support 5th version segment for hotfix builds (e.g. 145.0.7632.109.2)
- Derive AVAILABLE_PLATFORMS from version map
This commit is contained in:
CloakHQ
2026-03-02 08:23:44 +01:00
parent 4c2e06682b
commit fc10bdf13e
9 changed files with 296 additions and 75 deletions
+29 -13
View File
@@ -10,10 +10,20 @@ from pathlib import Path
from ._version import __version__
# ---------------------------------------------------------------------------
# Chromium version shipped with this release
# Chromium version shipped with this release.
# Different platforms may ship different versions (e.g. Linux gets v145 first,
# macOS stays on v142 until Mac builds are ready).
# CHROMIUM_VERSION is the latest across all platforms (for display/reference).
# Use get_chromium_version() for the current platform's actual version.
# ---------------------------------------------------------------------------
CHROMIUM_VERSION = "145.0.7632.109"
PLATFORM_CHROMIUM_VERSIONS: dict[str, str] = {
"linux-x64": "145.0.7632.109",
"darwin-arm64": "142.0.7444.175",
"darwin-x64": "142.0.7444.175",
}
# ---------------------------------------------------------------------------
# Default stealth arguments passed to the patched Chromium binary.
# These activate source-level fingerprint patches compiled into the binary.
@@ -70,9 +80,14 @@ SUPPORTED_PLATFORMS: dict[tuple[str, str], str] = {
("Darwin", "x86_64"): "darwin-x64",
}
# Platforms with pre-built binaries available for download.
# Update this set as new platform builds are released.
AVAILABLE_PLATFORMS: set[str] = {"linux-x64", "darwin-arm64", "darwin-x64"}
# Platforms with pre-built binaries available for download (derived from version map).
AVAILABLE_PLATFORMS: set[str] = set(PLATFORM_CHROMIUM_VERSIONS.keys())
def get_chromium_version() -> str:
"""Return the Chromium version for the current platform."""
tag = get_platform_tag()
return PLATFORM_CHROMIUM_VERSIONS.get(tag, CHROMIUM_VERSION)
def get_platform_tag() -> str:
@@ -105,7 +120,7 @@ def get_cache_dir() -> Path:
def get_binary_dir(version: str | None = None) -> Path:
"""Return the directory for a Chromium version binary."""
v = version or CHROMIUM_VERSION
v = version or get_chromium_version()
return get_cache_dir() / f"chromium-{v}"
@@ -141,23 +156,24 @@ def check_platform_available() -> None:
def get_effective_version() -> str:
"""Return the best available version: auto-updated if available, else hardcoded.
"""Return the best available version: auto-updated if available, else platform default.
Reads the latest_version marker file from the cache directory.
Returns CHROMIUM_VERSION if no update has been downloaded.
Reads a platform-scoped marker file from the cache directory.
Returns the platform's hardcoded version if no update has been downloaded.
"""
marker = get_cache_dir() / "latest_version"
base = get_chromium_version()
marker = get_cache_dir() / f"latest_version_{get_platform_tag()}"
if marker.exists():
try:
version = marker.read_text().strip()
if version and _version_newer(version, CHROMIUM_VERSION):
if version and _version_newer(version, base):
# Verify the binary actually exists
binary = get_binary_path(version)
if binary.exists():
return version
except (ValueError, OSError):
pass
return CHROMIUM_VERSION
return base
def _version_tuple(v: str) -> tuple[int, ...]:
@@ -187,14 +203,14 @@ GITHUB_DOWNLOAD_BASE_URL = (
def get_download_url(version: str | None = None) -> str:
"""Return the full download URL for the current platform's binary archive."""
v = version or CHROMIUM_VERSION
v = version or get_chromium_version()
tag = get_platform_tag()
return f"{DOWNLOAD_BASE_URL}/chromium-v{v}/cloakbrowser-{tag}.tar.gz"
def get_fallback_download_url(version: str | None = None) -> str:
"""Return the GitHub Releases fallback URL for the binary archive."""
v = version or CHROMIUM_VERSION
v = version or get_chromium_version()
tag = get_platform_tag()
return f"{GITHUB_DOWNLOAD_BASE_URL}/chromium-v{v}/cloakbrowser-{tag}.tar.gz"
+22 -12
View File
@@ -30,6 +30,7 @@ from .config import (
get_binary_dir,
get_binary_path,
get_cache_dir,
get_chromium_version,
get_download_url,
get_effective_version,
get_fallback_download_url,
@@ -76,18 +77,19 @@ def ensure_binary() -> str:
_maybe_trigger_update_check()
return str(binary_path)
# Fall back to hardcoded version if effective version binary doesn't exist
if effective != CHROMIUM_VERSION:
# Fall back to platform's hardcoded version if effective version binary doesn't exist
platform_version = get_chromium_version()
if effective != platform_version:
fallback_path = get_binary_path()
if fallback_path.exists() and _is_executable(fallback_path):
logger.debug("Binary found in cache: %s", fallback_path)
_maybe_trigger_update_check()
return str(fallback_path)
# Download hardcoded version
# Download platform's hardcoded version
logger.info(
"Stealth Chromium %s not found. Downloading for %s...",
CHROMIUM_VERSION,
platform_version,
get_platform_tag(),
)
_download_and_extract()
@@ -168,7 +170,7 @@ def _verify_download_checksum(file_path: Path, version: str | None = None) -> No
def _fetch_checksums(version: str | None = None) -> dict[str, str] | None:
"""Fetch SHA256SUMS file for a version. Returns {filename: hash} or None."""
v = version or CHROMIUM_VERSION
v = version or get_chromium_version()
has_custom_url = os.environ.get("CLOAKBROWSER_DOWNLOAD_URL")
# Build URL list — respect custom URL contract (no GitHub fallback)
@@ -384,7 +386,7 @@ def check_for_update() -> str | None:
latest = _get_latest_chromium_version()
if latest is None:
return None
if not _version_newer(latest, CHROMIUM_VERSION):
if not _version_newer(latest, get_chromium_version()):
return None
binary_dir = get_binary_dir(latest)
@@ -420,16 +422,23 @@ def _should_check_for_update() -> bool:
def _get_latest_chromium_version() -> str | None:
"""Hit GitHub Releases API, return latest chromium-v* version string or None."""
"""Hit GitHub Releases API, return latest chromium-v* version for this platform.
Checks that the release has a binary asset for the current platform,
so Linux-only releases won't be offered to macOS users.
"""
try:
resp = httpx.get(
GITHUB_API_URL, params={"per_page": 10}, timeout=10.0
)
resp.raise_for_status()
platform_tarball = f"cloakbrowser-{get_platform_tag()}.tar.gz"
for release in resp.json():
tag = release.get("tag_name", "")
if tag.startswith("chromium-v") and not release.get("draft"):
return tag.removeprefix("chromium-v")
asset_names = {a["name"] for a in release.get("assets", [])}
if platform_tarball in asset_names:
return tag.removeprefix("chromium-v")
return None
except Exception:
logger.debug("Auto-update check failed", exc_info=True)
@@ -437,10 +446,10 @@ def _get_latest_chromium_version() -> str | None:
def _write_version_marker(version: str) -> None:
"""Write the latest version marker to cache dir."""
"""Write the latest version marker for this platform to cache dir."""
cache_dir = get_cache_dir()
cache_dir.mkdir(parents=True, exist_ok=True)
marker = cache_dir / "latest_version"
marker = cache_dir / f"latest_version_{get_platform_tag()}"
# Write to temp file then rename for atomicity
tmp = marker.with_suffix(".tmp")
tmp.write_text(version)
@@ -455,10 +464,11 @@ def _check_and_download_update() -> None:
check_file.parent.mkdir(parents=True, exist_ok=True)
check_file.write_text(str(time.time()))
platform_version = get_chromium_version()
latest = _get_latest_chromium_version()
if latest is None:
return
if not _version_newer(latest, CHROMIUM_VERSION):
if not _version_newer(latest, platform_version):
return
# Already downloaded?
@@ -469,7 +479,7 @@ def _check_and_download_update() -> None:
logger.info(
"Newer Chromium available: %s (current: %s). Downloading in background...",
latest,
CHROMIUM_VERSION,
platform_version,
)
_download_and_extract(version=latest)
_write_version_marker(latest)