Files
codex/scripts/codex_package/test_v8.py
Charlie Marsh c0b6285711 Pin V8 release manifests and prevent published release replacement (#43444)
## Why

Artifact checksums alone do not authenticate the downloaded checksum manifest. V8 downloads need a trusted digest recorded in the repository, and published releases should not have their assets overwritten.

## What changed

- Pin the V8 `150.4.0` release manifest digests and verify manifests before downloading archives or bindings in packaging and `setup-rusty-v8`, preserving CRLF support.
- Refuse to replace published V8 releases, remove unfinished drafts on retry, and use `gh release create` to upload assets before publication.
- Install Windows `sccache` through a pinned `taiki-e/install-action` in the release and canary workflows.
- Document independent manifest verification and digest recording for version updates.

## Testing

Add five packaging tests covering successful downloads, CRLF manifests, tampered manifests, missing pins, and missing pin files. Rejection tests verify that artifacts are not downloaded.

GitOrigin-RevId: 5c771cdcff376388e124faa4826bf81135d84b50
2026-09-07 11:55:57 +00:00

153 lines
5.5 KiB
Python

import hashlib
import sys
import tempfile
import unittest
from collections.abc import Iterator
from contextlib import contextmanager
from pathlib import Path
from unittest.mock import MagicMock, patch
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from codex_package import v8
from codex_package.targets import TARGET_SPECS, TargetSpec
class FetchCodexV8ArtifactsTest(unittest.TestCase):
version = "150.4.0"
def setUp(self) -> None:
temporary = tempfile.TemporaryDirectory()
self.addCleanup(temporary.cleanup)
self.root = Path(temporary.name)
@contextmanager
def release(
self,
target: str,
*,
line_ending: bytes = b"\n",
trusted_digest: str | None = None,
trusted_name: str | None = None,
create_pins: bool = True,
) -> Iterator[tuple[TargetSpec, MagicMock, str]]:
spec = TARGET_SPECS[target]
profile = v8.V8_ARTIFACT_PROFILE
archive_name = (
f"rusty_v8_{profile}_{target}.lib.gz"
if spec.is_windows
else f"librusty_v8_{profile}_{target}.a.gz"
)
binding_name = f"src_binding_{profile}_{target}.rs"
manifest_name = f"rusty_v8_{profile}_{target}.sha256"
archive = b"trusted V8 archive"
binding = b"trusted V8 binding"
manifest = (
line_ending.join(
(
f"{hashlib.sha256(archive).hexdigest()} {archive_name}".encode(),
f"{hashlib.sha256(binding).hexdigest()} {binding_name}".encode(),
)
)
+ line_ending
)
payloads = {
manifest_name: manifest,
archive_name: archive,
binding_name: binding,
}
if create_pins:
pins = (
self.root / "third_party/v8/rusty_v8_150_4_0_release_manifests.sha256"
)
pins.parent.mkdir(parents=True)
digest = trusted_digest or hashlib.sha256(manifest).hexdigest()
name = trusted_name or manifest_name
pins.write_bytes(f"{digest} {name}".encode() + line_ending)
def download(_url: str, destination: Path) -> None:
destination.parent.mkdir(parents=True, exist_ok=True)
destination.write_bytes(payloads[destination.name])
with (
patch.object(v8, "REPO_ROOT", self.root),
patch.object(v8, "download_file", side_effect=download) as download_file,
):
yield spec, download_file, manifest_name
def test_fetches_artifacts_after_authenticating_manifest(self) -> None:
with self.release("x86_64-unknown-linux-gnu") as (
spec,
download,
manifest_name,
):
artifacts = v8.fetch_codex_v8_artifacts(
spec, version=self.version, cache_root=self.root / "cache"
)
self.assertEqual(artifacts.archive.read_bytes(), b"trusted V8 archive")
self.assertEqual(artifacts.binding.read_bytes(), b"trusted V8 binding")
self.assertEqual(download.call_args_list[0].args[1].name, manifest_name)
self.assertEqual(download.call_count, 3)
def test_authenticates_windows_manifest_with_crlf(self) -> None:
with self.release("x86_64-pc-windows-msvc", line_ending=b"\r\n") as (
spec,
download,
_manifest_name,
):
artifacts = v8.fetch_codex_v8_artifacts(
spec, version=self.version, cache_root=self.root / "cache"
)
self.assertEqual(artifacts.archive.read_bytes(), b"trusted V8 archive")
self.assertEqual(artifacts.binding.read_bytes(), b"trusted V8 binding")
self.assertEqual(download.call_count, 3)
def test_rejects_tampered_manifest_before_downloading_artifacts(self) -> None:
with self.release("x86_64-unknown-linux-gnu", trusted_digest="0" * 64) as (
spec,
download,
manifest_name,
):
with self.assertRaisesRegex(
RuntimeError, "does not match its trusted SHA-256"
):
v8.fetch_codex_v8_artifacts(
spec, version=self.version, cache_root=self.root / "cache"
)
download.assert_called_once()
self.assertEqual(download.call_args.args[1].name, manifest_name)
def test_rejects_missing_manifest_pin_before_downloading_artifacts(self) -> None:
with self.release(
"x86_64-unknown-linux-gnu", trusted_name="another-target.sha256"
) as (spec, download, manifest_name):
with self.assertRaisesRegex(RuntimeError, "has no trusted SHA-256"):
v8.fetch_codex_v8_artifacts(
spec, version=self.version, cache_root=self.root / "cache"
)
download.assert_called_once()
self.assertEqual(download.call_args.args[1].name, manifest_name)
def test_rejects_missing_pin_file_before_downloading_artifacts(self) -> None:
with self.release("x86_64-unknown-linux-gnu", create_pins=False) as (
spec,
download,
manifest_name,
):
with self.assertRaises(FileNotFoundError):
v8.fetch_codex_v8_artifacts(
spec, version=self.version, cache_root=self.root / "cache"
)
download.assert_called_once()
self.assertEqual(download.call_args.args[1].name, manifest_name)
if __name__ == "__main__":
unittest.main()