"""Freeze the pushed board commit; never package uncommitted code or private data.""" import concurrent.futures import hashlib import io import json from pathlib import Path import subprocess import urllib.request import zipfile ROOT = Path(__file__).resolve().parents[1] COMMIT = '0ba3c0a07afb70aed54713739d3c128dacc1aaf0' ORIGIN = 'https://kangshifu.fmode.cn' OUT = ROOT / 'work/board-deploy-20261106-r1' PKG = OUT / 'package' sha = lambda b: hashlib.sha256(b).hexdigest() norm = lambda b: sha(b.replace(b'\r\n', b'\n')) def remote(p): req = urllib.request.Request(ORIGIN + '/' + p, headers={'Cache-Control': 'no-cache'}) with urllib.request.urlopen(req, timeout=35) as r: return r.read(), r.headers.get('content-type', '') def prepare(): if PKG.exists(): raise RuntimeError('PACKAGE_ALREADY_EXISTS') source = zipfile.ZipFile(io.BytesIO(subprocess.check_output(['git', 'archive', '--format=zip', COMMIT], cwd=ROOT))) members = [p for p in source.namelist() if not p.endswith('/') and ( (p.startswith('src/') and not p.startswith('src/dev/')) or p.startswith(('server/src/', 'server/references/', 'server/web/', 'server/test/', 'test/')) or p in {'package.json', 'server/scripts/build-member-groups.mjs', 'server/library-api.mjs'} or (p.startswith('server/voc-library/') and not Path(p).name.startswith('test_')))] PKG.mkdir(parents=True) for p in members: target = PKG / 'payload' / p target.parent.mkdir(parents=True, exist_ok=True) target.write_bytes(source.read(p)) front = sorted(p for p in members if p.startswith('src/')) index, _ = remote('index.html') production = dict(zip(front, concurrent.futures.ThreadPoolExecutor(max_workers=6).map(remote, front))) files = [] unknown = [] for p in front: body, kind = production[p] after = source.read(p) # SPA fallback is an absent module, never a successfully deployed JavaScript file. absent = body == index and 'text/html' in kind baseline = [] if absent else [norm(body)] known = absent or norm(body) == norm(after) if not known: for revision in ('bb38e3732e8ae102ff98345abfee5c1caba13d71', 'd14d02f', '7d01b5c'): before = subprocess.run(['git', 'show', revision + ':' + p], cwd=ROOT, capture_output=True) if before.returncode == 0 and norm(before.stdout) == norm(body): known = True break if not known: unknown.append(p) target = OUT / 'production-before' / p target.parent.mkdir(parents=True, exist_ok=True) target.write_bytes(body) files.append({'path': p, 'sha256': sha(after), 'priorNormalizedSha256': baseline, 'allowMissing': absent, 'observedState': 'spa-fallback' if absent else 'static-file', 'observedSha256': sha(body), 'changed': absent or norm(body) != norm(after), 'matchesKnownGitVersion': known}) manifest = {'version': 'ksf.board.publish.v1', 'release': 'ksf.board.20261106.r1', 'commit': COMMIT, 'origin': ORIGIN, 'homepageSha256': sha(index), 'files': files} (PKG / 'deploy').mkdir() (PKG / 'deploy/board-files.json').write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + '\n', encoding='utf-8') receipt = {'commit': COMMIT, 'staticFiles': len(files), 'changedFiles': sum(x['changed'] for x in files), 'newFiles': sum(x['allowMissing'] for x in files), 'unknownProductionBaselines': unknown, 'homepageSha256': sha(index), 'productionWrites': 0, 'productionBrowserVerified': False} (OUT / 'preparation.json').write_text(json.dumps(receipt, ensure_ascii=False, indent=2), encoding='utf-8') print(json.dumps(receipt, ensure_ascii=False)) if __name__ == '__main__': prepare()