Files
aios/scripts/autonomous-release/build_artifact.py
T

71 lines
2.4 KiB
Python

#!/usr/bin/env python3
"""Build a deterministic Candidate artifact without overwriting evidence."""
from __future__ import annotations
import argparse
import json
import os
from pathlib import Path
from aios_autonomous_release_candidate.artifact import ArtifactBuilder
def exclusive_write(path: Path, content: bytes, mode: int) -> None:
if path.is_symlink():
raise RuntimeError("artifact output symlink rejected")
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
if hasattr(os, "O_NOFOLLOW"):
flags |= os.O_NOFOLLOW
descriptor = os.open(path, flags, mode)
try:
os.write(descriptor, content)
os.fsync(descriptor)
finally:
os.close(descriptor)
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser()
parser.add_argument("--source", required=True, type=Path)
parser.add_argument("--source-oid", required=True)
parser.add_argument("--tree-oid", required=True)
parser.add_argument("--output-directory", required=True, type=Path)
parser.add_argument("--name", default="aios-autonomous-release-candidate")
return parser
def main(argv: list[str] | None = None) -> int:
args = build_parser().parse_args(argv)
output = args.output_directory
output.mkdir(parents=True, exist_ok=True, mode=0o750)
if output.is_symlink():
raise RuntimeError("artifact output directory symlink rejected")
os.chmod(output, output.stat().st_mode & 0o750)
builder = ArtifactBuilder()
built = builder.build_from_directory(args.source_oid, args.tree_oid, args.source)
builder.verify(built)
artifact_path = output / f"{args.name}.tar"
manifest_path = output / f"{args.name}.manifest.json"
exclusive_write(artifact_path, built.content, 0o640)
exclusive_write(manifest_path, built.manifest.as_json_bytes(), 0o640)
print(
json.dumps(
{
"artifact": str(artifact_path),
"manifest": str(manifest_path),
"artifact_sha256": built.manifest.artifact_sha256,
"manifest_sha256": built.manifest.manifest_sha256,
"package_closure_sha256": built.manifest.package_closure_sha256,
"secrets_included": False,
"production_side_effects": False,
},
sort_keys=True,
)
)
return 0
if __name__ == "__main__":
raise SystemExit(main())