From 87c81e9694e560e3e98b4b41eea8251e7e91dd88 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Thu, 22 Oct 2026 03:58:45 +0200 Subject: [PATCH] feat: ship the handheld port with each release build_port.py runs after split_pack.py, so RetroBIOS.zip is in the signed checksum list and uploaded with the packs. check_release.py takes the port from that list: it is no pack, so release.json does not record it. --- scripts/check_release.py | 8 ++++++-- tests/test_check_release.py | 15 +++++++++++++++ wiki/release-process.md | 5 +++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/scripts/check_release.py b/scripts/check_release.py index a3711553..018dbc16 100644 --- a/scripts/check_release.py +++ b/scripts/check_release.py @@ -3,7 +3,8 @@ Run on the draft before publishing it, and on the published release at any time. Every pack asset release.json names must be on the release at the sha256 -SHA256SUMS.txt lists for it, the parts of a pack must add up to the download +SHA256SUMS.txt lists for it, as must the handheld port (RetroBIOS.zip) when +the list names it, the parts of a pack must add up to the download size the README prints, and nothing else may be attached. An upload that failed in the loop, or a part re-uploaded from an older build, otherwise publishes a release that `sha256sum --check` rejects for every user. @@ -26,6 +27,7 @@ from dataclasses import dataclass from pathlib import Path sys.path.insert(0, os.path.dirname(__file__)) +from build_port import PORT_ZIP from check_release_assets import digests_of from largefiles import LARGE_FILES_REPO from release_record import RECORD, load_record @@ -91,7 +93,9 @@ def compare_release( findings.append(Finding("extra", name, "attached but neither recorded nor listed")) for name in sorted(set(recorded) - set(sums)): findings.append(Finding("unlisted", name, f"absent from {SUMS}")) - for name in sorted(set(sums) - set(recorded)): + # The handheld port is a release file but no pack: release.json records + # packs, and the checksum list alone vouches for the port. + for name in sorted(set(sums) - set(recorded) - {PORT_ZIP}): findings.append(Finding("unrecorded", name, f"listed in {SUMS}, absent from release.json")) wanted = {**sums, **(local_files or {})} diff --git a/tests/test_check_release.py b/tests/test_check_release.py index c4fca2a3..50a305f7 100644 --- a/tests/test_check_release.py +++ b/tests/test_check_release.py @@ -95,6 +95,21 @@ class ReleaseMatchesWhatWasBuilt(unittest.TestCase): self.assertIn(("unrecorded", "Other_BIOS_Pack.zip"), kinds) self.assertIn(("missing", "Other_BIOS_Pack.zip"), kinds) + def test_the_handheld_port_is_vouched_for_by_the_checksum_list(self): + sums = {**SUMS_LIST, "RetroBIOS.zip": A} + assets = _assets() + self.assertEqual( + _kinds(compare_release(RECORD, sums, assets, "v2026.10.10")), + {("missing", "RetroBIOS.zip")}, + ) + assets["RetroBIOS.zip"] = Asset(70, A) + self.assertEqual(compare_release(RECORD, sums, assets, "v2026.10.10"), []) + assets["RetroBIOS.zip"] = Asset(70, B) + self.assertEqual( + _kinds(compare_release(RECORD, sums, assets, "v2026.10.10")), + {("content", "RetroBIOS.zip")}, + ) + def test_parts_must_add_up_to_the_printed_download_size(self): assets = _assets() assets["Big_BIOS_Pack.part2of2.zip"] = Asset(99, B) diff --git a/wiki/release-process.md b/wiki/release-process.md index 864fb59c..d0a8bcd8 100644 --- a/wiki/release-process.md +++ b/wiki/release-process.md @@ -202,6 +202,11 @@ python scripts/pipeline.py --include-archived # and the set compared with the pack before the pack is removed. python scripts/split_pack.py dist/ +# 2b. The handheld port, RetroBIOS.zip, built from ports/RetroBIOS with the +# installer the bootstraps pin. It is a release file, listed in the +# checksums below, and check_release.py holds it to them. +python scripts/build_port.py + # 3. Checksums of the files as published, then sign the list. The checksums # answer corruption, and the signature answers a rewritten release, which is # the one thing a checksum published beside its own artifacts cannot