Read the Kolibri version from one shared helper across platforms #10507
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |
| uses: ./.github/workflows/platform-debian-server-build_deb.yml | |
| 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 |