test_q3_release_desktop_integrity.py
python
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
9 hours ago
| 1 | """Data-integrity tests for Q3-release desktop installers (§QR.13).""" |
| 2 | |
| 3 | from __future__ import annotations |
| 4 | |
| 5 | from pathlib import Path |
| 6 | |
| 7 | from tests.fixtures.desktop_release import ( |
| 8 | GIT_SHA_FIXTURE, |
| 9 | sample_signed_artifacts, |
| 10 | write_artifact_files, |
| 11 | ) |
| 12 | from tools.desktop_release.checksums import parse_sha256sums |
| 13 | from tools.desktop_release.constants import MANIFEST_FILENAME_TEMPLATE, SHA256SUMS_FILENAME |
| 14 | from tools.desktop_release.finalize import ArtifactInput, finalize_release_artifacts |
| 15 | from tools.desktop_release.manifest import canonical_manifest_bytes, validate_manifest |
| 16 | from tools.desktop_release.version_align import check_version_alignment |
| 17 | from tests.support import KIT_ROOT |
| 18 | |
| 19 | |
| 20 | FULL_SECRETS = { |
| 21 | "APPLE_CERTIFICATE": True, |
| 22 | "APPLE_CERTIFICATE_PASSWORD": True, |
| 23 | "APPLE_ID": True, |
| 24 | "APPLE_TEAM_ID": True, |
| 25 | "APPLE_APP_SPECIFIC_PASSWORD": True, |
| 26 | "APPLE_SIGNING_IDENTITY": True, |
| 27 | "WINDOWS_CERTIFICATE": True, |
| 28 | "WINDOWS_CERTIFICATE_PASSWORD": True, |
| 29 | "LINUX_SIGNING_KEY": True, |
| 30 | } |
| 31 | |
| 32 | |
| 33 | def test_twin_manifest_byte_identical(tmp_path: Path) -> None: |
| 34 | arts = sample_signed_artifacts() |
| 35 | paths = write_artifact_files(tmp_path / "bins", arts) |
| 36 | inputs = [ |
| 37 | ArtifactInput( |
| 38 | platform=a["platform"], |
| 39 | path=p, |
| 40 | signing_status="signed", |
| 41 | signing_method=a["signing"]["method"], |
| 42 | arch=a.get("arch"), |
| 43 | ) |
| 44 | for a, p in zip(arts, paths, strict=True) |
| 45 | ] |
| 46 | out_a = tmp_path / "a" |
| 47 | out_b = tmp_path / "b" |
| 48 | m1 = finalize_release_artifacts( |
| 49 | version="0.1.0", |
| 50 | git_sha=GIT_SHA_FIXTURE, |
| 51 | artifacts=inputs, |
| 52 | output_dir=out_a, |
| 53 | publish=True, |
| 54 | secrets_present=FULL_SECRETS, |
| 55 | ) |
| 56 | m2 = finalize_release_artifacts( |
| 57 | version="0.1.0", |
| 58 | git_sha=GIT_SHA_FIXTURE, |
| 59 | artifacts=inputs, |
| 60 | output_dir=out_b, |
| 61 | publish=True, |
| 62 | secrets_present=FULL_SECRETS, |
| 63 | ) |
| 64 | assert canonical_manifest_bytes(m1) == canonical_manifest_bytes(m2) |
| 65 | name = MANIFEST_FILENAME_TEMPLATE.format(version="0.1.0") |
| 66 | assert (out_a / name).read_bytes() == (out_b / name).read_bytes() |
| 67 | |
| 68 | |
| 69 | def test_manifest_sha256_matches_sums(tmp_path: Path) -> None: |
| 70 | arts = sample_signed_artifacts() |
| 71 | paths = write_artifact_files(tmp_path / "bins", arts) |
| 72 | inputs = [ |
| 73 | ArtifactInput( |
| 74 | platform=a["platform"], |
| 75 | path=p, |
| 76 | signing_status="signed", |
| 77 | signing_method=a["signing"]["method"], |
| 78 | ) |
| 79 | for a, p in zip(arts, paths, strict=True) |
| 80 | ] |
| 81 | out = tmp_path / "dist" |
| 82 | manifest = finalize_release_artifacts( |
| 83 | version="0.1.0", |
| 84 | git_sha=GIT_SHA_FIXTURE, |
| 85 | artifacts=inputs, |
| 86 | output_dir=out, |
| 87 | publish=True, |
| 88 | secrets_present=FULL_SECRETS, |
| 89 | ) |
| 90 | parsed = parse_sha256sums((out / SHA256SUMS_FILENAME).read_text(encoding="utf-8")) |
| 91 | for entry in manifest["artifacts"]: |
| 92 | assert parsed[entry["filename"]] == entry["sha256"] |
| 93 | # Re-validate after rewrite |
| 94 | rewritten = out / MANIFEST_FILENAME_TEMPLATE.format(version="0.1.0") |
| 95 | validate_manifest(__import__("json").loads(rewritten.read_text(encoding="utf-8"))) |
| 96 | |
| 97 | |
| 98 | def test_version_align_is_pure() -> None: |
| 99 | before = { |
| 100 | p: p.read_bytes() |
| 101 | for p in ( |
| 102 | KIT_ROOT / "VERSION", |
| 103 | KIT_ROOT / "desktop" / "package.json", |
| 104 | KIT_ROOT / "desktop" / "src-tauri" / "Cargo.toml", |
| 105 | KIT_ROOT / "desktop" / "src-tauri" / "tauri.conf.json", |
| 106 | ) |
| 107 | } |
| 108 | check_version_alignment(KIT_ROOT) |
| 109 | after = {p: p.read_bytes() for p in before} |
| 110 | assert before == after |
File History
1 commit
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
9 hours ago