allowlist.py python
53 lines 1.7 KB
Raw
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 13 hours ago
1 """Publish allowlist for GitHub Release assets (§QR.4.5)."""
2
3 from __future__ import annotations
4
5 import re
6
7 from tools.desktop_release.constants import (
8 ALLOWED_INSTALLER_SUFFIXES,
9 ALLOWED_SIDECAR_SUFFIXES,
10 MANIFEST_FILENAME_TEMPLATE,
11 SHA256SUMS_FILENAME,
12 )
13
14 _UNSIGNED_MARKERS = ("unsigned", "-unsigned", "_unsigned")
15
16
17 class AllowlistError(ValueError):
18 """Raised when a filename is not on the Auto v1 publish allowlist."""
19
20
21 _MANIFEST_RE = re.compile(r"^overseer-kit-desktop-.+-manifest\.json$")
22
23
24 def is_allowed_release_asset(filename: str, *, version: str | None = None) -> bool:
25 """Return True if ``filename`` may attach to a GitHub Release (§QR.4.5)."""
26 name = filename.strip()
27 if not name or "/" in name or "\\" in name:
28 return False
29 lower = name.lower()
30 for marker in _UNSIGNED_MARKERS:
31 if marker in lower:
32 return False
33 if name == SHA256SUMS_FILENAME:
34 return True
35 if version is not None:
36 expected = MANIFEST_FILENAME_TEMPLATE.format(version=version.strip())
37 if name == expected:
38 return True
39 elif _MANIFEST_RE.match(name):
40 return True
41 for suffix in ALLOWED_SIDECAR_SUFFIXES:
42 if name.endswith(suffix):
43 return True
44 for suffix in ALLOWED_INSTALLER_SUFFIXES:
45 if name.endswith(suffix):
46 return True
47 return False
48
49
50 def refuse_disallowed_asset(filename: str, *, version: str | None = None) -> None:
51 """Raise :class:`AllowlistError` when filename is not allowlisted."""
52 if not is_allowed_release_asset(filename, version=version):
53 raise AllowlistError(f"release asset not on allowlist: {filename!r}")
File History 1 commit
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 13 hours ago