ci: add CCMA release builds

This commit is contained in:
Marcel Peterkau
2026-06-23 20:19:53 +02:00
parent 302170230a
commit 0e3087a780
16 changed files with 842 additions and 24 deletions
+100
View File
@@ -0,0 +1,100 @@
# -*- mode: python ; coding: utf-8 -*-
"""PyInstaller spec for CCMA.
Packaged output:
- Windows: dist/ccma.exe
- Linux: dist/ccma
Icon:
- On Windows the spec auto-generates build/app.ico from the PNG icon if it does
not already exist, so direct PyInstaller and scripted builds behave the same.
"""
import sys
from pathlib import Path
from PyInstaller.utils.hooks import collect_data_files
block_cipher = None
spec_dir = Path(globals().get("SPECPATH", Path.cwd())).resolve()
project_root = spec_dir.parent
entry_script = project_root / "main.py"
package_src = project_root / "src" / "ccma"
assets_src = package_src / "assets"
app_name_slug = "ccma"
win_icon_path = project_root / "build" / "app.ico"
png_icon_path = assets_src / "icons" / "ccma.png"
if sys.platform == "win32" and not win_icon_path.exists() and png_icon_path.exists():
try:
from PIL import Image
img = Image.open(png_icon_path).convert("RGBA")
win_icon_path.parent.mkdir(parents=True, exist_ok=True)
img.save(
win_icon_path,
format="ICO",
sizes=[(16, 16), (24, 24), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)],
)
print(f"[spec] Generated ICO: {win_icon_path}")
except Exception as exc:
print(f"[spec] WARNING: ICO generation failed: {exc}")
win_icon = str(win_icon_path) if win_icon_path.exists() else None
datas: list[tuple[str, str]] = []
if assets_src.exists():
datas.append((str(assets_src), "ccma/assets"))
version_file = project_root / "VERSION"
if version_file.exists():
datas.append((str(version_file), "."))
datas.append((str(version_file), "ccma"))
for optional_pkg in ("ttkbootstrap_icons", "ttkbootstrap_icons_mat"):
try:
datas += collect_data_files(optional_pkg)
except Exception:
pass
hiddenimports = ["ttkbootstrap_icons", "ttkbootstrap_icons_mat"]
a = Analysis(
[str(entry_script)],
pathex=[str(project_root), str(project_root / "src")],
binaries=[],
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name=app_name_slug,
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=win_icon,
)