Reject stale native runtime build provenance before release staging

This commit is contained in:
karl committed 2026-10-13 13:04:58 +02:00
1 parent ea2c3f4691
commit 07bbcb76e8
12 files changed
+204 -9

No files matched your search

+18 -1
View File
@@ -8,6 +8,7 @@ from unittest import mock
import zipfile
from package_windows import package, CRT_LIBRARIES
from embeddinggemma2 import runtime_provenance as provenance
def executable(path, machine=0x8664):
@@ -26,7 +27,7 @@ def inventory(resources):
for name in ["ggml-cpu-x64.dll", "ggml-vulkan.dll", "vulkan-1.dll", "ggml.dll", "ggml-base.dll", "llama.dll", "mtmd.dll", *sorted(CRT_LIBRARIES)]:
data = (resources / name).read_bytes()
records.append({"path": name, "bytes": len(data), "sha256": hashlib.sha256(data).hexdigest()})
(resources / "runtime-libraries.json").write_text(json.dumps({"worker_sha256": hashlib.sha256(worker.read_bytes()).hexdigest(), "libraries": records}))
(resources / "runtime-libraries.json").write_text(json.dumps({"worker_sha256": hashlib.sha256(worker.read_bytes()).hexdigest(), "build_provenance": provenance.fingerprint(resources.parents[3]), "libraries": records}))
class PackageTests(unittest.TestCase):
@@ -48,8 +49,24 @@ class PackageTests(unittest.TestCase):
package(root, app, output, cli)
self.assertEqual(output.read_bytes(), previous)
def test_old_inventory_rejected_without_replacing_archive(self):
with tempfile.TemporaryDirectory() as directory:
root, resources, app, output = self.fixture(directory)
output.write_bytes(b"previous archive")
inventory = resources / "runtime-libraries.json"
manifest = json.loads(inventory.read_text())
del manifest["build_provenance"]
inventory.write_text(json.dumps(manifest))
with self.assertRaisesRegex(ValueError, "provenance"):
package(root, app, output)
self.assertEqual(output.read_bytes(), b"previous archive")
def fixture(self, directory):
root = Path(directory)
for name in provenance.INPUTS:
path = root / name
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes((provenance.ROOT / name).read_bytes())
resources = root / "apps/desktop/src-tauri/resources"
app = root / "build/app.exe"
executable(app)