← Commit history

Update 2 file(s)

John Lauer ·dfcbec098a ·1mo ago ·parent ebd5aa5
2 files changed +169
tools/build_release.pyadded+94
@@ -0,0 +1,94 @@+#!/usr/bin/env python3+"""Build (and optionally publish) a kicad-bridge runtime release.++Until now the shipping file list lived only in a maintainer's scratchpad, so+nobody else could reproduce a release and a container reset would have lost it.+It is `tools/release_files.json` now, in the repo, next to this script.++    python3 tools/build_release.py 0.9.219            # build + update manifest+    python3 tools/build_release.py 0.9.219 --publish  # ... and push + upload++The zip is built from the explicit list, never a directory walk: a stray file in+the working tree must never end up on a user's machine.+"""+import hashlib+import json+import os+import subprocess+import sys+import zipfile+from datetime import datetime, timezone++ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))+REF = "adom/kicad-bridge"+MANIFEST = "adom-bridge-kicad-manifest.json"+++def main() -> int:+    if len(sys.argv) < 2:+        print(__doc__)+        return 2+    version = sys.argv[1].lstrip("v")+    publish = "--publish" in sys.argv+    os.chdir(ROOT)++    files = json.load(open("tools/release_files.json"))["files"]+    missing = [f for f in files if not os.path.isfile(f)]+    if missing:+        print("REFUSING TO BUILD - listed files are missing:")+        for m in missing:+            print("   ", m)+        return 1++    # Version lives in two places and they must agree; a mismatch has shipped+    # before and is invisible until someone reads bridgeVersion off a box.+    open("BRIDGE_VERSION", "w").write(version)+    bj = json.load(open("bridge.json"))+    bj["version"] = version+    json.dump(bj, open("bridge.json", "w"), indent=2)++    out = f"adom-bridge-kicad-v{version}.zip"+    with zipfile.ZipFile(out, "w", zipfile.ZIP_DEFLATED) as z:+        for f in files:+            z.write(f, f)++    raw = open(out, "rb").read()+    sha, size = hashlib.sha256(raw).hexdigest(), len(raw)++    # Guards for two failures that actually shipped: a raw NUL byte written into+    # a source file (un-importable, bricks the bridge), and a version mismatch+    # between the zip and BRIDGE_VERSION.+    with zipfile.ZipFile(out) as z:+        if z.read("BRIDGE_VERSION").decode().strip() != version:+            print("REFUSING: BRIDGE_VERSION inside the zip does not match", version)+            return 1+        for n in z.namelist():+            if n.endswith(".py") and b"\x00" in z.read(n):+                print(f"REFUSING: NUL byte in {n} - Python cannot import this file")+                return 1++    m = json.load(open(MANIFEST))+    m.update(version=version, sha256=sha, size=size,+             url=f"https://wiki.adom.inc/download/{REF}/{version}/{out}",+             released_at=datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"))+    json.dump(m, open(MANIFEST, "w"), indent=2)++    print(f"built {out}\n  files : {len(files)}\n  size  : {size}\n  sha256: {sha}")+    if not publish:+        print("\nnot published (pass --publish). Manifest updated locally.")+        return 0++    subprocess.run(["adom-wiki", "repo", "push", REF, "--files",+                    "BRIDGE_VERSION", "bridge.json", MANIFEST], check=False)+    subprocess.run(["adom-wiki", "release", "create", REF, version], check=False)+    subprocess.run(["adom-wiki", "release", "upload", REF, version, out], check=False)+    print("\nPUBLISHED. Now INSTALL it - refresh_bridges does not pull a release:")+    print(f"  adom-bridge --target <BOX> bridge_install '{{\"manifestUrl\":"+          f"\"https://wiki.adom.inc/api/v1/pages/kicad-bridge/files/{MANIFEST}\","+          f"\"force\":true,\"reason\":\"...\"}}'")+    print("  then confirm with kicad_status -> bridgeVersion")+    return 0+++if __name__ == "__main__":+    raise SystemExit(main())
tools/release_files.jsonadded+75
@@ -0,0 +1,75 @@+{+  "_comment": "The exact runtime payload. Adding a file here ships it to every Bridge user; the release zip is built from THIS list, never from a directory walk. skills/, dev-skills/, publish-skills/, dashboard/, demo/, docs/, images and *.md except SKILL.md are deliberately absent - they are the page repo's job, not the runtime's.",+  "files": [+    "BRIDGE_VERSION",+    "LICENSE",+    "SKILL.md",+    "adom_library.py",+    "bridge.json",+    "caller_identity.py",+    "capabilities.py",+    "certs/cacert.pem",+    "dock.json",+    "handlers/__init__.py",+    "handlers/ad_client.py",+    "handlers/bom.py",+    "handlers/bridge_client.py",+    "handlers/close_windows.py",+    "handlers/demo.py",+    "handlers/diagnostics.py",+    "handlers/export.py",+    "handlers/export_molecule.py",+    "handlers/export_part.py",+    "handlers/fix_keyboard.py",+    "handlers/install_footprint.py",+    "handlers/install_library.py",+    "handlers/install_symbol.py",+    "handlers/kicad_cli_lint.py",+    "handlers/kicad_ui.py",+    "handlers/launch.py",+    "handlers/library_browser.py",+    "handlers/make_part_project.py",+    "handlers/netlist.py",+    "handlers/open_files.py",+    "handlers/open_footprint_editor.py",+    "handlers/open_symbol_editor.py",+    "handlers/place_footprint.py",+    "handlers/plugin_diagnose.py",+    "handlers/png_stdlib.py",+    "handlers/progress.py",+    "handlers/run_drc.py",+    "handlers/settings.py",+    "handlers/show.py",+    "handlers/software_opengl.py",+    "handlers/state.py",+    "handlers/uia.py",+    "handlers/uninstall.py",+    "handlers/upgrade.py",+    "handlers/win_focus.py",+    "handlers/win_menu.py",+    "handlers/win_taskbar.py",+    "install.sh",+    "kicad_detect.py",+    "launch_editor.ps1",+    "lib_table.py",+    "navigate_symbol.ps1",+    "package.json",+    "page.json",+    "parsers/__init__.py",+    "parsers/pcb.py",+    "parsers/schematic.py",+    "parsers/sexpr.py",+    "plugin_install.py",+    "plugin_payload/adom_bridge.py",+    "plugin_payload/usercustomize.py",+    "proc.py",+    "quiet_console.py",+    "resources/adom-overlay-32.png",+    "resources/adom-overlay.ico",+    "server.py",+    "start.bat",+    "start.sh",+    "templates/blank-board.kicad_pcb",+    "uninstall.sh"+  ]+}\ No newline at end of file