Skip to content

Remove dead SQLAlchemy helpers from tasks and sqlite utils #10496

Remove dead SQLAlchemy helpers from tasks and sqlite utils

Remove dead SQLAlchemy helpers from tasks and sqlite utils #10496

name: Kolibri Build Assets for Pull Request
on: pull_request
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions:
contents: read
jobs:
whl:
name: Build WHL file
uses: ./.github/workflows/build_whl.yml
pex:
name: Build PEX file
needs: whl
uses: ./.github/workflows/build_pex.yml
with:
whl-file-name: ${{ needs.whl.outputs.whl-file-name }}
dmg:
name: Build DMG file
needs: whl
uses: ./.github/workflows/platform-macos-app-build_dmg.yml
with:
whl-file-name: ${{ needs.whl.outputs.whl-file-name }}
deb:
name: Build DEB file
needs: whl
uses: learningequality/kolibri-installer-debian/.github/workflows/build_deb.yml@v0.18.0
with:
tar-file-name: ${{ needs.whl.outputs.tar-file-name }}
ref: v0.16.1
server_deb:
name: Build kolibri-server DEB file
needs: whl
uses: ./.github/workflows/platform-debian-server-build_deb.yml
with:
tar-file-name: ${{ needs.whl.outputs.tar-file-name }}
exe:
name: Build EXE file
needs: whl
uses: ./.github/workflows/platform-windows-app-build_exe.yml
with:
whl-file-name: ${{ needs.whl.outputs.whl-file-name }}
apk:
name: Build APK file
needs: whl
uses: ./.github/workflows/platform-android-build_apk.yml
with:
tar-file-name: ${{ needs.whl.outputs.tar-file-name }}
zip:
name: Build Raspberry Pi Image
needs: [deb, server_deb]
uses: ./.github/workflows/platform-pi-build_img.yml
with:
deb-file-name: ${{ needs.deb.outputs.deb-file-name }}
server-deb-file-name: ${{ needs.server_deb.outputs.deb-file-name }}
pi_smoke_test:
name: Pi image smoke test
needs: zip
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7.0.0
- name: Download zip artifact
uses: actions/download-artifact@v8
with:
name: ${{ needs.zip.outputs.zip-file-name }}
path: dist
- name: Verify image WiFi configuration
run: sudo ./platforms/raspberry-pi/smoke-test-wifi.sh dist/*.zip
server_smoke_test:
name: kolibri-server serving smoke test
needs: [deb, server_deb]
runs-on: ubuntu-latest
timeout-minutes: 15
env:
# Single source for the served port: preseeded into debconf below and read
# by serving_smoke_test.sh (via $KOLIBRI_SERVER_PORT) when it curls nginx.
KOLIBRI_SERVER_PORT: "8080"
steps:
- uses: actions/checkout@v7.0.0
- name: Download the Kolibri deb
uses: actions/download-artifact@v8
with:
name: ${{ needs.deb.outputs.deb-file-name }}
path: debs
- name: Download the kolibri-server deb
uses: actions/download-artifact@v8
with:
name: ${{ needs.server_deb.outputs.deb-file-name }}
path: debs
- name: Preseed debconf selections
run: |
echo "kolibri kolibri/init boolean false" | sudo debconf-set-selections
echo "kolibri kolibri/user string kolibri" | sudo debconf-set-selections
echo "kolibri-server kolibri-server/port select ${KOLIBRI_SERVER_PORT}" | sudo debconf-set-selections
echo "kolibri-server kolibri-server/zip_content_port select 8081" | sudo debconf-set-selections
- name: Install the Kolibri and kolibri-server debs
env:
DEBIAN_FRONTEND: noninteractive
run: |
sudo apt-get update
sudo apt-get install -y \
"./debs/${{ needs.deb.outputs.deb-file-name }}" \
"./debs/${{ needs.server_deb.outputs.deb-file-name }}"
- name: Start kolibri-server
run: sudo service kolibri-server restart
- name: Assert Kolibri is served through nginx
run: ./platforms/debian-server/tests/serving_smoke_test.sh
- name: Dump service logs on failure
if: failure()
run: |
sudo journalctl -u kolibri-server --no-pager || true
sudo journalctl -u nginx --no-pager || true
sudo cat /home/kolibri/.kolibri/logs/uwsgi.log 2>/dev/null || true
android_smoke_test:
name: Android smoke test (API ${{ matrix.api-level }})
needs: apk
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- api-level: 24
target: default
- api-level: 30
target: google_apis
- api-level: 35
target: google_apis
experimental: true
steps:
- uses: actions/checkout@v7.0.0
- name: Set up JDK 21
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '21'
- name: Install Maestro CLI
working-directory: platforms/android
run: make maestro-install
- name: Add Maestro to PATH
run: echo "$HOME/.maestro/bin" >> "$GITHUB_PATH"
- name: Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Download APK artifact
uses: actions/download-artifact@v8
with:
name: ${{ needs.apk.outputs.apk-file-name }}
path: platforms/android/dist
- name: Run smoke test
# The API 35 emulator intermittently drops to `device offline` mid-test on
# the hosted runner (software-rendered, no snapshot) — a crash the
# Maestro-level retry can't recover from, since the emulator itself is gone.
# This job is advisory (not in the required `smoke_tests` gate), so mark the
# flaky axis experimental to keep its coverage without red-X'ing the PR;
# 24/30 stay hard signals. `continue-on-error` must sit on the step, not the
# job: job-level only spares the overall run, leaving the matrix leg's own
# check red — step-level flips the leg's conclusion to success.
continue-on-error: ${{ matrix.experimental || false }}
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
arch: x86_64
target: ${{ matrix.target }}
force-avd-creation: false
disable-animations: true
# Hardened emulator flags. Snapshot save/restore + accelerated GPU have been
# the root cause of intermittent "bad color buffer handle" and "device offline"
# crashes mid-test on CI — `-no-snapshot` skips both load and save, and
# `swiftshader_indirect` forces software rendering.
emulator-options: -no-snapshot -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -camera-front none
# NOTE: reactivecircus runs each line of this script as a separate `sh -c` call,
# so multi-line shell constructs (until/while/case) must live in the Makefile
# or a script file, not here, and directory changes do not persist between
# lines — reference platforms/android explicitly.
script: |
adb install -r platforms/android/dist/*.apk
adb shell am set-debug-app --persistent org.learningequality.Kolibri
adb wait-for-device
until adb shell pm path org.learningequality.Kolibri >/dev/null 2>&1; do sleep 1; done
# Pre-grant so the WRITE_EXTERNAL_STORAGE dialog (API 24-28) never appears.
# `|| true`: the permission doesn't exist on API 29+.
adb shell pm grant org.learningequality.Kolibri android.permission.WRITE_EXTERNAL_STORAGE || true
# Let the launcher settle before app launch, to avoid the "Pixel Launcher
# isn't responding" ANR seen on the API 35 runner under cold-boot contention.
sleep 15
make -C platforms/android smoke-test-with-retry
- name: Upload Maestro debug output
if: always()
uses: actions/upload-artifact@v7
with:
name: maestro-debug-output-api-${{ matrix.api-level }}
path: ~/.maestro/tests/
mac_smoke_test:
name: macOS DMG smoke test
needs: dmg
# The DMG is built on macos-15-intel; smoke-test the Intel binary on an Intel
# runner so a Rosetta shim on an arm64 runner can't mask a broken build.
runs-on: macos-15-intel
timeout-minutes: 15
steps:
- uses: actions/checkout@v7.0.0
- name: Download macOS DMG
uses: actions/download-artifact@v8
with:
name: ${{ needs.dmg.outputs.dmg-file-name }}
path: artifacts
- name: Run smoke test
run: ./platforms/desktop-app/scripts/smoke_test_macos.sh "./artifacts/${{ needs.dmg.outputs.dmg-file-name }}"
windows_smoke_test:
name: Windows EXE smoke test
needs: exe
runs-on: windows-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v7.0.0
- name: Download Windows installer
uses: actions/download-artifact@v8
with:
name: ${{ needs.exe.outputs.exe-file-name }}
path: artifacts
- name: Run smoke test
shell: bash
run: ./platforms/desktop-app/scripts/smoke_test_windows.sh "./artifacts/${{ needs.exe.outputs.exe-file-name }}"
browser_smoke_test:
name: Browser smoke test
needs: whl
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7.0.0
- name: Install Python
uses: actions/setup-python@v6
with:
python-version: '3.12'
- uses: actions/download-artifact@v8
with:
name: ${{ needs.whl.outputs.whl-file-name }}
path: dist
- name: Install WHL file
run: pip install dist/${{ needs.whl.outputs.whl-file-name }}
- name: Install Playwright
run: |
pip install "playwright<2"
playwright install --with-deps chromium
- name: Run browser smoke test
env:
KOLIBRI_HOME: ${{ runner.temp }}/kolibri_home
SCREENSHOT_PATH: ${{ runner.temp }}/smoke_test_screenshot.png
working-directory: ${{ runner.temp }}
run: python ${{ github.workspace }}/integration_testing/smoke_test.py
- name: Upload screenshot
if: always()
uses: actions/upload-artifact@v7
with:
name: smoke_test_screenshot
path: ${{ runner.temp }}/smoke_test_screenshot.png
if-no-files-found: ignore
test_whl_file:
name: Test WHL file with uv-supported Python versions
needs: whl
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
cext: [true, false]
runs-on: ubuntu-latest
steps:
- name: Set up uv
uses: astral-sh/setup-uv@v8.2.0
with:
enable-cache: true
cache-python: true
- name: Install Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}
- uses: actions/download-artifact@v8
with:
name: ${{ needs.whl.outputs.whl-file-name }}
path: dist
# Seed the venv with real pip so the wheel is installed via pip itself
# (not `uv pip`), exercising the install path end users actually follow.
- name: Create virtual environment with pip
run: uv venv --seed --python ${{ matrix.python-version }}
- name: Install WHL file
run: .venv/bin/pip install dist/${{ needs.whl.outputs.whl-file-name }}
- name: Smoke test WHL file
env:
KOLIBRI_NO_C_EXTENSIONS: ${{ matrix.cext == false && '1' || '' }}
run: .venv/bin/kolibri configure setup
test_whl_file_no_uv:
name: Test WHL file with Python versions without uv support
needs: whl
strategy:
matrix:
python-version: [3.6, 3.7]
cext: [true, false]
runs-on: ubuntu-latest
container:
image: python:${{ matrix.python-version }}-buster
steps:
- uses: actions/download-artifact@v8
with:
name: ${{ needs.whl.outputs.whl-file-name }}
path: dist
- name: Install WHL file
run: pip install dist/${{ needs.whl.outputs.whl-file-name }}
- name: Smoke test WHL file
env:
KOLIBRI_NO_C_EXTENSIONS: ${{ matrix.cext == false && '1' || '' }}
run: kolibri configure setup
# Single stable check for branch protection. Gate on this one job so matrix
# or implementation changes in the smoke tests don't require updating the
# required-checks list in branch protection.
smoke_tests:
name: WHL smoke tests
needs:
- whl
- browser_smoke_test
- test_whl_file
- test_whl_file_no_uv
if: always()
runs-on: ubuntu-latest
steps:
- name: Fail if any needed job failed or was cancelled
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: exit 1