feat(update): add verifiable release manifest

This commit is contained in:
chengma
2026-07-13 11:58:05 +08:00
parent d4a3df4df0
commit 567d4e7b68
7 changed files with 281 additions and 17 deletions
+58
View File
@@ -1,6 +1,11 @@
import hashlib
import json
import tempfile
import unittest
from pathlib import Path
from _helpers import REPO_ROOT
from app import release_manifest
from app import version
@@ -88,6 +93,59 @@ class PackagingTests(unittest.TestCase):
self.assertIn('Compress-ArchiveWithRetry', script)
self.assertIn('Start-Sleep -Seconds $DelaySeconds', script)
self.assertIn('Assert-NoExcludedData -Root $releaseDir', script)
self.assertIn('-m app.release_manifest manifest', script)
self.assertIn('-m app.release_manifest metadata', script)
self.assertIn('release-metadata.json', script)
def make_release_dir(self, root, app_version="1.2.3"):
release_dir = Path(root) / "release"
(release_dir / "_internal").mkdir(parents=True)
(release_dir / "cmshopee.exe").write_bytes(b"exe")
(release_dir / "_internal" / "runtime.dll").write_bytes(b"runtime")
(release_dir / "version.txt").write_text(app_version, encoding="ascii")
(release_dir / "README.txt").write_text("说明", encoding="utf-8")
return release_dir
def test_release_manifest_covers_program_files_with_hashes(self):
with tempfile.TemporaryDirectory() as temp_dir:
release_dir = self.make_release_dir(temp_dir)
output = release_manifest.write_package_manifest(release_dir, "1.2.3")
manifest = json.loads(output.read_text(encoding="utf-8"))
self.assertEqual("cmshopee-portable-v1", manifest["package_format"])
self.assertEqual("1.2.3", manifest["app_version"])
self.assertEqual("cmshopee.exe", manifest["entry_point"])
paths = [item["path"] for item in manifest["files"]]
self.assertEqual(len(paths), len(set(path.casefold() for path in paths)))
self.assertNotIn("package-manifest.json", paths)
self.assertIn("_internal/runtime.dll", paths)
exe = next(item for item in manifest["files"] if item["path"] == "cmshopee.exe")
self.assertEqual(3, exe["size_bytes"])
self.assertEqual(hashlib.sha256(b"exe").hexdigest(), exe["sha256"])
def test_release_manifest_rejects_user_data_and_version_mismatch(self):
with tempfile.TemporaryDirectory() as temp_dir:
release_dir = self.make_release_dir(temp_dir)
(release_dir / "data").mkdir()
with self.assertRaises(release_manifest.ReleaseManifestError):
release_manifest.build_package_manifest(release_dir, "1.2.3")
(release_dir / "data").rmdir()
with self.assertRaises(release_manifest.ReleaseManifestError):
release_manifest.build_package_manifest(release_dir, "9.9.9")
def test_release_metadata_matches_zip_size_and_hash(self):
with tempfile.TemporaryDirectory() as temp_dir:
zip_path = Path(temp_dir) / "蝦皮圈優化助手1.2.3.zip"
zip_path.write_bytes(b"portable-zip")
metadata = release_manifest.build_release_metadata(zip_path, "1.2.3")
release = metadata["release"]
self.assertEqual(zip_path.stat().st_size, release["size_bytes"])
self.assertEqual(
hashlib.sha256(b"portable-zip").hexdigest(), release["sha256"]
)
self.assertEqual("cmshopee-portable-v1", release["package_format"])
if __name__ == "__main__":