Files
codex/third_party/voice/release_runtime.py
Benjamin Carlsson 721f46a07a Bundle signed voice resources in macOS releases (#43983)
## What changed

- Build, sign, and notarize `codex-voice-host` and its native runtime for Apple Silicon and Intel macOS release packages, granting the helper audio-input access.
- Include voice resources in primary package archives and DMGs, with a root-level `codex` symlink to `bin/codex` so the runtime can be located.
- Seal runtime receipts with post-signing hashes, require matching release versions and source builds, and bundle dependency notices, licenses, and source metadata.
- Keep voice resources out of Python wheels to preserve their older macOS compatibility; the native voice build targets macOS 14.

## Testing

Add packaging tests for alpha, beta, and stable versions, signed-byte preservation, license hashes, receipt validation, tamper detection, and exclusion of unlisted files. Extend release verification to check voice architectures, signatures, build identity, package hashes, and DMG contents.

GitOrigin-RevId: 9f9415a8b2532d655a9a8740bcdf64066ddb7472
2026-09-09 02:20:06 +00:00

57 lines
2.2 KiB
Python

"""Stage verified macOS voice libraries and seal their post-signing release receipt."""
import argparse
import json
from pathlib import Path
import shutil
from package_runtime import runtime_files
from runtime import digest
def stage(source: Path, destination: Path, target: str) -> None:
if target not in {"aarch64-apple-darwin", "x86_64-apple-darwin"}:
raise ValueError("public voice runtime requires a macOS target")
source = source.resolve(strict=True)
files = runtime_files(source, target)
destination.mkdir()
try:
for relative, expected in files.items():
copied = destination / relative
copied.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(source / relative, copied)
if digest(copied) != expected:
raise ValueError("runtime changed while staging release inputs")
except BaseException:
shutil.rmtree(destination)
raise
def seal(root: Path, target: str) -> None:
root = root.resolve(strict=True)
manifest_path = root / "runtime.json"
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
if manifest.get("developmentOnly") is not True or manifest.get("target") != target:
raise ValueError("expected an unsealed development receipt for this target")
for record in manifest["libraries"]:
record["sha256"] = digest(root / record["path"])
manifest["developmentOnly"] = False
manifest["distribution"] = "publicRelease"
manifest_path.write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
runtime_files(root, target, public_release=True)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("operation", choices=("stage", "seal"))
parser.add_argument("--target", required=True)
parser.add_argument("--source", type=Path)
parser.add_argument("--output", type=Path, required=True)
args = parser.parse_args()
if args.operation == "stage":
if args.source is None:
parser.error("stage requires --source")
stage(args.source, args.output, args.target)
else:
seal(args.output, args.target)