Skip to content

Add iOS/Linux/Windows bridge example tests + bump Flutter to 3.41.7 #5

Add iOS/Linux/Windows bridge example tests + bump Flutter to 3.41.7

Add iOS/Linux/Windows bridge example tests + bump Flutter to 3.41.7 #5

name: Test bridge (no publish, no slow platform tests)
# Throwaway workflow that exercises just the new serious_python_bridge work —
# the cibuildwheel matrix, the Android NDK cross-build, and the macOS bridge
# example integration test — without triggering the slow flet_example
# platform matrix or the publish/release steps in ci.yml. Delete before
# merging to main.
on:
push:
branches: [dart-bridge]
workflow_dispatch:
jobs:
test_wheel_build:
name: cibuildwheel (${{ matrix.os }})
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04, ubuntu-24.04-arm, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Build wheels
uses: pypa/cibuildwheel@v2.21.3
with:
package-dir: src/serious_python_bridge/python
- name: List built wheels
shell: bash
run: |
ls -la wheelhouse/
echo
echo "Wheel filenames (expect cp312-abi3-<plat>):"
ls wheelhouse/*.whl
echo
echo "Wheel contents (expect dart_bridge.abi3.so):"
for whl in wheelhouse/*.whl; do
echo "--- $whl ---"
python -m zipfile -l "$whl"
done
test_android_build:
name: Android cross-build (${{ matrix.abi }})
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
abi: [arm64-v8a, armeabi-v7a, x86_64]
env:
PYTHON_VERSION: "3.12"
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download python-android-mobile-forge tarball
run: |
set -euo pipefail
VER="$PYTHON_VERSION"
ABI="${{ matrix.abi }}"
ARCHIVE="python-android-mobile-forge-${VER}.tar.gz"
curl -fL -o "$ARCHIVE" \
"https://github.com/flet-dev/python-build/releases/download/v${VER}/${ARCHIVE}"
mkdir -p pydist
tar -xzf "$ARCHIVE" -C pydist \
"install/android/${ABI}/python-${VER}.13/include/" \
"install/android/${ABI}/python-${VER}.13/lib/"
echo "Python.h candidates:"
find pydist -name "Python.h"
echo "libpython candidates:"
find pydist -name "libpython*.so"
- name: Cross-compile dart_bridge.abi3.so
run: |
set -euxo pipefail
VER="$PYTHON_VERSION"
ABI="${{ matrix.abi }}"
case "$ABI" in
arm64-v8a) TARGET=aarch64-linux-android ;;
armeabi-v7a) TARGET=armv7a-linux-androideabi ;;
x86_64) TARGET=x86_64-linux-android ;;
*) echo "unsupported ABI: $ABI" >&2 ; exit 1 ;;
esac
API=21
NDK="${ANDROID_NDK_HOME:-${ANDROID_NDK_LATEST_HOME}}"
TOOLCHAIN="$NDK/toolchains/llvm/prebuilt/linux-x86_64"
CC="$TOOLCHAIN/bin/${TARGET}${API}-clang"
test -x "$CC"
INCLUDE_DIR=$(find pydist -path "*/python-${VER}.13/include/python${VER}" | head -n1)
LIBPYTHON=$(find pydist -path "*/python-${VER}.13/lib/libpython${VER}.so" | head -n1)
test -n "$INCLUDE_DIR" -a -n "$LIBPYTHON"
OUT="dart_bridge.abi3-android-${ABI}.so"
$CC -shared -fPIC -fvisibility=hidden \
-DPy_LIMITED_API=0x030c0000 \
-I"$INCLUDE_DIR" \
-I"src/serious_python_bridge/native" \
src/serious_python_bridge/native/dart_bridge.c \
src/serious_python_bridge/native/dart_api/dart_api_dl.c \
"$LIBPYTHON" \
-Wl,-z,max-page-size=16384 \
-o "$OUT"
- name: Inspect output
run: |
ls -lh dart_bridge.abi3-android-*.so
file dart_bridge.abi3-android-*.so
test_bridge_example_macos:
name: Bridge example macOS round-trip (Python ${{ matrix.python_version }})
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
python_version: ['3.12', '3.13', '3.14']
env:
SERIOUS_PYTHON_VERSION: ${{ matrix.python_version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Flutter
uses: kuhnroyal/flutter-fvm-config-action/setup@v3
with:
path: '.fvmrc'
cache: true
- name: Package + run integration test
working-directory: "src/serious_python_bridge/example"
run: |
dart run serious_python:main package app/src --platform Darwin --python-version ${{ matrix.python_version }}
flutter test integration_test -d macos
test_bridge_example_ios:
name: Bridge example iOS round-trip (Python ${{ matrix.python_version }})
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
python_version: ['3.12', '3.13', '3.14']
env:
SERIOUS_PYTHON_VERSION: ${{ matrix.python_version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Flutter
uses: kuhnroyal/flutter-fvm-config-action/setup@v3
with:
path: '.fvmrc'
cache: true
- name: Setup iOS Simulator
id: simulator
uses: futureware-tech/simulator-action@v4
with:
model: 'iPhone 16 Pro Max'
os: "iOS"
os_version: "^18.6"
shutdown_after_job: true
wait_for_boot: true
- name: Package + run integration test
working-directory: "src/serious_python_bridge/example"
run: |
dart run serious_python:main package app/src --platform iOS --python-version ${{ matrix.python_version }}
flutter test integration_test --device-id ${{ steps.simulator.outputs.udid }}
test_bridge_example_linux:
name: Bridge example Linux ${{ matrix.title }} round-trip (Python ${{ matrix.python_version }})
runs-on: ${{ matrix.runner }}
needs: test_wheel_build
strategy:
fail-fast: false
matrix:
python_version: ['3.12', '3.13', '3.14']
include:
- arch: arm64
runner: ubuntu-24.04-arm
title: ARM64
wheel_artifact: bridge-wheels-ubuntu-24.04-arm
- arch: amd64
runner: ubuntu-24.04
title: AMD64
wheel_artifact: bridge-wheels-ubuntu-24.04
env:
SERIOUS_PYTHON_VERSION: ${{ matrix.python_version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup uv
uses: astral-sh/setup-uv@v6
- name: Get Flutter version from .fvmrc
uses: kuhnroyal/flutter-fvm-config-action/config@v3
id: fvm-config-action
with:
path: '.fvmrc'
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: ${{ steps.fvm-config-action.outputs.FLUTTER_VERSION }}
channel: ${{ matrix.arch == 'arm64' && 'master' || 'stable' }}
cache: true
- name: Install Linux desktop build deps
run: |
sudo apt-get update --allow-releaseinfo-change
sudo apt-get install -y xvfb libgtk-3-dev
if [ "${{ matrix.arch }}" = "amd64" ]; then
sudo apt-get install -y \
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly gstreamer1.0-libav
else
sudo apt-get install -y \
clang ninja-build gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly gstreamer1.0-libav
fi
- name: Download dart_bridge wheel artifact
uses: actions/download-artifact@v4
with:
name: ${{ matrix.wheel_artifact }}
path: ${{ runner.temp }}/dart_bridge_wheels
- name: Pick matching wheel for this arch
id: wheel
run: |
set -euo pipefail
WHL=$(ls "${{ runner.temp }}/dart_bridge_wheels"/dart_bridge-*manylinux*.whl | head -n1)
test -n "$WHL"
echo "path=$WHL" >> "$GITHUB_OUTPUT"
echo "Picked: $WHL"
- name: Package + run integration test
working-directory: src/serious_python_bridge/example
run: |
flutter pub get
dart run serious_python:main package app/src \
--platform Linux \
--python-version ${{ matrix.python_version }} \
--requirements ${{ steps.wheel.outputs.path }}
xvfb-run flutter test integration_test -d linux
test_bridge_example_windows:
name: Bridge example Windows round-trip (Python ${{ matrix.python_version }})
runs-on: windows-latest
needs: test_wheel_build
strategy:
fail-fast: false
matrix:
python_version: ['3.12', '3.13', '3.14']
env:
SERIOUS_PYTHON_VERSION: ${{ matrix.python_version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Flutter
uses: kuhnroyal/flutter-fvm-config-action/setup@v3
with:
path: '.fvmrc'
cache: true
- name: Download dart_bridge wheel artifact
uses: actions/download-artifact@v4
with:
name: bridge-wheels-windows-latest
path: ${{ runner.temp }}\dart_bridge_wheels
- name: Pick matching wheel
id: wheel
shell: bash
run: |
set -euo pipefail
WHL=$(ls "$RUNNER_TEMP/dart_bridge_wheels"/dart_bridge-*-win_amd64.whl | head -n1)
test -n "$WHL"
echo "path=$WHL" >> "$GITHUB_OUTPUT"
echo "Picked: $WHL"
- name: Package + run integration test
working-directory: "src/serious_python_bridge/example"
run: |
dart run serious_python:main package app/src --platform Windows --python-version ${{ matrix.python_version }} --requirements ${{ steps.wheel.outputs.path }}
flutter test integration_test -d windows