app
Altium - the Altium Bridge
Public Made by Adomby adom
Adom Bridge for Altium Designer: a resident DelphiScript agent gives the AI eval, the 1,100-command process launcher, all 8 EDA surfaces with screenshots, compile/ERC, DRC, OutJob outputs, native SchLib/PcbLib authoring with STEP 3D bodies, and dialog handling by PID.
← Commit history
release.py: --publish/--stage require --source <commit you pulled> and refuse unless the wiki head is that commit (checked before build, signing, upload and the stamp push). A source pushed between pull and publish shipped stale code in 0.2.52 and the stamp push overwrote that commit's CHANGELOG.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2 files changed
+35−7
PUBLISHING.md+1−1@@ -18,7 +18,7 @@ only in which manifest points at which version. ```bash python3 scripts/release.py # lint + cargo test + build, zip into dist/. Publishes nothing.-python3 scripts/release.py --publish "<one sentence for the release log>"+python3 scripts/release.py --publish "<one sentence for the release log>" --source <the commit you pulled> python3 scripts/release.py --promote <ver> --attest "<the human's exact words>" --by "<name>" python3 scripts/release.py --rollback <ver> --attest "<the human's exact words>" --by "<name>" ```
scripts/release.py+34−6@@ -80,6 +80,24 @@ def run(*a, **kw): return subprocess.run(a, check=True, **kw) +def wiki_head():+ out = subprocess.run(["adom-wiki", "repo", "log", PAGE, "--limit", "1", "--json"],+ check=True, capture_output=True, text=True).stdout+ d = json.loads(out)+ return ((d.get("data") or d).get("log") or [{}])[0].get("hash", "")+++def assert_source_is_head(source, when):+ """The working copy is a pull, and a pull records no commit, so the operator names the commit+ they pulled. Another session can push a new source between that pull and this publish; building+ then ships stale code, and the stamp push overwrites their CHANGELOG with ours."""+ head = wiki_head()+ if not source or not head.startswith(source):+ raise SystemExit(f"REFUSED ({when}): the wiki head of {PAGE} is {head[:7]}, but --source says {source or '(none)'}. "+ f"Pull again (adom-wiki repo pull {PAGE}), read what changed, and rerun with --source {head[:7]}.")+ return head++ def now_iso(): return datetime.datetime.now(datetime.timezone.utc).isoformat().replace("+00:00", "Z") @@ -371,15 +389,17 @@ def two_curl_split_check(): return served -def stage_only(log_line):+def stage_only(log_line, source): """A build waiting for a live battery: signed and uploaded as a release asset, but NO tier moves and no skills pkg row. Its manifest is archived so a later publish or pin can point at it."""+ assert_source_is_head(source, "before build") ver = json.loads((SRC / "bridge.json").read_text())["version"] lint_versions(ver) lint_agent_script() n = lint_verbs() print(f"verb lint ok: {n} verbs") build_exe()+ assert_source_is_head(source, "before signing") sign_pe_files(ver) zname, zpath, sha = build_zip(ver) subprocess.run(["adom-wiki", "release", "create", PAGE, ver, "--title", f"altium-bridge {ver}",@@ -390,15 +410,18 @@ def stage_only(log_line): print(f"STAGED {ver}: signed zip sha256 {sha[:12]} uploaded; no tier moved. Archived scripts/releases/{ver}.json.") -def ship_insiders(log_line):+def ship_insiders(log_line, source):+ assert_source_is_head(source, "before build") ver = json.loads((SRC / "bridge.json").read_text())["version"] lint_versions(ver) lint_agent_script() n = lint_verbs() print(f"verb lint ok: {n} verbs declared and dispatchable") build_exe()+ assert_source_is_head(source, "before signing") sign_pe_files(ver) zname, zpath, sha = build_zip(ver)+ assert_source_is_head(source, "before upload") print(f"== release {ver} on {PAGE} (bytes live on the product page, both tiers) ==") subprocess.run(["adom-wiki", "release", "create", PAGE, ver, "--title", f"altium-bridge {ver}",@@ -448,6 +471,7 @@ def ship_insiders(log_line): "-m", f"altium-bridge {ver} (insiders): {log_line}", cwd=work) print("== source stamps to the product page (public manifest NOT touched) ==")+ assert_source_is_head(source, "before the stamp push") run("adom-wiki", "repo", "push", PAGE, "-m", f"v{ver} (insiders): {log_line}", "--files", "CHANGELOG.md", "src/bridge.json", "src/BRIDGE_VERSION", "package.json", "page.json", "bridge-rs/src/main.rs", cwd=ROOT)@@ -518,6 +542,10 @@ def promote(ver, words, by, rollback=False): print(f"PUBLIC tier now serves {ver} ({'rollback' if rollback else 'promote'}), attested by {by}.") +def source_arg(args):+ return args[args.index("--source") + 1] if "--source" in args and len(args) > args.index("--source") + 1 else ""++ def main(): args = sys.argv[1:] if "--promote" in args:@@ -536,14 +564,14 @@ def main(): i = args.index("--publish") log_line = args[i + 1] if len(args) > i + 1 and not args[i + 1].startswith("--") else "" if not log_line:- raise SystemExit('usage: release.py --publish "<one changelog sentence for the release log>"')- ship_insiders(log_line)+ raise SystemExit('usage: release.py --publish "<one changelog sentence for the release log>" --source <commit you pulled>')+ ship_insiders(log_line, source_arg(args)) elif "--stage" in args: i = args.index("--stage") log_line = args[i + 1] if len(args) > i + 1 and not args[i + 1].startswith("--") else "" if not log_line:- raise SystemExit('usage: release.py --stage "<one line: what this staged build is for>"')- stage_only(log_line)+ raise SystemExit('usage: release.py --stage "<one line: what this staged build is for>" --source <commit you pulled>')+ stage_only(log_line, source_arg(args)) else: # lint + build only: packaging needs a signed exe, so the zip is made by --stage/--publish ver = json.loads((SRC / "bridge.json").read_text())["version"]