Skip to content

feat: GUI installers for OnTrack Python and OnTrack-RS #5

feat: GUI installers for OnTrack Python and OnTrack-RS

feat: GUI installers for OnTrack Python and OnTrack-RS #5

Workflow file for this run

name: OnTrack CI — Linux · Windows · Android
on:
push:
paths:
- "ontrack/**"
- ".github/workflows/ontrack-ci.yml"
pull_request:
paths:
- "ontrack/**"
defaults:
run:
working-directory: ontrack
# ──────────────────────────────────────────────────────────────────────────
# JOB 1: Linux x86_64 (unit tests + PyInstaller smoke build)
# ──────────────────────────────────────────────────────────────────────────
jobs:
linux:
name: "Linux x86_64"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
cache-dependency-path: ontrack/requirements.txt
- name: Install system deps (Tk + display)
run: |
sudo apt-get update -qq
sudo apt-get install -y python3-tk xvfb libgl1
- name: Install Python deps
run: pip install -r requirements.txt pytest pytest-mock pytest-cov
- name: Run unit tests (all marks)
run: |
pytest tests/ -v --tb=short \
-m "linux or android" \
--cov=core --cov=config \
--cov-report=term-missing \
--cov-report=xml:coverage-linux.xml
- name: Upload coverage
uses: actions/upload-artifact@v4
with:
name: coverage-linux
path: ontrack/coverage-linux.xml
- name: PyInstaller smoke build (no GUI window)
# Runs headless; --onefile --noconsole verifies the spec compiles.
# We use xvfb-run in case any import touches Tk at collect time.
run: |
xvfb-run --auto-servernum pyinstaller \
--onefile --noconsole \
--name ontrack-linux \
main.py
continue-on-error: true # build failure is reported, not fatal in PR
- name: Upload Linux binary
if: always()
uses: actions/upload-artifact@v4
with:
name: ontrack-linux
path: ontrack/dist/ontrack-linux
if-no-files-found: warn
# ──────────────────────────────────────────────────────────────────────────
# JOB 2: Windows 11 (unit tests + PyInstaller smoke build)
# ──────────────────────────────────────────────────────────────────────────
windows:
name: "Windows 11 (x86_64)"
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
cache-dependency-path: ontrack/requirements.txt
- name: Install Python deps
run: pip install -r requirements.txt pytest pytest-mock pytest-cov
- name: Run unit tests (windows mark)
run: |
pytest tests/ -v --tb=short `
-m "windows or linux" `
--cov=core --cov=config `
--cov-report=term-missing `
--cov-report=xml:coverage-windows.xml
- name: Upload coverage
uses: actions/upload-artifact@v4
with:
name: coverage-windows
path: ontrack/coverage-windows.xml
- name: PyInstaller smoke build
run: |
pyinstaller `
--onefile --noconsole `
--name ontrack-windows `
main.py
continue-on-error: true
- name: Upload Windows binary
if: always()
uses: actions/upload-artifact@v4
with:
name: ontrack-windows
path: ontrack/dist/ontrack-windows.exe
if-no-files-found: warn
# ──────────────────────────────────────────────────────────────────────────
# JOB 3: Android buildozer config validation (no emulator needed)
#
# This job:
# a) runs the Android-marked pytest checks (config, imports, spec)
# b) attempts a buildozer dry-run to validate the spec parses correctly
# c) does NOT produce an APK (that requires NDK ~10 GB — use self-hosted)
# ──────────────────────────────────────────────────────────────────────────
android-validate:
name: "Android config validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install test deps (no full build chain needed for config checks)
run: pip install pytest pytest-mock requests geopy pandas openpyxl python-dotenv
- name: Install buildozer (spec parsing only)
run: pip install buildozer
- name: Run Android compat checks
run: pytest tests/ -v --tb=short -m android
- name: Buildozer spec parse (dry-run)
# buildozer --help exits 0 even without NDK; what we want is that
# parsing buildozer.spec does not raise a ConfigError.
run: |
python - <<'PYEOF'
import sys
try:
from buildozer import Buildozer
b = Buildozer()
print("buildozer.spec parsed OK")
print(f" title : {b.config.get('app', 'title')}")
print(f" package : {b.config.get('app', 'package.name')}")
print(f" version : {b.config.get('app', 'version')}")
print(f" android.api: {b.config.get('app', 'android.api')}")
print(f" requirements: {b.config.get('app', 'requirements')}")
except Exception as e:
print(f"buildozer.spec parse ERROR: {e}", file=sys.stderr)
sys.exit(1)
PYEOF
- name: Summarize Android readiness
if: always()
run: |
echo "=== Android Build Readiness Summary ==="
echo ""
echo "✓ buildozer.spec parsed without errors"
echo "✓ Android compat pytest checks completed"
echo ""
echo "To perform a full APK build, run on a self-hosted runner"
echo "with the Android SDK/NDK pre-installed, or use:"
echo " buildozer android debug"
echo ""
echo "Known blockers (see test output above):"
echo " • customtkinter/Tkinter in gui/ must be replaced with Kivy"
echo " • ortools must be replaced with a p4a-compatible solver"
# ──────────────────────────────────────────────────────────────────────────
# JOB 4: Full APK build (self-hosted / manual trigger only)
#
# Uncomment and configure a self-hosted runner with Android SDK to use.
# ──────────────────────────────────────────────────────────────────────────
# android-apk:
# name: "Android APK (self-hosted)"
# runs-on: [self-hosted, linux, android-sdk]
# needs: android-validate
# if: github.event_name == 'workflow_dispatch'
# steps:
# - uses: actions/checkout@v4
# - name: Build APK
# run: buildozer android debug
# - name: Upload APK
# uses: actions/upload-artifact@v4
# with:
# name: ontrack-apk
# path: ontrack/bin/*.apk