Add GPL-3.0 license, PCM packaging, and cross-platform deploy

- LICENSE.txt (GPL-3.0-or-later), declared in the new PCM v2
  metadata.json (validated against the official schema)
- tools/build_package.py builds the registry-layout addon zip in dist/
  plus the submission metadata copy with sha256/sizes and a release
  download_url derived from the Gitea homepage
- tools/deploy.py: symlink/copy deploy for Linux, macOS and Windows
- 64 px resources/icon.png for the PCM listing
- README: Linux setup/dev commands, packaging and license sections

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
janik
2026-07-15 14:55:24 +07:00
parent ffbd4a86b5
commit 4e39f598a5
7 changed files with 920 additions and 10 deletions
+109
View File
@@ -0,0 +1,109 @@
"""Build the PCM addon zip (KiCad Plugin and Content Manager).
python tools/build_package.py
Archive layout per https://dev-docs.kicad.org/en/addons/:
metadata.json package copy (must NOT carry download_* keys)
resources/icon.png 64x64 listing icon
plugins/ the IPC plugin: plugin.json, entrypoint,
fill_resistance/, icons/, requirements.txt
Writes dist/<identifier>_<version>.zip and dist/metadata-registry.json -
the submission copy for gitlab.com/kicad/addons/metadata with
download_sha256 / download_size / install_size filled in; set
download_url to the released zip before submitting. The zip also works
directly via PCM "Install from File".
"""
from __future__ import annotations
import hashlib
import json
import sys
import zipfile
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
PLUGIN_FILES = [
"plugin.json",
"fill_res_action.py",
"requirements.txt",
"LICENSE.txt",
]
PLUGIN_GLOBS = [
("fill_resistance", "*.py"),
("icons", "*.png"),
]
def collect() -> list[tuple[Path, str]]:
"""[(source path, archive name), ...] for the package zip."""
entries = [(ROOT / "metadata.json", "metadata.json"),
(ROOT / "resources" / "icon.png", "resources/icon.png")]
for name in PLUGIN_FILES:
entries.append((ROOT / name, f"plugins/{name}"))
for sub, pattern in PLUGIN_GLOBS:
for p in sorted((ROOT / sub).glob(pattern)):
entries.append((p, f"plugins/{sub}/{p.name}"))
missing = [str(src) for src, _ in entries if not src.is_file()]
if missing:
sys.exit("missing package files:\n " + "\n ".join(missing)
+ "\n(run tools/gen_icons.py for resources/icon.png)")
return entries
def main() -> int:
meta = json.loads((ROOT / "metadata.json").read_text(encoding="utf-8"))
version = meta["versions"][0]
bad = [k for k in version if k.startswith("download")]
if bad:
sys.exit(f"metadata.json must not carry {bad} - those keys belong "
f"only in the registry submission copy")
if "CHANGE-ME" in json.dumps(meta):
print("warning: metadata.json still contains CHANGE-ME placeholders")
entries = collect()
dist = ROOT / "dist"
dist.mkdir(exist_ok=True)
zip_path = dist / f"{meta['identifier']}_{version['version']}.zip"
install_size = 0
with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as z:
for src, arcname in entries:
z.write(src, arcname)
install_size += src.stat().st_size
data = zip_path.read_bytes()
sha256 = hashlib.sha256(data).hexdigest()
registry = json.loads(json.dumps(meta)) # deep copy
registry.pop("$schema", None)
# Gitea/GitHub release-asset URL convention; create the release with
# tag v<version> and attach the zip unrenamed, or fix the URL up
homepage = meta["resources"].get("homepage", "https://CHANGE-ME.example")
registry["versions"][0].update({
"download_url": (f"{homepage.rstrip('/')}/releases/download/"
f"v{version['version']}/{zip_path.name}"),
"download_sha256": sha256,
"download_size": len(data),
"install_size": install_size,
})
reg_path = dist / "metadata-registry.json"
reg_path.write_text(json.dumps(registry, indent=4) + "\n",
encoding="utf-8")
print(f"wrote {zip_path} ({len(data)} bytes, {len(entries)} files)")
print(f"wrote {reg_path}")
print(f" download_sha256: {sha256}")
print(f" download_size: {len(data)}")
print(f" install_size: {install_size}")
print("next: upload the zip, set download_url (and homepage) in "
"metadata-registry.json, then submit it as "
f"packages/{meta['identifier']}/metadata.json to "
"gitlab.com/kicad/addons/metadata")
return 0
if __name__ == "__main__":
sys.exit(main())