From db577b4a340bf4fd2217f7d198b5f7be943bbeb3 Mon Sep 17 00:00:00 2001 From: MiniRML <134226498+MiniRML@users.noreply.github.com> Date: Mon, 12 Oct 2026 09:29:03 -0700 Subject: [PATCH] fix(release): preflight asset destination types --- tools/package_release.py | 7 ++++++- tools/tests/test_package_release.py | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/tools/package_release.py b/tools/package_release.py index 52f0b3ffc..09ac2b73f 100644 --- a/tools/package_release.py +++ b/tools/package_release.py @@ -26,8 +26,13 @@ def package(platform, build, output, version): for file in [*files, binary]: if not file.is_file() or file.stat().st_size == 0: raise RuntimeError(f"Missing or empty release file: {file}") - output.mkdir(parents=True, exist_ok=True) asset = f"relinker-{version}.exe" if platform == "windows" else f"relinker-{version}" + names = (f"prx-{platform}-{version}.zip", f"prx-{platform}-{version}.tar.gz", asset) + for name in names: + destination = output / name + if destination.exists() and not destination.is_file(): + raise RuntimeError(f"Release destination is not a file: {destination}") + output.mkdir(parents=True, exist_ok=True) with tempfile.TemporaryDirectory(prefix=".release-", dir=output) as temporary: staging = Path(temporary) with zipfile.ZipFile(staging / f"prx-{platform}-{version}.zip", "w", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as archive: diff --git a/tools/tests/test_package_release.py b/tools/tests/test_package_release.py index a969a1692..5d0a87c80 100644 --- a/tools/tests/test_package_release.py +++ b/tools/tests/test_package_release.py @@ -89,6 +89,30 @@ class ReleasePackageTests(unittest.TestCase): with working_directory(self.source), self.assertRaisesRegex(RuntimeError, "Missing patched libraries"): package_release.package("linux", self.build, self.output, "v1.0") + def test_directory_destination_preserves_every_existing_asset(self): + names = ["prx-linux-v1.zip", "prx-linux-v1.tar.gz", "relinker-v1"] + for blocked in names: + with self.subTest(blocked=blocked), tempfile.TemporaryDirectory() as tmp: + output = Path(tmp) + for name in names: + destination = output / name + if name == blocked: + destination.mkdir() + (destination / "keep.txt").write_bytes(b"directory content") + else: + destination.write_bytes(b"old " + name.encode()) + (output / "unrelated.txt").write_bytes(b"unrelated") + with self.assertRaises((OSError, RuntimeError)): + package_release.package("linux", self.build, output, "v1") + self.assertEqual(sorted(path.name for path in output.iterdir()), sorted(names + ["unrelated.txt"])) + for name in names: + destination = output / name + if name == blocked: + self.assertEqual((destination / "keep.txt").read_bytes(), b"directory content") + else: + self.assertEqual(destination.read_bytes(), b"old " + name.encode()) + self.assertEqual((output / "unrelated.txt").read_bytes(), b"unrelated") + def test_invalid_tag_creates_no_assets(self): with self.assertRaises(ValueError): package_release.package("linux", self.build, self.output, "../v1.0")