A minimal, cross-platform GUI application written in Python using BeeWare/Toga.
toga-hello/
├── .github/
│ └── workflows/
│ └── release.yml # CI/CD for cross-platform builds
├── icons/
│ └── README.md # Icon requirements
├── src/
│ └── helloworld/
│ ├── **init**.py # Package marker
│ ├── **main**.py # Execution entry point
│ └── app.py # Main application logic
├── tests/
│ └── **init**.py
├── https://www.google.com/search?q=LICENSE
├── pyproject.toml # Briefcase configuration
└── README.md
This project relies on GTK bindings. Note: Ubuntu 24.04 and Linux Mint 22 have moved to girepository-2.0. You must install the correct development headers for local testing:
sudo apt update
sudo apt install -y git python3-dev python3-venv \
libgirepository-2.0-dev \
libcairo2-dev gir1.2-gtk-3.0 pkg-config
Legacy Systems: If you are on Ubuntu 22.04 or older, use
libgirepository1.0-devinstead.
See BeeWare documentation for platform-specific requirements.
- Create and activate a virtual environment:
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
- Install Briefcase (The packaging tool):
pip install briefcase
- Install the project in editable mode:
This ensures
briefcasecan find your code logic insrc/.
pip install -e .
This emulates the full packaging environment.
briefcase dev
Since this is a standard Python package, you can run it as a module:
python -m helloworld
To bundle this application for distribution locally, use briefcase.
# Linux AppImage (Portable single-file executable)
# Note: Uses manylinux_2_34 (AlmaLinux 9) Docker image
briefcase create linux appimage
briefcase build linux appimage
briefcase package linux appimage
# Windows (Must run on Windows)
briefcase create windows app
briefcase build windows app
briefcase package windows app
# macOS (Must run on macOS)
briefcase create macOS app
briefcase build macOS app
# For ad-hoc signing (runs locally only):
briefcase package macOS app --adhoc-sign
# For distribution (requires Developer ID):
# briefcase package macOS app --identity "Developer ID Application: ..."
# Android (Requires Android SDK - Briefcase handles this)
briefcase create android
briefcase build android
briefcase package android
# iOS (Requires macOS + Xcode)
briefcase create iOS
briefcase build iOS
briefcase package iOS
This repository includes a GitHub Action (.github/workflows/release.yml) that automatically builds binaries whenever you push a version tag.
- Commit your changes:
git add .
git commit -m "Your commit message"
git push origin main
- Trigger a release:
git tag -f v0.1.0
git push -f origin v0.1.0
The workflow builds and uploads the following artifacts:
- Linux:
.AppImage(portable) - Windows:
.msiinstaller - macOS:
.dmgdisk image (Signed if secrets are present, otherwise ad-hoc) - Android: Debug
.apk - iOS:
.ipa(if signed) or Xcode archive.tar.gz(unsigned)
Creating a portable AppImage for GTK apps requires a specific balance between the Build OS version and the Python Library versions.
The working configuration in pyproject.toml uses manylinux_2_34 (AlmaLinux 9) to provide modern GLib (2.68+), while strictly pinning pygobject to avoid the bleeding-edge girepository-2.0 requirement.
Do not change these versions unless you verify compatibility:
[tool.briefcase.app.helloworld.linux]
requires = [
"toga-gtk>=0.4.0,<0.4.5", # Stable Toga series
"pygobject>=3.46.0,<3.48.0", # Pinned to support GLib 2.68 but avoid girepository-2.0
]
[tool.briefcase.app.helloworld.linux.appimage]
manylinux = "manylinux_2_34" # AlmaLinux 9 build environment
system_requires = [
"fuse-libs", # Red Hat package name (not libfuse2)
"cairo-devel",
"cairo-gobject-devel",
"gobject-introspection-devel",
]
To enable production-grade signing in GitHub Actions, configure the following secrets in Settings > Secrets and variables > Actions:
| Secret Name | Description |
|---|---|
APPLE_DEVELOPER_ID_CERTIFICATE |
Base64-encoded .p12 certificate file. |
APPLE_DEVELOPER_ID_CERTIFICATE_PASSWORD |
Password for the .p12 file. |
APPLE_DEVELOPER_ID |
Your Apple Developer ID (e.g., Developer ID Application: Name (ID)). |
KEYCHAIN_PASSWORD |
A random string used to secure the temporary CI keychain. |
APPLE_TEAM_ID |
Your 10-character Apple Team ID (required for iOS). |
Without these secrets, macOS builds will be ad-hoc signed (requiring manual Gatekeeper override) and iOS builds will produce an unsigned Xcode archive.
MIT License - see LICENSE for details.