diff --git a/tests/test_content_packs_vst.py b/tests/test_content_packs_vst.py index 8204f8c9..f1071d03 100644 --- a/tests/test_content_packs_vst.py +++ b/tests/test_content_packs_vst.py @@ -89,3 +89,30 @@ def test_unknown_platform_rejected(tmp_path): assert "unknown platform" in str(e) else: raise AssertionError("build_vst_pack accepted an unknown platform") + + +def test_repo_flag_reaches_both_publish_target_and_manifest_url(tmp_path, monkeypatch): + # Load-bearing invariant: --repo must reach BOTH the upload target and the URL + # written into the manifest. If it reaches only one, a pack is downloaded from + # a repo it was never uploaded to → every client 404s. Capture the publish + # repo and assert the emitted manifest URL points at the same one. + import json + + root = tmp_path / "vst" + _fake_vst_tree(root) + published_to = [] + monkeypatch.setattr( + content_packs, "_publish_release", + lambda tag, zip_path, title, notes, repo=content_packs.REPO: published_to.append(repo)) + + manifest_path = tmp_path / "manifest.json" + rc = content_packs.main([str(root), "--vst", "--publish", + "--repo", "acme/widgets", "--manifest", str(manifest_path)]) + assert rc == 0 + manifest = json.loads(manifest_path.read_text()) + + # Uploaded to acme/widgets for every platform... + assert set(published_to) == {"acme/widgets"}, published_to + # ...and every manifest URL points at that same repo (not the default core). + for plat, entry in manifest.items(): + assert "/acme/widgets/releases/download/" in entry["url"], (plat, entry["url"]) diff --git a/tools/content_packs.py b/tools/content_packs.py index 759905bc..d428e768 100644 --- a/tools/content_packs.py +++ b/tools/content_packs.py @@ -201,6 +201,12 @@ def main(argv=None) -> int: help="slice one rig VST root (src[0]) into per-platform " "vst--v packs; manifest keyed by platform " "(the shape rig_builder's data/vst_packs.json wants)") + ap.add_argument("--repo", default=REPO, + help=f"GitHub repo to publish releases to AND reference in the " + f"emitted manifest URLs (default {REPO}). The upload " + f"target and the URL always use this same repo — a pack " + f"is downloaded from whatever the manifest says, so they " + f"must not diverge.") ap.add_argument("--manifest", type=Path, help="write the {id: {url,sha256,bytes}} map here (default: stdout)") ap.add_argument("--selfcheck", action="store_true", help="run the round-trip demo and exit") @@ -219,10 +225,13 @@ def main(argv=None) -> int: zip_path = out_dir / vst_asset(plat, args.version) build_vst_pack(vst_root, zip_path, plat) if args.publish: + # --repo MUST reach both, or the manifest advertises a repo the + # asset was never uploaded to (every client download 404s). _publish_release(vst_tag(plat, args.version), zip_path, f"Rig VST pack ({plat}) v{args.version}", - "Opt-in per-platform rig VST pack. Not a code release.") - url = vst_url(plat, args.version) + "Opt-in per-platform rig VST pack. Not a code release.", + args.repo) + url = vst_url(plat, args.version, args.repo) else: url = (out_dir.resolve() / zip_path.name).as_uri() manifest[plat] = manifest_entry(zip_path, url) @@ -232,8 +241,8 @@ def main(argv=None) -> int: zip_path = out_dir / pack_asset(pid, args.version) build_pack(src, zip_path) if args.publish: - publish(pid, args.version, zip_path) - url = pack_url(pid, args.version) + publish(pid, args.version, zip_path, args.repo) + url = pack_url(pid, args.version, args.repo) else: url = (out_dir.resolve() / zip_path.name).as_uri() manifest[pid] = manifest_entry(zip_path, url)