From bf9e11d08f13892b7129b16e4b67b2f77613b879 Mon Sep 17 00:00:00 2001 From: oop7 <110548351+oop7@users.noreply.github.com> Date: Tue, 3 Feb 2026 14:41:19 +0200 Subject: [PATCH] macOS build: trim .app bundle and packaging tweaks Improve macOS CI packaging by trimming unnecessary files from the built .app and adjusting build options. Changes include: - Enable cx_Freeze silent build and run Python with -OO for bdist_mac. - Add zip_include_packages to ensure key packages are bundled inside zip distributions. - Exclude additional stdlib modules (pydoc, doctest, email) to reduce size. - New workflow step to locate the generated .app and remove screenshots, Qt translations, unused PySide6 plugins and other Qt artifacts (Qt6Web*, Qt6Pdf*), with safer path detection and logging. - Remove noisy post-build directory listings and simplify DMG handling/log messages; make .app and .dmg discovery more robust. These changes aim to produce smaller, cleaner artifacts and more reliable CI packaging for macOS builds. --- .github/workflows/build-macos.yml | 87 +++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index e07755e..8ba0b6a 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -95,6 +95,7 @@ jobs: build_exe_options = dict( optimize=2, + silent=True, packages=[ "ytsage", "PySide6.QtCore", @@ -109,6 +110,13 @@ jobs: "loguru", "setuptools", ], + zip_include_packages=[ + "PySide6", + "shiboken6", + "requests", + "PIL", + "packaging", + ], excludes=[ "PySide6.QtBluetooth", "PySide6.QtOpenGL", @@ -132,6 +140,9 @@ jobs: "unittest", "test", "tests", + "pydoc", + "doctest", + "email", ], include_files=[ ("ytsage/assets/Icon", "lib/assets/Icon"), @@ -162,7 +173,6 @@ jobs: "bdist_dmg": { "volume_label": f"YTSage v{version}", "applications_shortcut": True, - # Sensible defaults; can be customized later if desired "format": "UDZO", "filesystem": "HFS+", "default_view": "icon-view", @@ -176,31 +186,67 @@ jobs: shell: bash run: | source venv/bin/activate - python setup_cxfreeze.py bdist_mac - # Locate the built .app (cx_Freeze may place it under build/ or dist/) + python -OO setup_cxfreeze.py bdist_mac + + - name: Trim unnecessary files from App bundle + shell: bash + run: | + version="${{ steps.get_version.outputs.VERSION }}" + + # Locate the built .app app_path="" - for cand in "dist/YTSage-v${VERSION}.app" "build/dist/YTSage-v${VERSION}.app" "build/YTSage-v${VERSION}.app"; do + for cand in "dist/YTSage-v${version}.app" "build/dist/YTSage-v${version}.app" "build/YTSage-v${version}.app"; do if [ -d "$cand" ]; then app_path="$cand"; break; fi done if [ -z "$app_path" ]; then app_path=$(ls -d dist/*.app build/dist/*.app build/*.app 2>/dev/null | head -n1 || true) fi - if [ -n "$app_path" ] && [ -d "$app_path/Contents/Resources/lib/assets/branding/screenshots" ]; then - rm -rf "$app_path/Contents/Resources/lib/assets/branding/screenshots" - echo "Removed screenshots folder from .app bundle at $app_path" + + if [ -n "$app_path" ]; then + echo "Processing App Bundle at: $app_path" + + # 1. Remove screenshots + if [ -d "$app_path/Contents/Resources/lib/assets/branding/screenshots" ]; then + rm -rf "$app_path/Contents/Resources/lib/assets/branding/screenshots" + echo "Removed screenshots folder" + fi + + # 2. Remove unused Qt translations + # In macOS .app, Qt libs might be in Contents/MacOS/PySide6 or similar + # Search for translations folder within the app bundle + translations=$(find "$app_path" -type d -name "translations" | grep "PySide6" || true) + if [ -n "$translations" ]; then + rm -rf "$translations" + echo "Removed Qt translations at $translations" + fi + + # 3. Remove unused Qt plugins (matching Windows logic) + plugins_dir=$(find "$app_path" -type d -name "plugins" | grep "PySide6" | head -n1 || true) + if [ -n "$plugins_dir" ]; then + echo "Cleaning plugins in $plugins_dir" + for plugin in designer pdf svg sql help qml quick webengine bluetooth opengl printsupport test xml; do + if [ -d "$plugins_dir/$plugin" ]; then + rm -rf "$plugins_dir/$plugin" + echo "Removed plugin: $plugin" + fi + done + fi + + # 4. Remove other unused components if found + find "$app_path" -name "Qt6Web*" -delete + find "$app_path" -name "Qt6Pdf*" -delete + echo "Cleaned additional Qt files" + + else + echo "Error: Could not find .app bundle to trim!" + exit 1 fi - echo "Post-bdist_mac directory listing:" - echo "-- dist --"; ls -lah dist || true - echo "-- build --"; ls -lah build || true - name: Build DMG (bdist_dmg) shell: bash run: | source venv/bin/activate python setup_cxfreeze.py bdist_dmg - echo "Post-bdist_dmg directory listing:" - echo "-- dist --"; ls -lah dist || true - echo "-- build --"; ls -lah build || true - name: Package and prepare release artifacts (.app.zip and .dmg) shell: bash @@ -209,7 +255,7 @@ jobs: echo "Preparing artifacts for version: $version" mkdir -p artifacts - # Find the .app bundle (preferring versioned name) + # Find the .app bundle app_path="" for cand in "dist/YTSage-v${version}.app" "build/dist/YTSage-v${version}.app" "build/YTSage-v${version}.app"; do if [ -d "$cand" ]; then app_path="$cand"; break; fi @@ -217,21 +263,17 @@ jobs: if [ -z "$app_path" ]; then app_path=$(ls -d dist/*.app build/dist/*.app build/*.app 2>/dev/null | head -n1 || true) fi + if [ -n "$app_path" ] && [ -d "$app_path" ]; then app_base="$(basename "$app_path")" app_parent="$(dirname "$app_path")" - # Ensure screenshots folder is not shipped - if [ -d "$app_path/Contents/Resources/lib/assets/branding/screenshots" ]; then - rm -rf "$app_path/Contents/Resources/lib/assets/branding/screenshots" - echo "Removed screenshots folder from .app bundle at $app_path" - fi (cd "$app_parent" && zip -r "${GITHUB_WORKSPACE}/artifacts/YTSage-v${version}-${ARCH_SUFFIX}.app.zip" "$app_base") echo "Created: artifacts/YTSage-v${version}-${ARCH_SUFFIX}.app.zip" else echo "Warning: .app bundle not found in dist/ or build/" fi - # Try to find the generated DMG in dist or build + # Try to find the generated DMG dmg_src="" for cand in "dist/YTSage-v${version}.dmg"; do if [ -f "$cand" ]; then dmg_src="$cand"; break; fi @@ -241,11 +283,10 @@ jobs: fi if [ -n "$dmg_src" ] && [ -f "$dmg_src" ]; then - # Rename the DMG to a consistent name in artifacts cp "$dmg_src" "artifacts/YTSage-v${version}-${ARCH_SUFFIX}.dmg" - echo "Copied DMG to artifacts from $dmg_src -> artifacts/YTSage-v${version}-${ARCH_SUFFIX}.dmg" + echo "Copied DMG to artifacts" else - echo "Warning: No DMG found in dist/ or build/" + echo "Warning: No DMG found" fi echo "Final artifacts:"