Repository navigation
Modernize ProgramLoader and unify program loading pipeline #367
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: Multi-Distro Build (CMake) | |
| on: | |
| push: | |
| branches: [master] | |
| paths-ignore: | |
| - '**.md' | |
| - '.markdownlint.json' | |
| pull_request: | |
| types: [opened, synchronize, reopened, ready_for_review] | |
| branches: [master, develop] | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| jobs: | |
| # 1. Ubuntu All Frontends (SDL3, SDL2, SDL1, TUI, Headless) | |
| ubuntu-all-frontends: | |
| name: Ubuntu 24.04 (All Frontends) | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y g++ cmake ninja-build imagemagick libzip-dev \ | |
| libcurl4-openssl-dev zlib1g-dev git libxkbcommon-dev libz3-dev \ | |
| libsdl2-dev libsdl1.2-dev libsdl-image1.2-dev libpulse-dev libasound2-dev ccache gh | |
| - name: Setup ccache | |
| uses: hendrikmuhs/ccache-action@v1.2 | |
| with: | |
| key: ${{ runner.os }}-ubuntu-all | |
| - name: Setup SDL3 | |
| uses: libsdl-org/setup-sdl@main | |
| id: sdl | |
| with: | |
| version: 3-latest | |
| version-sdl-image: 3-latest | |
| install-linux-dependencies: true | |
| - name: Configure | |
| run: | | |
| cmake -B build -G Ninja \ | |
| -DCMAKE_C_COMPILER_LAUNCHER=ccache \ | |
| -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ | |
| -DFRONTEND=all \ | |
| -DCMAKE_PREFIX_PATH="${{ steps.sdl.outputs.prefix }}" \ | |
| -DCMAKE_POLICY_VERSION_MINIMUM=3.5 | |
| - name: Build | |
| run: cmake --build build -j$(nproc) | |
| - name: Test | |
| env: | |
| SDL_VIDEODRIVER: dummy | |
| SDL_VIDEO_DRIVER: dummy | |
| SDL_AUDIODRIVER: dummy | |
| SDL_AUDIO_DRIVER: dummy | |
| run: ctest --test-dir build -j$(nproc) --output-on-failure | |
| - name: Install | |
| run: sudo cmake --install build | |
| # 2. Multi-Distro Matrix (Fedora, Arch Linux, Debian / Pi OS x86) | |
| distro-matrix: | |
| name: ${{ matrix.name }} | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: Fedora Latest (SDL3) | |
| image: fedora:latest | |
| setup: | | |
| dnf install -y gcc-c++ cmake ninja-build ImageMagick libzip-devel \ | |
| SDL3-devel SDL3_image-devel libcurl-devel zlib-devel git z3-devel curl ccache nodejs \ | |
| perl-IO-Compress | |
| frontend: sdl3 | |
| - name: Arch Linux Rolling (SDL3) | |
| image: archlinux:latest | |
| setup: | | |
| pacman -Syu --noconfirm | |
| pacman -S --noconfirm base-devel cmake ninja imagemagick libzip \ | |
| sdl3 sdl3_image libcurl-gnutls zlib git z3 curl ccache nodejs | |
| frontend: sdl3 | |
| - name: Debian 12 / Pi OS x86 (SDL2) | |
| image: debian:bookworm-slim | |
| setup: | | |
| apt-get update | |
| apt-get install -y g++ cmake ninja-build imagemagick libzip-dev \ | |
| libcurl4-openssl-dev zlib1g-dev git libxkbcommon-dev libz3-dev \ | |
| libsdl2-dev curl ccache nodejs | |
| frontend: sdl2 | |
| container: | |
| image: ${{ matrix.image }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Dependencies | |
| run: ${{ matrix.setup }} | |
| - name: Cache ccache | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cache/ccache | |
| ~/.ccache | |
| key: ccache-${{ matrix.name }}-${{ github.sha }} | |
| restore-keys: | | |
| ccache-${{ matrix.name }}- | |
| - name: Configure | |
| run: | | |
| cmake -B build -G Ninja \ | |
| -DCMAKE_C_COMPILER_LAUNCHER=ccache \ | |
| -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ | |
| -DFRONTEND=${{ matrix.frontend }} \ | |
| -DCMAKE_POLICY_VERSION_MINIMUM=3.5 | |
| - name: Build | |
| run: cmake --build build -j$(nproc) | |
| - name: Test | |
| env: | |
| SDL_VIDEODRIVER: dummy | |
| SDL_VIDEO_DRIVER: dummy | |
| SDL_AUDIODRIVER: dummy | |
| SDL_AUDIO_DRIVER: dummy | |
| run: ctest --test-dir build -j$(nproc) --output-on-failure | |
| - name: Install | |
| run: cmake --install build | |
| # 3. Native ARM64 (Ubuntu / Raspberry Pi OS 64-bit Compatible) | |
| rpi-arm64: | |
| name: Native ARM64 (Ubuntu / Pi OS 64-bit) | |
| runs-on: ubuntu-24.04-arm | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y g++ cmake ninja-build imagemagick libzip-dev \ | |
| libcurl4-openssl-dev zlib1g-dev git libxkbcommon-dev libz3-dev ccache | |
| - name: Setup ccache | |
| uses: hendrikmuhs/ccache-action@v1.2 | |
| with: | |
| key: ${{ runner.os }}-arm64 | |
| - name: Setup SDL3 | |
| uses: libsdl-org/setup-sdl@main | |
| id: sdl | |
| with: | |
| version: 3-latest | |
| version-sdl-image: 3-latest | |
| install-linux-dependencies: true | |
| - name: Configure | |
| run: | | |
| cmake -B build -G Ninja \ | |
| -DCMAKE_C_COMPILER_LAUNCHER=ccache \ | |
| -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ | |
| -DFRONTEND=sdl3 \ | |
| -DCMAKE_PREFIX_PATH="${{ steps.sdl.outputs.prefix }}" \ | |
| -DCMAKE_POLICY_VERSION_MINIMUM=3.5 | |
| - name: Build | |
| run: cmake --build build -j$(nproc) | |
| - name: Test | |
| env: | |
| SDL_VIDEODRIVER: dummy | |
| SDL_VIDEO_DRIVER: dummy | |
| SDL_AUDIODRIVER: dummy | |
| SDL_AUDIO_DRIVER: dummy | |
| run: ctest --test-dir build -j$(nproc) --output-on-failure | |
| - name: Install | |
| run: sudo cmake --install build | |
| # 4. Sanitizers (ASAN/UBSAN - All Frontends) | |
| sanitizers-build: | |
| name: Sanitizers (All Frontends + ASAN/UBSAN) | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y g++ cmake ninja-build imagemagick libzip-dev \ | |
| libcurl4-openssl-dev zlib1g-dev git libxkbcommon-dev libz3-dev \ | |
| libsdl2-dev libsdl1.2-dev libsdl-image1.2-dev libpulse-dev libasound2-dev ccache gh | |
| - name: Setup ccache | |
| uses: hendrikmuhs/ccache-action@v1.2 | |
| with: | |
| key: ${{ runner.os }}-sanitizers | |
| - name: Setup SDL3 | |
| uses: libsdl-org/setup-sdl@main | |
| id: sdl | |
| with: | |
| version: 3-latest | |
| version-sdl-image: 3-latest | |
| install-linux-dependencies: true | |
| - name: Configure | |
| run: | | |
| cmake -B build -G Ninja \ | |
| -DCMAKE_C_COMPILER_LAUNCHER=ccache \ | |
| -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ | |
| -DFRONTEND=all \ | |
| -DENABLE_ASAN=ON \ | |
| -DENABLE_UBSAN=ON \ | |
| -DCMAKE_PREFIX_PATH="${{ steps.sdl.outputs.prefix }}" \ | |
| -DCMAKE_POLICY_VERSION_MINIMUM=3.5 | |
| - name: Build | |
| run: cmake --build build -j$(nproc) | |
| - name: Test | |
| env: | |
| ASAN_OPTIONS: "detect_leaks=1" | |
| UBSAN_OPTIONS: "print_stacktrace=1" | |
| SDL_VIDEODRIVER: dummy | |
| SDL_VIDEO_DRIVER: dummy | |
| SDL_AUDIODRIVER: dummy | |
| SDL_AUDIO_DRIVER: dummy | |
| run: ctest --test-dir build -j$(nproc) --output-on-failure | |
| # 5. Static Analysis (clang-tidy) | |
| clang-tidy-check: | |
| name: Static Analysis (clang-tidy) | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y g++ cmake ninja-build clang-tidy imagemagick \ | |
| libzip-dev libcurl4-openssl-dev zlib1g-dev git libxkbcommon-dev libz3-dev \ | |
| libsdl2-dev libsdl1.2-dev libsdl-image1.2-dev libpulse-dev libasound2-dev ccache gh | |
| - name: Setup ccache | |
| uses: hendrikmuhs/ccache-action@v1.2 | |
| with: | |
| key: ${{ runner.os }}-clang-tidy | |
| - name: Setup SDL3 | |
| uses: libsdl-org/setup-sdl@main | |
| id: sdl | |
| with: | |
| version: 3-latest | |
| version-sdl-image: 3-latest | |
| install-linux-dependencies: true | |
| - name: Configure | |
| run: | | |
| cmake -B build -G Ninja \ | |
| -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ | |
| -DFRONTEND=all \ | |
| -DBUILD_TESTING=OFF \ | |
| -DCMAKE_PREFIX_PATH="${{ steps.sdl.outputs.prefix }}" \ | |
| -DCMAKE_POLICY_VERSION_MINIMUM=3.5 | |
| cmake --build build --target generate_xpms | |
| jq 'unique_by(.file)' build/compile_commands.json > build/compile_commands.json.tmp && mv build/compile_commands.json.tmp build/compile_commands.json | |
| - name: Build & Analyze | |
| run: | | |
| run-clang-tidy -p build -j$(nproc) -quiet "src/.*" | |
| # 6. Fuzzing Smoke Test (libFuzzer + ASan/UBSan) | |
| fuzz-smoke: | |
| name: Fuzzing Smoke Test (Ubuntu 24.04 + Clang + libFuzzer) | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y clang cmake ninja-build imagemagick libzip-dev \ | |
| libcurl4-openssl-dev zlib1g-dev git libxkbcommon-dev libz3-dev ccache | |
| - name: Setup ccache | |
| uses: hendrikmuhs/ccache-action@v1.2 | |
| with: | |
| key: ${{ runner.os }}-fuzz | |
| - name: Restore Fuzzing Corpus Cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: tests/fuzz/corpus | |
| key: ${{ runner.os }}-fuzz-corpus-${{ github.sha }} | |
| restore-keys: | | |
| ${{ runner.os }}-fuzz-corpus- | |
| - name: Configure & Build | |
| run: | | |
| cmake -B build-fuzz -G Ninja \ | |
| -DCMAKE_C_COMPILER=clang \ | |
| -DCMAKE_CXX_COMPILER=clang++ \ | |
| -DCMAKE_C_COMPILER_LAUNCHER=ccache \ | |
| -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ | |
| -DFRONTEND=headless \ | |
| -DENABLE_FUZZING=ON \ | |
| -DBUILD_TESTING=ON \ | |
| -DCMAKE_POLICY_VERSION_MINIMUM=3.5 | |
| cmake --build build-fuzz -j$(nproc) | |
| - name: Run Fuzz Tests | |
| run: | | |
| ctest --test-dir build-fuzz -L fuzz --output-on-failure | |
| - name: Minimize Corpus | |
| if: always() | |
| run: | | |
| for target in memory snapshot disk-loader image-container disk-controller disk-adapter speaker audio-mixer mockingboard ay8910 via6522; do | |
| if [ -d "tests/fuzz/corpus/${target}" ]; then | |
| mkdir -p "tests/fuzz/corpus/${target}-min" | |
| ./build-fuzz/fuzz-${target} -merge=1 "tests/fuzz/corpus/${target}-min" "tests/fuzz/corpus/${target}" || true | |
| rm -rf "tests/fuzz/corpus/${target}" | |
| mv "tests/fuzz/corpus/${target}-min" "tests/fuzz/corpus/${target}" | |
| fi | |
| done | |
| # 7. Shared Peripherals (Headless + Plugin Loader Smoke Test) | |
| shared-peripherals: | |
| name: Shared Peripherals (Headless Plugin Loader) | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y g++ cmake ninja-build imagemagick libzip-dev \ | |
| libcurl4-openssl-dev zlib1g-dev git libxkbcommon-dev libz3-dev ccache | |
| - name: Setup ccache | |
| uses: hendrikmuhs/ccache-action@v1.2 | |
| with: | |
| key: ${{ runner.os }}-shared-peripherals | |
| - name: Configure | |
| run: | | |
| cmake -B build-shared -G Ninja \ | |
| -DCMAKE_C_COMPILER_LAUNCHER=ccache \ | |
| -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ | |
| -DFRONTEND=headless \ | |
| -DBUILD_SHARED_PERIPHERALS=ON \ | |
| -DBUILD_TESTING=ON \ | |
| -DCMAKE_POLICY_VERSION_MINIMUM=3.5 | |
| - name: Build | |
| run: cmake --build build-shared -j$(nproc) | |
| - name: Test | |
| run: ctest --test-dir build-shared -j$(nproc) --output-on-failure | |
| - name: Assert Hardware Count | |
| run: | | |
| count=$(./build-shared/linapple --list-hardware | grep -c '^- ') | |
| echo "Detected peripheral count: $count" | |
| if [ "$count" -ne 10 ]; then | |
| echo "Expected 10 peripherals, but got $count" | |
| exit 1 | |
| fi | |
| - name: Assert No Plugin Carries Compression | |
| run: | | |
| for plugin in build-shared/*.so; do | |
| echo "== $plugin" | |
| ! ldd "$plugin" | grep -E 'libz\.so|libzip\.so' | |
| done | |
| # 8. No Disk Peripherals (Headless, both image-opening cards off) | |
| no-disk-peripherals: | |
| name: No Disk Peripherals (Headless, No Compression) | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y g++ cmake ninja-build imagemagick libzip-dev \ | |
| libcurl4-openssl-dev zlib1g-dev git libxkbcommon-dev libz3-dev ccache | |
| - name: Setup ccache | |
| uses: hendrikmuhs/ccache-action@v1.2 | |
| with: | |
| key: ${{ runner.os }}-no-disk-peripherals | |
| - name: Configure | |
| run: | | |
| cmake -B build-nodisk -G Ninja \ | |
| -DCMAKE_C_COMPILER_LAUNCHER=ccache \ | |
| -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ | |
| -DFRONTEND=headless \ | |
| -DENABLE_PERIPHERAL_DISK=OFF \ | |
| -DENABLE_PERIPHERAL_HARDDISK=OFF \ | |
| -DBUILD_TESTING=ON \ | |
| -DCMAKE_POLICY_VERSION_MINIMUM=3.5 | |
| - name: Build | |
| run: cmake --build build-nodisk -j$(nproc) | |
| - name: Test | |
| run: ctest --test-dir build-nodisk -j$(nproc) --output-on-failure | |
| - name: Assert No Compression Is Configured or Linked | |
| run: | | |
| ! grep -E '^(ZLIB_|LIBZIP_|pkgcfg_lib_LIBZIP)' build-nodisk/CMakeCache.txt | |
| ldd build-nodisk/linapple | |
| ! ldd build-nodisk/linapple | grep -E 'libz\.so|libzip\.so' | |
| # 9. CI Gate (All Checks Passed) | |
| ci-gate: | |
| name: CI Status Gate | |
| if: always() | |
| needs: | |
| - ubuntu-all-frontends | |
| - distro-matrix | |
| - rpi-arm64 | |
| - sanitizers-build | |
| - clang-tidy-check | |
| - fuzz-smoke | |
| - shared-peripherals | |
| - no-disk-peripherals | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Verify all required jobs passed | |
| run: | | |
| echo "Evaluating CI job statuses..." | |
| passed=true | |
| for result in "${{ needs.ubuntu-all-frontends.result }}" \ | |
| "${{ needs.distro-matrix.result }}" \ | |
| "${{ needs.rpi-arm64.result }}" \ | |
| "${{ needs.sanitizers-build.result }}" \ | |
| "${{ needs.clang-tidy-check.result }}" \ | |
| "${{ needs.fuzz-smoke.result }}" \ | |
| "${{ needs.shared-peripherals.result }}" \ | |
| "${{ needs.no-disk-peripherals.result }}"; do | |
| echo "Job result: $result" | |
| if [ "$result" != "success" ]; then | |
| passed=false | |
| fi | |
| done | |
| if [ "$passed" = false ]; then | |
| echo "Error: One or more required CI jobs failed or were cancelled." | |
| exit 1 | |
| fi | |
| echo "All required CI jobs succeeded." |