Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/workflows/macbuild.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# macOS CI — builds a .app bundle and packages it as a .dmg
name: MacOS CI

on:
push:
branches:
- '*'
pull_request:
branches:
- '*'

jobs:
build:
runs-on: macos-latest # arm64 (Apple Silicon)

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'

- name: Build macOS App
run: bash macbuild.sh

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: DMG Package
path: dist/*.dmg
Binary file added icons/logo.icns
Binary file not shown.
37 changes: 37 additions & 0 deletions macbuild.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash
# macOS build script for DroneCAN GUI Tool
# Produces a .app bundle and a .dmg installer in the dist/ folder.
# Requirements: Python 3.9+

set -e

python3 --version

# Create and activate a clean virtual environment
python3 -m venv venv
source venv/bin/activate

python3 -m pip install -U pip
python3 -m pip install -U py2app
python3 -m pip install -U pymavlink
python3 -m pip install -U python-can
python3 -m pip install -U .

APP_NAME="DroneCAN GUI Tool"

# Clean previous build artifacts
rm -rf build dist

# Build the .app bundle with py2app
python3 setup_mac.py py2app

# Package the .app into a .dmg
hdiutil create \
-volname "${APP_NAME}" \
-srcfolder "dist/${APP_NAME}.app" \
-ov \
-format UDZO \
"dist/DroneCAN_GUI_Tool.dmg"
Comment on lines +29 to +34

Copilot AI Mar 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DMG packaging step references dist/${APP_NAME}.app, but py2app names the output bundle directory from the entry script basename (bin/dronecan_gui_tool), so the generated bundle path will be dist/dronecan_gui_tool.app by default. This will cause the hdiutil create step to fail in CI unless the source folder path is updated (or the py2app config is changed to emit the expected bundle name).

Copilot uses AI. Check for mistakes.

echo "Build complete. Artifact: dist/DroneCAN_GUI_Tool.dmg"
ls -lh dist/
57 changes: 57 additions & 0 deletions setup_mac.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""
py2app build configuration for macOS .app bundle.
Usage: python3 setup_mac.py py2app
"""
import os
import site

PACKAGE_NAME = 'dronecan_gui_tool'
APP_NAME = 'DroneCAN GUI Tool'

# Locate the dronecan dsdl_specs data files
site_packages = site.getsitepackages()[0]
dsdl_specs = os.path.join(site_packages, 'dronecan', 'dsdl_specs')

OPTIONS = {
'argv_emulation': False,
'packages': [
PACKAGE_NAME,
'dronecan',
'qtwidgets',
'pyqtgraph',
'qtawesome',
'qtconsole',
'ipykernel',
'jupyter_client',
'zmq',
'pygments',
'traitlets',
],
'includes': [
'PyQt5',
'PyQt5.QtCore',
'PyQt5.QtGui',
'PyQt5.QtWidgets',
'PyQt5.QtSvg',
'PyQt5.QtPrintSupport',
'PyQt5.QtSerialPort',
],
'resources': [dsdl_specs],
'iconfile': 'icons/logo.icns',
'plist': {
'CFBundleName': APP_NAME,
'CFBundleDisplayName': APP_NAME,
'CFBundleIdentifier': 'org.dronecan.gui-tool',
'NSHighResolutionCapable': True,
},
}

from setuptools import setup

setup(
name=APP_NAME,
app=['bin/dronecan_gui_tool'],
options={'py2app': OPTIONS},
setup_requires=['py2app'],
data_files=[('icons', ['icons/logo.icns'])],
)
Loading