Skip to main content

Building Releases

This guide covers building distributable versions of CSV to QLab for macOS using PyInstaller.

Intended Audience

This guide is for maintainers and contributors who need to build release versions of the GUI application. End users should download pre-built releases from GitHub Releases.

Prerequisites

System Requirements

  • macOS (for building .app bundles)
  • Python 3.8 or later
  • Git

Development Setup

  1. Clone the repository:

    git clone https://github.com/fross123/csv_to_qlab.git
    cd csv_to_qlab
  2. Create and activate virtual environment:

    python3 -m venv env
    source env/bin/activate
  3. Install dependencies:

    pip install -r requirements.txt
    pip install pyinstaller

Building with PyInstaller

Understanding application.spec

The application.spec file defines how PyInstaller bundles the application. Key sections:

Entry Point (line 6):

a = Analysis(['run_gui.py'],  # Entry point outside app/ package
Entry Point Architecture

The GUI uses run_gui.py as its entry point (located in project root), which imports the app package. This follows PyInstaller best practices for Python packages with relative imports.

Data Files (lines 9-12):

datas=[
('app/static', 'static'), # Web UI assets
('app/templates', 'templates'), # Flask templates
('app/qlab_osc_config.json', '.'), # OSC configuration (REQUIRED!)
]

Application Settings (lines 42-57):

  • name: csv-to-qlab.app
  • icon: icon.icns (must be in root directory)
  • console: False (GUI application, not terminal)
Critical Files

The qlab_osc_config.json file must be included in the bundle, or the application won't be able to send OSC messages to QLab!

Build Process

  1. Verify you're in the project root:

    pwd  # Should show .../csv_to_qlab
  2. Run PyInstaller:

    pyinstaller application.spec
  3. Build output:

    • dist/csv-to-qlab/ - Intermediate build files
    • dist/csv-to-qlab.app/ - Final macOS application bundle
  4. Build artifacts:

    • build/ - Temporary build files (can be deleted)
    • dist/ - Final application bundle

Testing the Build

Before distributing, thoroughly test the bundled application:

  1. Launch the app:

    open dist/csv-to-qlab.app
  2. Verify functionality:

    • Application launches without errors
    • All UI elements render correctly
    • File upload works
    • OSC messages send to QLab successfully
    • Error handling works properly
  3. Test with example files:

    # Use the example CSV files in app/static/example_file/
  4. Check for missing resources:

    • Look for "file not found" errors in Console.app
    • Verify all static assets load
    • Confirm templates render

Common Build Issues

Missing Icon File

Error: FileNotFoundError: icon.icns

Solution: Ensure icon.icns exists in the project root:

ls icon.icns  # Should show the file

Missing OSC Config

Symptom: Application launches but fails to send cues

Solution: Verify qlab_osc_config.json is in the bundle:

# Check bundle contents
ls dist/csv-to-qlab.app/Contents/MacOS/qlab_osc_config.json

If missing, check application.spec line 12.

Import Errors

Error: ModuleNotFoundError when running bundled app

Solution: Add missing modules to hiddenimports in application.spec:

hiddenimports=['module_name'],

Creating Distribution Packages

DMG Creation (macOS)

For official releases, package the .app into a DMG:

  1. Install create-dmg (if not already installed):

    brew install create-dmg
  2. Create DMG:

    create-dmg \
    --volname "CSV to QLab" \
    --window-pos 200 120 \
    --window-size 600 400 \
    --icon-size 100 \
    --app-drop-link 425 120 \
    "CSV-To-QLab.dmg" \
    "dist/csv-to-qlab.app"
  3. Test the DMG:

    • Mount the DMG
    • Drag app to Applications
    • Launch and verify functionality

Multi-Architecture Builds

For distributing to both Intel and Apple Silicon Macs:

Intel Mac (x86_64):

arch -x86_64 pyinstaller application.spec

Apple Silicon (ARM):

arch -arm64 pyinstaller application.spec
Build on Target Architecture

For best compatibility, build on the target architecture:

  • Build Intel version on Intel Mac (or with Rosetta)
  • Build ARM version on Apple Silicon Mac

Release Checklist

Before publishing a release:

  • All tests passing (pytest)
  • Version number updated in relevant files
  • CHANGELOG.md updated
  • Application builds without errors
  • Bundled app tested on clean macOS installation
  • Example CSV files work correctly
  • Documentation updated
  • Release notes written
  • DMG created and tested
  • GitHub release created with DMG attached

GitHub Actions (Future)

Automation Opportunity

Consider setting up GitHub Actions to automatically build releases for multiple architectures when tags are pushed. See .github/workflows/ for existing CI/CD setup.

Troubleshooting Build Issues

Clean Build

If you encounter persistent issues, try a clean build:

# Remove build artifacts
rm -rf build dist *.spec~

# Rebuild
pyinstaller application.spec

Verbose Output

For debugging build issues:

pyinstaller --log-level DEBUG application.spec

Check Dependencies

Ensure all dependencies are properly installed:

pip list | grep -E "Flask|pywebview|python-osc"

Development Workflow

For rapid development and testing:

  1. Use the source directly (not bundled):

    python run_gui.py

    Or with GUI dependencies:

    pip install -e .[gui]
    python run_gui.py
  2. Only build when:

    • Testing distribution-specific issues
    • Preparing for release
    • Verifying bundling of new resources
  3. Use editable install for CLI development:

    pip install -e .

Further Reading

Questions?

If you encounter issues building releases, please:

  1. Check this documentation
  2. Search existing issues
  3. Open a new issue with build logs