#!/usr/bin/env python3 """Read-only release metadata check against an explicitly reviewed source ref. This does not sign, generate, publish, build or validate artifact bytes. Signature, artifact provenance, mirror parity and operator acceptance gates remain mandatory. """ import argparse import json from pathlib import Path import re import subprocess import tomllib from urllib.parse import unquote, urlsplit def validate(manifest, commit, backend_version, frontend_version): version = manifest.get('version') if not isinstance(version, str) or not re.fullmatch(r'\d+\.\d+\.\d+(?:-[A-Za-z0-9.]+)?', version): raise ValueError('invalid release version') if version != backend_version or version != frontend_version: raise ValueError('manifest/backend/frontend versions differ from reviewed source') if manifest.get('source_commit') != commit: raise ValueError('manifest source_commit differs from reviewed source') components = manifest.get('components') if not isinstance(components, list) or not components: raise ValueError('release has no components') for component in components: if component.get('new_version') != version: raise ValueError('component version differs from reviewed release') url = urlsplit(component.get('download_url', '')) parts = unquote(url.path).split('/') if (url.scheme != 'https' or not url.netloc or url.query or url.fragment or len(parts) < 5 or parts[-4:-1] != ['releases', 'download', 'v' + version] or not parts[-1] or parts[-1] in ('.', '..')): raise ValueError('component URL does not bind the reviewed release version over HTTPS') def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('manifest', type=Path) parser.add_argument('--source-ref', required=True, help='explicit reviewed full commit or tag') args = parser.parse_args() root = Path(__file__).resolve().parents[1] def git(*arguments): return subprocess.check_output(['git', '-C', str(root), *arguments], text=True).strip() commit = git('rev-parse', '--verify', args.source_ref + '^{commit}') backend = tomllib.loads(git('show', commit + ':core/archipelago/Cargo.toml'))['package']['version'] frontend = json.loads(git('show', commit + ':neode-ui/package.json'))['version'] validate(json.loads(args.manifest.read_text()), commit, backend, frontend) print('Release metadata matches reviewed source ' + commit + '; artifact/signature acceptance remains separate') if __name__ == '__main__': try: main() except (ValueError, KeyError, subprocess.CalledProcessError) as error: raise SystemExit('REFUSED: ' + str(error))