hermes-hub/scripts/build_dist.py
Hermes Team 50fde5f16e refactor(plan-a): close residual blockers, concurrency race, and feed verification
- Implemented 3-tier release feed status (MANIFEST_LIVE, PACKAGE_LIVE, PACKAGE_HASH_VERIFIED)
- Added reproducible package and checksum builder in scripts/build_dist.py
- Preserved user header comments across YAML saves in router_config.py
- Connected model_timeout_seconds, monitoring_interval_seconds, and auto_monitoring to runtime
- Guarded global gemini:antigravity credential swap with _AGY_INVOCATION_LOCK to eliminate concurrent subprocess race
- Added concurrency regression test in tests/test_antigravity_concurrency.py
- Added interprocess file locking (_FileLock) for router_state.json in health_tracker.py
- Sandboxed APPDATA and USERPROFILE in tests/test_installer.py
- Exported roadmap modules in router/__init__.py
- Verified 151 passing tests (100%) and 7/7 release gate checks
2026-08-20 22:55:43 +07:00

79 lines
2.4 KiB
Python

"""Hermes Hub — Reproducible Package & Checksums Builder.
Builds distribution archive (hermes-hub-<version>.zip), computes SHA-256 hashes,
and writes canonical dist/checksums.txt.
"""
from __future__ import annotations
import hashlib
import os
import zipfile
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "src"))
from antigravity_provider.version import __version__
DIST_DIR = ROOT / "dist"
SRC_DIR = ROOT / "src"
def sha256_file(filepath: Path) -> str:
h = hashlib.sha256()
with open(filepath, "rb") as f:
while chunk := f.read(65536):
h.update(chunk)
return h.hexdigest()
def build_package_zip(version: str = __version__) -> Path:
DIST_DIR.mkdir(parents=True, exist_ok=True)
zip_name = f"hermes-hub-{version}.zip"
zip_path = DIST_DIR / zip_name
# Create reproducible zip archive with deterministic timestamps
with zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_DEFLATED) as zf:
for root, dirs, files in os.walk(SRC_DIR):
for file in sorted(files):
if file.endswith((".pyc", ".pyo")) or "__pycache__" in root:
continue
file_path = Path(root) / file
arcname = file_path.relative_to(ROOT).as_posix()
zf.write(file_path, arcname=arcname)
# Include config and docs
for extra in ("config/compatibility.json", "README.md", "pyproject.toml"):
extra_path = ROOT / extra
if extra_path.is_file():
zf.write(extra_path, arcname=extra)
return zip_path
def update_checksums():
DIST_DIR.mkdir(parents=True, exist_ok=True)
checksum_file = DIST_DIR / "checksums.txt"
lines = []
for item in sorted(DIST_DIR.iterdir()):
if item.is_file() and item.name != "checksums.txt":
digest = sha256_file(item)
lines.append(f"{digest} {item.name}")
if lines:
checksum_file.write_text("\n".join(lines) + "\n", encoding="utf-8")
print(f"Updated {checksum_file} with {len(lines)} artifact checksum(s):")
for line in lines:
print(f" {line}")
def main():
print(f"Building Hermes Hub distribution package v{__version__}...")
zip_path = build_package_zip(__version__)
print(f"Created: {zip_path}")
update_checksums()
if __name__ == "__main__":
main()