Files
codex/.github/scripts/voice-cygwin-inputs.py
Benjamin Carlsson ce7fbb373b Bundle native voice runtimes in Windows releases (#44922)
## Why

Windows release packages need the voice helper and native audio libraries. Realtime TLS connections on fresh Windows installations also need platform certificate validation so Windows can retrieve missing trusted roots on demand.

## What changed

- Build and sign the voice helper and audio DLLs for Windows x64 and ARM64, bundle a pinned Microsoft CRT DLL, and verify signatures and runtime receipts before packaging.
- Add verified, pinned Cygwin and native build tools plus MSVC linker, compiler, and path handling fixes for the Windows Bazel builds.
- Include voice resources in primary release archives and WinGet packages. Preserve WinGet executable names, update manifest hashes, and recognize the package root through matching entrypoint metadata. Keep Python runtime wheels voice-free to preserve their existing Windows support floor.
- Use Windows platform TLS validation for realtime WebSockets when no custom CA bundle is configured, preserving custom CA behavior.

## Testing

Add coverage for build-input integrity and unsafe paths, signed Windows runtime assembly, WinGet file and hash preservation, package discovery, and TLS trust selection, untrusted certificate rejection, and hostname validation.

GitOrigin-RevId: 423da35872fa5549d69fd4ca97d922bb49599386
2026-09-11 21:59:24 +00:00

99 lines
3.7 KiB
Python

"""Verify the pinned Cygwin build-input archive before offline installation."""
import argparse
import hashlib
import json
from pathlib import Path, PurePosixPath
import shutil
import tarfile
def records(manifest):
metadata = manifest["metadata"]
if {item["file"] for item in metadata} != {
"x86_64/setup.xz",
"x86_64/setup.xz.sig",
}:
raise ValueError("signed setup metadata is required")
entries = metadata + manifest["packages"]
expected = {entry["file"]: entry for entry in entries}
if len(expected) != len(entries):
raise ValueError("duplicate Cygwin input")
for name in expected:
path = PurePosixPath(name)
if (
not path.parts
or path.is_absolute()
or ".." in path.parts
or path.as_posix() != name
or "\\" in name
or ":" in name
):
raise ValueError(f"unsafe Cygwin input: {name}")
return expected
def extract(manifest, archive, destination):
expected = records(manifest)
pin = manifest["archive"]
with archive.open("rb") as stream:
if (
archive.stat().st_size != pin["bytes"]
or hashlib.file_digest(stream, "sha256").hexdigest() != pin["sha256"]
):
raise ValueError("Cygwin archive digest or size mismatch")
stream.seek(0)
with tarfile.open(fileobj=stream, mode="r:gz") as bundle:
members = bundle.getmembers()
if len(members) != len(expected) or {m.name for m in members} != set(
expected
):
raise ValueError("missing, extra, or duplicate Cygwin inputs")
for member in members:
if not member.isfile() or member.issparse():
raise ValueError(f"non-regular Cygwin input: {member.name}")
with bundle.extractfile(member) as source:
if (
member.size != expected[member.name]["bytes"]
or hashlib.file_digest(source, "sha512").hexdigest()
!= expected[member.name]["sha512"]
):
raise ValueError(f"Cygwin input mismatch: {member.name}")
destination.mkdir(parents=True)
try:
bundle.extractall(destination, members=members, filter="data")
except BaseException:
shutil.rmtree(destination)
raise
def check_installed(manifest, inventory):
installed = sorted(
tuple(line.split())
for line in inventory.read_text().splitlines()
if len(line.split()) == 2 and not line.startswith("Package ")
)
expected = sorted((item["name"], item["version"]) for item in manifest["packages"])
if installed != expected:
raise ValueError("installed Cygwin packages differ from reviewed inputs")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("command", choices=("extract", "check-installed"))
parser.add_argument("--archive", type=Path)
parser.add_argument("--directory", type=Path)
parser.add_argument("--inventory", type=Path)
args = parser.parse_args()
pinned = json.loads(
Path(__file__).with_name("voice-cygwin-snapshot.json").read_text()
)
if args.command == "extract":
if args.archive is None or args.directory is None:
parser.error("extract requires --archive and --directory")
extract(pinned, args.archive, args.directory)
else:
if args.inventory is None:
parser.error("check-installed requires --inventory")
check_installed(pinned, args.inventory)