Mage-Flow-NVFP4-AJH / validate_release.py
ajh-code's picture
Add files using upload-large-folder tool
54152e6 verified
Raw
History Blame Contribute Delete
2.88 kB
#!/usr/bin/env python3
"""Verify every immutable file declared by the v1 release manifest."""
from __future__ import annotations
import hashlib
import json
from pathlib import Path
import sys
RELEASE_ROOT = Path(__file__).resolve().parent
MANIFEST_PATH = RELEASE_ROOT / "MANIFEST.json"
def sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as handle:
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def main() -> int:
manifest = json.loads(MANIFEST_PATH.read_text(encoding="utf-8"))
failures: list[str] = []
checked: list[dict[str, object]] = []
declared_paths = {
Path(record["path"]).as_posix() for record in manifest["files"]
}
actual_paths = {
path.relative_to(RELEASE_ROOT).as_posix()
for path in RELEASE_ROOT.rglob("*")
if (
path.is_file()
and path != MANIFEST_PATH
and "__pycache__" not in path.relative_to(RELEASE_ROOT).parts
and path.suffix != ".pyc"
)
}
undeclared = sorted(actual_paths - declared_paths)
absent = sorted(declared_paths - actual_paths)
if undeclared:
failures.extend(f"undeclared package file: {path}" for path in undeclared)
if absent:
failures.extend(f"declared package file is absent: {path}" for path in absent)
for record in manifest["files"]:
relative = Path(record["path"])
path = (RELEASE_ROOT / relative).resolve()
if not path.is_relative_to(RELEASE_ROOT):
failures.append(f"path escapes release root: {relative}")
continue
if not path.is_file():
failures.append(f"missing: {relative}")
continue
if path.is_symlink():
failures.append(f"release file must not be a symlink: {relative}")
continue
actual_size = path.stat().st_size
actual_hash = sha256(path)
if actual_size != record["size"]:
failures.append(
f"size mismatch {relative}: {actual_size} != {record['size']}"
)
if actual_hash != record["sha256"]:
failures.append(
f"SHA-256 mismatch {relative}: {actual_hash} != "
f"{record['sha256']}"
)
checked.append(
{
"path": str(relative),
"size": actual_size,
"sha256": actual_hash,
}
)
result = {
"schema_version": manifest["schema_version"],
"status": "pass" if not failures else "fail",
"checked_file_count": len(checked),
"failures": failures,
}
print(json.dumps(result, indent=2, sort_keys=True))
return 0 if not failures else 1
if __name__ == "__main__":
raise SystemExit(main())