Termux removes old package files, so a pinned URL and hash do not keep build inputs available. Preserve the exact bytes without changing pins. Archive every PM HTTP artifact and the Termux runtime inputs by SHA256. CI reads R2 first. Only a missing object permits an upstream download, hash verification, immutable upload, and verified readback. Seed the actual toolchain and payload stores before their consumers run. Use the public archive as a pinned fallback in PM, bootstrap installers, and Nix fetchers. Keep network retries bounded and report attempted URLs. Keep publication credentials in protected CI jobs, not installed clients. Verification: - 283 targeted tests passed; five POSIX tests skipped on Windows. - All 87 preserved Termux packages passed local archive miss/hit checks. - Native ARM64 ripgrep installed through the mirror and ran successfully. - Wheel import, workflow lint, Python lint, shell syntax, and pins passed. Live R2 publication, POSIX tests, and Nix builds remain for native CI. The real-byte archive checks used loopback HTTP, not the live bucket.
29 lines
872 B
Python
29 lines
872 B
Python
"""Public, content-addressed copies of reviewed binary inputs."""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
import re
|
|
|
|
from pm.downloader import Source
|
|
|
|
_LAYOUT = json.loads(Path(__file__).with_name("artifact-mirror.json").read_text(encoding="utf-8"))
|
|
KEY_PREFIX = _LAYOUT["prefix"]
|
|
PUBLIC_PREFIX = _LAYOUT["origin"] + "/" + KEY_PREFIX
|
|
|
|
|
|
def object_key(sha256: str) -> str:
|
|
if not isinstance(sha256, str) or not re.fullmatch(r"[a-f0-9]{64}", sha256):
|
|
raise ValueError("A pinned input requires a full lowercase SHA256")
|
|
return KEY_PREFIX + sha256
|
|
|
|
|
|
def mirror_url(sha256: str) -> str:
|
|
object_key(sha256)
|
|
return PUBLIC_PREFIX + sha256
|
|
|
|
|
|
def pinned_source(url: str, dest: Path, sha256: str) -> Source:
|
|
archive = mirror_url(sha256)
|
|
return Source(url, dest, sha256, fallbacks=() if url == archive else (archive,))
|