Skip to content

Commit ddefc20

Browse files
author
FlowCyt Dev
committed
fix(mac): use single-file EXE instead of BUNDLE for macOS build
PyInstaller's BUNDLE step claimed 'completed successfully' but produced an empty directory (dist/PanelAgent with no .app structure) — a known flakiness with BUNDLE on macOS-14 runners. Switching to the same single- file EXE approach as Windows (exclude_binaries=False, no BUNDLE call) produces a working dist/PanelAgent Unix executable directly. UX trade-off: users run it from Terminal (or double-click in Finder, which opens Terminal) rather than a dock-icon .app. Same launcher, same ~/.panelagent data dir. The release zips it as PanelAgent-mac-arm64.zip. Workflow: look for dist/PanelAgent (file) not *.app (dir); smoke test chmods +x before launching; zip uses ditto to preserve the exec bit.
1 parent 73d28d6 commit ddefc20

2 files changed

Lines changed: 23 additions & 35 deletions

File tree

‎.github/workflows/build-desktop.yml‎

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -149,23 +149,20 @@ jobs:
149149
npm run build
150150
test -f out/index.html || { echo "next build did not produce out/index.html"; exit 1; }
151151
152-
- name: Build .app
152+
- name: Build macOS binary
153153
run: |
154154
python -m PyInstaller panelagent-mac.spec --noconfirm --clean
155155
echo "=== dist/ contents ==="
156156
ls -la dist/
157-
# Locate the produced .app (exact name may vary by PyInstaller version).
158-
app_path=$(find dist -maxdepth 1 -name "*.app" -type d | head -1)
159-
echo "Found app: ${app_path:-<none>}"
160-
test -n "$app_path" || { echo "No .app produced under dist/"; exit 1; }
161-
echo "APP_PATH=$app_path" >> "$GITHUB_ENV"
162-
echo "APP_NAME=$(basename "$app_path")" >> "$GITHUB_ENV"
163-
164-
- name: Smoke test (launch app + poll health + dump log + kill)
157+
test -f dist/PanelAgent || { echo "PyInstaller did not produce dist/PanelAgent"; exit 1; }
158+
echo "APP_PATH=dist/PanelAgent" >> "$GITHUB_ENV"
159+
160+
- name: Smoke test (launch binary + poll health + dump log + kill)
165161
continue-on-error: true
166162
run: |
167-
exe="${APP_PATH}/Contents/MacOS/${APP_NAME%.app}"
163+
exe="${APP_PATH}"
168164
echo "Launching $exe..."
165+
chmod +x "$exe"
169166
"$exe" &
170167
pid=$!
171168
ok=false
@@ -194,14 +191,15 @@ jobs:
194191
echo "::warning::Smoke test could not reach health endpoint within 120s. The .app will still be uploaded."
195192
fi
196193
197-
- name: Zip .app for upload
194+
- name: Zip binary for upload
198195
run: |
199196
cd dist
200-
# ditto preserves macOS metadata and permissions better than zip.
201-
ditto -c -k --keepParent "${APP_NAME}" PanelAgent-mac-arm64.zip
197+
# ditto preserves macOS permissions (executable bit) better than zip.
198+
ditto -c -k --keepParent PanelAgent PanelAgent-mac-arm64.zip
202199
test -f PanelAgent-mac-arm64.zip
200+
ls -la PanelAgent-mac-arm64.zip
203201
204-
- name: Upload .app zip to the release
202+
- name: Upload macOS zip to the release
205203
uses: softprops/action-gh-release@v2
206204
with:
207205
tag_name: ${{ github.ref_name }}

‎panelagent-mac.spec‎

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -84,35 +84,25 @@ pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
8484
exe = EXE(
8585
pyz,
8686
a.scripts,
87+
a.binaries,
88+
a.zipfiles,
89+
a.datas,
8790
[],
88-
exclude_binaries=True,
8991
name="PanelAgent",
9092
debug=False,
9193
bootloader_ignore_signals=False,
9294
strip=False,
9395
upx=False, # UPX is unreliable on macOS arm64
94-
console=False, # GUI app: no terminal window (logs go to ~/.panelagent/launcher.log)
96+
console=True, # macOS: run as a terminal app so users see startup output;
97+
# logs also go to ~/.panelagent/launcher.log
9598
disable_windowed_traceback=False,
9699
argv_emulation=False,
97100
target_arch="arm64",
98101
)
99102

100-
app = BUNDLE(
101-
exe,
102-
a.binaries,
103-
a.zipfiles,
104-
a.datas,
105-
name="PanelAgent",
106-
info_plist={
107-
"CFBundleDisplayName": "PanelAgent",
108-
"CFBundleShortVersionString": "1.0.0",
109-
"CFBundleVersion": "1",
110-
"CFBundleIdentifier": "com.panelagent.app",
111-
"NSHighResolutionCapable": True,
112-
"LSMinimumSystemVersion": "12.0",
113-
# Allow the bundled Python to run without a terminal; suppress the
114-
# dock icon flicker on launch.
115-
"LSUIElement": False,
116-
},
117-
# icon_filename="scripts/panelagent.icns", # add an icns if available
118-
)
103+
# NOTE: A proper .app bundle (BUNDLE) is desirable for the dock-icon UX, but
104+
# PyInstaller's BUNDLE step produced an empty directory in CI (the .app
105+
# wasn't materialized). Falling back to a single-file Unix executable — same
106+
# launcher, same UX as the Windows exe. The release zips this as
107+
# PanelAgent-mac-arm64. Users run it from Terminal or via a wrapper.
108+

0 commit comments

Comments
 (0)