build: package universal Windows runtime and verify automatic CPU fallback
This commit is contained in:
1 parent
0fcc8ec21c
commit
278b09f82c
16 files changed
+695
-34
No files matched your search
@@ -33,14 +33,17 @@ def pe_machine(path):
|
||||
def package(root, executable, output):
|
||||
resources = root / "apps/desktop/src-tauri/resources"
|
||||
selected = [(executable, "searchi.exe"), (root / "LICENSE", "LICENSE.txt")]
|
||||
for name in ["searchi-gemma-worker.exe", "LLAMA-LICENSE.txt", "media-runtime/manifest.json",
|
||||
"media-runtime/bin/ffmpeg.exe", "media-runtime/bin/ffprobe.exe"]:
|
||||
for name in ["searchi-gemma-worker.exe", "LLAMA-LICENSE.txt", "vulkan-1.dll", "VULKAN-LICENSE.txt", "media-runtime/manifest.json",
|
||||
"media-runtime/bin/ffmpeg.exe", "media-runtime/bin/ffprobe.exe",
|
||||
"licenses/Inter-OFL.txt", "licenses/Fluent-MIT.txt", "media-runtime/licenses/LICENSE.txt"]:
|
||||
selected.append((resources / name, name))
|
||||
for directory in ["licenses", "media-runtime/licenses"]:
|
||||
notices = list((resources / directory).rglob("*.txt"))
|
||||
if not notices:
|
||||
raise ValueError(f"Required notices are missing: {directory}")
|
||||
selected.extend((path, path.relative_to(resources).as_posix()) for path in notices)
|
||||
selected_names = {name for _, name in selected}
|
||||
selected.extend((path, path.relative_to(resources).as_posix()) for path in notices
|
||||
if path.relative_to(resources).as_posix() not in selected_names)
|
||||
machine = pe_machine(executable)
|
||||
architecture = {0x8664: "x86_64", 0xAA64: "aarch64"}.get(machine)
|
||||
if architecture is None:
|
||||
@@ -50,7 +53,7 @@ def package(root, executable, output):
|
||||
raise ValueError(f"Required package file is missing: {name}")
|
||||
if path != executable and path != root / "LICENSE" and not path.resolve().is_relative_to(resources.resolve()):
|
||||
raise ValueError("Resource resolves outside the staging directory")
|
||||
if name.endswith(".exe") and pe_machine(path) != machine:
|
||||
if name.endswith((".exe", ".dll")) and pe_machine(path) != machine:
|
||||
raise ValueError(f"Executable architecture differs: {name}")
|
||||
records = []
|
||||
output.parent.mkdir(parents=True, exist_ok=True)
|
||||
@@ -59,10 +62,17 @@ def package(root, executable, output):
|
||||
try:
|
||||
with zipfile.ZipFile(temporary_path, "w", zipfile.ZIP_DEFLATED, compresslevel=6) as archive:
|
||||
for path, name in selected:
|
||||
with path.open("rb") as stream:
|
||||
checksum = hashlib.file_digest(stream, "sha256").hexdigest()
|
||||
archive.write(path, name)
|
||||
records.append({"path": name, "bytes": path.stat().st_size, "sha256": checksum})
|
||||
# Hash and count the same blocks written to the archive: a
|
||||
# second source read or subsequent stat can describe different
|
||||
# bytes when a staged file changes during release preparation.
|
||||
checksum = hashlib.sha256()
|
||||
count = 0
|
||||
with path.open("rb") as stream, archive.open(name, "w", force_zip64=True) as entry:
|
||||
while block := stream.read(1024 * 1024):
|
||||
entry.write(block)
|
||||
checksum.update(block)
|
||||
count += len(block)
|
||||
records.append({"path": name, "bytes": count, "sha256": checksum.hexdigest()})
|
||||
archive.writestr("PACKAGE.json", json.dumps({"platform": "windows", "architecture": architecture,
|
||||
"status": "unsigned development package; clean-machine verification pending", "files": records}, indent=2))
|
||||
archive.writestr("START-HERE.txt", "searchi — Find what matters. Locally.\n\n"
|
||||
|
||||
Reference in new issue
Block a user