Skip to content

TODO/WIP/draft 👷 Runtime test the app from the CI #2296

TODO/WIP/draft 👷 Runtime test the app from the CI

TODO/WIP/draft 👷 Runtime test the app from the CI #2296

Workflow file for this run

name: Unit tests & build apps
on: ['push', 'pull_request']
env:
APK_ARTIFACT_FILENAME: bdist_unit_tests_app-debug-1.1.apk
AAB_ARTIFACT_FILENAME: bdist_unit_tests_app-release-1.1.aab
AAR_ARTIFACT_FILENAME: bdist_unit_tests_app-release-1.1.aar
PYTHONFORANDROID_PREREQUISITES_INSTALL_INTERACTIVE: 0
concurrency:
group: build-${{ github.ref }}
cancel-in-progress: true
jobs:
flake8:
name: Flake8 tests
runs-on: ubuntu-latest
# TODO: temporarily disabled for debugging purpose
if: false
steps:
- name: Checkout python-for-android
uses: actions/checkout@v4
- name: Set up Python 3.x
uses: actions/setup-python@v5
with:
python-version: 3.x
- name: Run flake8
run: |
python -m pip install --upgrade pip
pip install tox>=2.0
tox -e pep8
test:
name: Pytest [Python ${{ matrix.python-version }} | ${{ matrix.os }}]
needs: flake8
runs-on: ${{ matrix.os }}
# TODO: temporarily disabled for debugging purpose
if: false
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']
os: [ubuntu-latest, macOs-latest]
steps:
- name: Checkout python-for-android
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Tox tests
run: |
python -m pip install --upgrade pip
pip install tox>=2.0
make test
- name: Coveralls
uses: AndreMiras/coveralls-python-action@develop
if: ${{ matrix.os == 'ubuntu-latest' }}
with:
parallel: true
flag-name: run-${{ matrix.os }}-${{ matrix.python-version }}
ubuntu_build:
name: Build test APP [ ${{ matrix.runs_on }} | ${{ matrix.bootstrap.name }} ]
needs: [flake8]
runs-on: ${{ matrix.runs_on }}
continue-on-error: true
strategy:
matrix:
runs_on: [ubuntu-latest]
bootstrap:
- name: sdl2
target: testapps-with-numpy
# - name: sdl2_scipy # TODO: Re-enable this failing test.
# target: testapps-with-scipy
- name: webview
target: testapps-webview
- name: service_library
target: testapps-service_library-aar
- name: qt
target: testapps-qt
steps:
- name: Checkout python-for-android
uses: actions/checkout@v4
- name: Build python-for-android docker image
run: |
docker build --tag=kivy/python-for-android .
- name: Build multi-arch ${{ matrix.bootstrap.target }} artifact with docker
run: |
docker run --name p4a-latest kivy/python-for-android make ${{ matrix.bootstrap.target }}
- name: Copy produced artifacts from docker container (*.apk, *.aab)
if: matrix.bootstrap.name != 'service_library'
run: |
mkdir -p dist
docker cp p4a-latest:/home/user/app/testapps/on_device_unit_tests/${{ env.APK_ARTIFACT_FILENAME }} dist/
docker cp p4a-latest:/home/user/app/testapps/on_device_unit_tests/${{ env.AAB_ARTIFACT_FILENAME }} dist/
- name: Copy produced artifacts from docker container (*.aar)
if: matrix.bootstrap.name == 'service_library'
run: |
mkdir -p dist
docker cp p4a-latest:/home/user/app/testapps/on_device_unit_tests/${{ env.AAR_ARTIFACT_FILENAME }} dist/
- name: Rename artifacts to include the build platform name (*.apk, *.aab, *.aar)
run: |
if [ -f dist/${{ env.APK_ARTIFACT_FILENAME }} ]; then mv dist/${{ env.APK_ARTIFACT_FILENAME }} dist/${{ matrix.runs_on }}-${{ matrix.bootstrap.name }}-${{ env.APK_ARTIFACT_FILENAME }}; fi
if [ -f dist/${{ env.AAB_ARTIFACT_FILENAME }} ]; then mv dist/${{ env.AAB_ARTIFACT_FILENAME }} dist/${{ matrix.runs_on }}-${{ matrix.bootstrap.name }}-${{ env.AAB_ARTIFACT_FILENAME }}; fi
if [ -f dist/${{ env.AAR_ARTIFACT_FILENAME }} ]; then mv dist/${{ env.AAR_ARTIFACT_FILENAME }} dist/${{ matrix.runs_on }}-${{ matrix.bootstrap.name }}-${{ env.AAR_ARTIFACT_FILENAME }}; fi
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.runs_on }}-${{ matrix.bootstrap.name }}-artifacts
path: dist
macos_build:
name: Build test APP [ ${{ matrix.runs_on }} | ${{ matrix.bootstrap.name }} ]
needs: [flake8]
runs-on: ${{ matrix.runs_on }}
# TODO: temporarily disabled for debugging purpose
if: false
continue-on-error: true
strategy:
matrix:
# macos-latest (ATM macos-14) runs on Apple Silicon,
# macos-13 runs on Intel
runs_on: ['macos-latest', 'macos-13']
bootstrap:
- name: sdl2
target: testapps-with-numpy
- name: webview
target: testapps-webview
env:
ANDROID_HOME: ${HOME}/.android
ANDROID_SDK_ROOT: ${HOME}/.android/android-sdk
ANDROID_SDK_HOME: ${HOME}/.android/android-sdk
ANDROID_NDK_HOME: ${HOME}/.android/android-ndk
steps:
- name: Checkout python-for-android
uses: actions/checkout@v4
- name: Set up Python 3.x
uses: actions/setup-python@v5
with:
python-version: 3.x
- name: Install python-for-android
run: |
python3 -m pip install -e .
- name: Install prerequisites via pythonforandroid/prerequisites.py (Experimental)
run: |
python3 pythonforandroid/prerequisites.py
- name: Install dependencies (Legacy)
run: |
make --file ci/makefiles/osx.mk
- name: Build multi-arch apk Python 3 (armeabi-v7a, arm64-v8a, x86_64, x86)
run: |
make ${{ matrix.bootstrap.target }}
- name: Copy produced artifacts into dist/ (*.apk, *.aab)
run: |
mkdir -p dist
cp testapps/on_device_unit_tests/*.apk dist/
cp testapps/on_device_unit_tests/*.aab dist/
ls -l dist/
- name: Rename artifacts to include the build platform name (*.apk, *.aab)
run: |
if [ -f dist/${{ env.APK_ARTIFACT_FILENAME }} ]; then mv dist/${{ env.APK_ARTIFACT_FILENAME }} dist/${{ matrix.runs_on }}-${{ matrix.bootstrap.name }}-${{ env.APK_ARTIFACT_FILENAME }}; fi
if [ -f dist/${{ env.AAB_ARTIFACT_FILENAME }} ]; then mv dist/${{ env.AAB_ARTIFACT_FILENAME }} dist/${{ matrix.runs_on }}-${{ matrix.bootstrap.name }}-${{ env.AAB_ARTIFACT_FILENAME }}; fi
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.runs_on }}-${{ matrix.bootstrap.name }}-artifacts
path: dist
test_on_emulator:
name: Run App on Emulator
# TODO: keep it simple and go with ubuntu_build for a start
# needs: [ubuntu_build, macos_build]
needs: [ubuntu_build]
runs-on: ubuntu-latest
steps:
- name: Download Artifacts
uses: actions/download-artifact@v5
with:
# TODO: keep it simple for now, but we may iterate over more artifact in the future
name: ubuntu-latest-sdl2-artifacts
path: dist/
- name: Setup and Start Android Emulator
# This is the key action to run the emulator
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 30
# TODO: maybe make it a dedicated `ci/` script
script: |
APK_FILE=$(find dist -name "*.apk" -print -quit)
if [ -z "$APK_FILE" ]; then
echo "Error: No APK file found in dist/"
exit 1
fi
echo "Installing $APK_FILE..."
adb install "$APK_FILE"
APP_PACKAGE=$(aapt dump badging ${APK_FILE} | awk -F"'" '/package: name=/{print $2}' | tee /dev/tty)
APP_ACTIVITY=$(aapt dump badging ${APK_FILE} | awk -F"'" '/launchable-activity/ {print $2}' | tee /dev/tty)
adb shell am start -n ${APP_PACKAGE}/${APP_ACTIVITY}
echo "Launching $APP_PACKAGE/$APP_ACTIVITY..."
adb shell am start -n "$APP_PACKAGE/$APP_ACTIVITY" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
# Give the app time to start, run python, and log its status
sleep 15
# Dump the logs and search for a success string
adb logcat -d -s python:I *:S > app_logs.txt
echo "Checking app logs..."
if grep --extended-regexp --quiet "I python[ ]+: Initialized python" app_logs.txt && \
grep --extended-regexp --quiet "I python[ ]+: Ran 14 tests in" app_logs.txt && \
grep --extended-regexp --quiet "I python[ ]+: OK" app_logs.txt; then
echo "✅ SUCCESS: App launched and all unit tests passed."
else
echo "❌ Failure: Python runtime initialization not detected or app crashed."
echo "--- Full Logs ---"
cat app_logs.txt
echo "-----------------"
exit 1
fi
ubuntu_rebuild_updated_recipes:
name: Test updated recipes for arch ${{ matrix.android_arch }} [ ubuntu-latest ]
needs: [flake8]
runs-on: ubuntu-latest
# TODO: temporarily disabled for debugging purpose
if: false
continue-on-error: true
strategy:
matrix:
android_arch: ["arm64-v8a", "armeabi-v7a", "x86_64", "x86"]
env:
REBUILD_UPDATED_RECIPES_EXTRA_ARGS: --arch=${{ matrix.android_arch }}
steps:
- name: Checkout python-for-android (all-history)
uses: actions/checkout@v4
with:
fetch-depth: 0
# helps with GitHub runner getting out of space
- name: Free disk space
run: |
df -h
sudo swapoff -a
sudo rm -f /swapfile
sudo apt -y clean
docker images -q | xargs -r docker rmi
df -h
- name: Pull docker image
run: |
make docker/pull
- name: Rebuild updated recipes
run: |
make docker/run/make/rebuild_updated_recipes
macos_rebuild_updated_recipes:
name: Test updated recipes for arch ${{ matrix.android_arch }} [ ${{ matrix.runs_on }} ]
needs: [flake8]
runs-on: ${{ matrix.runs_on }}
# TODO: temporarily disabled for debugging purpose
if: false
continue-on-error: true
strategy:
matrix:
android_arch: ["arm64-v8a", "armeabi-v7a", "x86_64", "x86"]
# macos-latest (ATM macos-14) runs on Apple Silicon,
# macos-13 runs on Intel
runs_on: ['macos-latest', 'macos-13']
env:
ANDROID_HOME: ${HOME}/.android
ANDROID_SDK_ROOT: ${HOME}/.android/android-sdk
ANDROID_SDK_HOME: ${HOME}/.android/android-sdk
ANDROID_NDK_HOME: ${HOME}/.android/android-ndk
REBUILD_UPDATED_RECIPES_EXTRA_ARGS: --arch=${{ matrix.android_arch }}
steps:
- name: Checkout python-for-android (all-history)
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python 3.x
uses: actions/setup-python@v5
with:
python-version: 3.x
- name: Install python-for-android
run: |
python3 -m pip install -e .
- name: Install prerequisites via pythonforandroid/prerequisites.py (Experimental)
run: |
python3 pythonforandroid/prerequisites.py
- name: Install dependencies (Legacy)
run: |
make --file ci/makefiles/osx.mk
- name: Rebuild updated recipes
run: |
make rebuild_updated_recipes
coveralls_finish:
needs: test
runs-on: ubuntu-latest
steps:
- name: Coveralls Finished
uses: AndreMiras/coveralls-python-action@develop
with:
parallel-finished: true
documentation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Requirements
run: |
python -m pip install --upgrade pip
pip install -r doc/requirements.txt
- name: Check links
run: sphinx-build -b linkcheck doc/source doc/build
- name: Generate documentation
run: sphinx-build doc/source doc/build