From d734011601ae1eecc0e3ae334b58d07e5b4d80d3 Mon Sep 17 00:00:00 2001 From: Christian Kolset Date: Tue, 11 Aug 2026 11:36:10 -0600 Subject: Finish multi-platform release restructuring (previous commit was incomplete) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git add silently staged nothing from the previous attempt because one pathspec in that batch (scripts/release/repository, already moved) no longer existed — only the .gitignore-adjacent renames landed. This commit adds what was actually meant to go in: - core/updater.py: releases/download/updates-/ instead of a single shared updates/ tag. - labui.spec: bundles root.json from this platform's own tree. - scripts/release/repo_init.py, repo_release.py: auto-detect platform, operate inside scripts/release//. - .gitignore: per-platform ignore rules (previous commit only carried the file renames, not this). - docs/building.md, scripts/release/README.md: rewritten for the per-platform flow. - Also picks up pre-existing local TUF re-signing (new snapshot/ timestamp signatures, bumped expiry/version) that was sitting uncommitted before this restructuring started. Co-Authored-By: Claude Sonnet 5 --- scripts/release/repo_init.py | 59 +++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 15 deletions(-) (limited to 'scripts/release/repo_init.py') diff --git a/scripts/release/repo_init.py b/scripts/release/repo_init.py index ccbfe17..c0360c0 100644 --- a/scripts/release/repo_init.py +++ b/scripts/release/repo_init.py @@ -1,28 +1,55 @@ """ scripts/release/repo_init.py -Run ONCE, ever, by the maintainer, locally. Generates the TUF signing keys -and the initial repository metadata (including root.json, which later gets -bundled into the app via labui.spec). +Run ONCE PER PLATFORM, by the maintainer, locally, on a machine running that +platform (no cross-compiling — build and sign Windows releases on Windows, +Linux releases on Linux/WSL2, etc.). Generates that platform's TUF signing +keys and initial repository metadata (including root.json, which later gets +bundled into that platform's build via labui.spec). -Running this again after the repo already exists is safe (tufup skips -re-creating keys/roles that already exist) but there is normally no reason -to run it more than once per project. +Every platform gets its own keystore/repository tree, under +scripts/release// — Windows and Linux builds of the same version +are different byte-for-byte archives, and TUF's metadata filenames +(root.json, timestamp.json, ...) aren't platform-prefixed, so they can't +share one repo/release without one platform silently overwriting the +other's trust root and metadata. -Keys land in ./keystore — never commit that directory (already gitignored). -Back it up somewhere safe and private; losing the root key means you can -never publish another trusted update to existing installs. +Running this again after a platform's repo already exists is safe (tufup +skips re-creating keys/roles that already exist) but there is normally no +reason to run it more than once per platform. + +Keys land in .//keystore — never commit that directory (already +gitignored). Back it up somewhere safe and private, once per platform; +losing a platform's root key means you can never publish another trusted +update to that platform's existing installs. """ import os +import sys from pathlib import Path from tufup.repo import Repository, RolesDict -# Run from this script's own directory — tufup's config file (.tufup-repo-config) -# and all repo_dir/keys_dir paths are resolved relative to the current working -# directory, so invocation location must be consistent every time. -os.chdir(Path(__file__).resolve().parent) + +def _platform_key() -> str: + """win / mac / linux — must match core.updater._platform_key() and the + "updates-" release tag on the publishing side.""" + if sys.platform.startswith("win"): + return "win" + if sys.platform == "darwin": + return "mac" + return "linux" + + +PLATFORM = _platform_key() + +# Run from this script's own platform subdirectory — tufup's config file +# (.tufup-repo-config) and all repo_dir/keys_dir paths are resolved relative +# to the current working directory, so invocation location must be +# consistent every time. +_PLATFORM_DIR = Path(__file__).resolve().parent / PLATFORM +_PLATFORM_DIR.mkdir(parents=True, exist_ok=True) +os.chdir(_PLATFORM_DIR) APP_NAME = "labui" @@ -49,8 +76,10 @@ def main(): ) repo.initialize() repo.save_config() - print(f"Initialized tufup repo for '{APP_NAME}' in ./repository, keys in ./keystore") - print("Back up ./keystore now, somewhere private and durable. It is gitignored on purpose.") + print(f"Initialized tufup repo for '{APP_NAME}' ({PLATFORM}) in " + f"{_PLATFORM_DIR / 'repository'}, keys in {_PLATFORM_DIR / 'keystore'}") + print(f"Back up {_PLATFORM_DIR / 'keystore'} now, somewhere private and " + f"durable. It is gitignored on purpose.") if __name__ == "__main__": -- cgit v1.2.3