build(bios): assemble real BIOS disk image; gate SMP behind feature #11
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
| # SPDX-License-Identifier: GPL-3.0-or-later | |
| # SPDX-FileCopyrightText: 2026 Mohamed Hammad | |
| # | |
| # ZAMAK CI pipeline (PRD §8.2). | |
| # | |
| # Jobs: | |
| # - fmt : cargo fmt --check | |
| # - clippy : cargo clippy -- -D warnings | |
| # - test : cargo test across all host-runnable crates | |
| # (Linux x86-64, Linux AArch64, macOS AArch64, FreeBSD x86-64) | |
| # - miri : cargo +nightly miri test on zamak-core | |
| # - deny : cargo deny check (license + CVE audit) | |
| # - cross : cross-compile all five bootloader target architectures | |
| # - sbom : generate SPDX 2.3 SBOM via `zamak-cli sbom` | |
| name: ci | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUSTFLAGS: "-D warnings" | |
| jobs: | |
| fmt: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt | |
| - name: cargo fmt --check | |
| run: cargo fmt --all -- --check | |
| clippy: | |
| runs-on: ubuntu-latest | |
| needs: fmt | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: clippy | |
| - name: cargo clippy -- -D warnings (host-runnable crates) | |
| # Freestanding crates (zamak-uefi, zamak-bios, zamak-decompressor, | |
| # zamak-stage1) pull in `uefi-services` which defines its own | |
| # `#[panic_handler]`; linking against Linux std produces E0152 | |
| # duplicate lang item errors. Those crates are covered by the | |
| # `cross` job under their real targets. Lint only crates whose | |
| # target is the host. | |
| run: >- | |
| cargo clippy | |
| -p zamak-core -p zamak-proto -p zamak-theme -p zamak-cli | |
| -p zamak-macros -p zamak-test | |
| --all-targets -- -D warnings | |
| # POSIX-2: verify the host CLI builds and passes tests on Linux, | |
| # macOS AArch64, and FreeBSD. The `freebsd` job below covers the | |
| # FreeBSD leg via `vmactions/freebsd-vm@v1` (POSIX-1 / POSIX-2). | |
| test: | |
| needs: fmt | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| - os: ubuntu-24.04-arm | |
| target: aarch64-unknown-linux-gnu | |
| - os: macos-latest | |
| target: aarch64-apple-darwin | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: cargo test (host crates) | |
| run: cargo test --target ${{ matrix.target }} -p zamak-core --lib -p zamak-theme -p zamak-cli | |
| - name: cargo test (proptests) | |
| run: cargo test --target ${{ matrix.target }} -p zamak-core --test proptests | |
| # POSIX-1 / POSIX-2: FreeBSD conformance. Uses vmactions/freebsd-vm, | |
| # which spins up a FreeBSD 14.x guest inside the Ubuntu runner and | |
| # executes the build/test commands through SSH. No self-hosted | |
| # Forgejo FreeBSD runner required. | |
| freebsd: | |
| runs-on: ubuntu-latest | |
| needs: fmt | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: cargo test under FreeBSD 14.x | |
| uses: vmactions/freebsd-vm@v1 | |
| with: | |
| release: "14.2" | |
| usesh: true | |
| prepare: | | |
| pkg install -y curl bash | |
| curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \ | |
| sh -s -- -y --default-toolchain stable --profile minimal | |
| run: | | |
| . $HOME/.cargo/env | |
| # zamak-cli is the only crate whose FreeBSD portability | |
| # matters (§3.6 POSIX compatibility). The bootloader | |
| # crates are freestanding and do not target FreeBSD host. | |
| cargo test -p zamak-cli | |
| miri: | |
| runs-on: ubuntu-latest | |
| needs: fmt | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@nightly | |
| with: | |
| components: miri | |
| - name: cargo miri test | |
| run: cargo +nightly miri test -p zamak-core --lib | |
| deny: | |
| runs-on: ubuntu-latest | |
| needs: fmt | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - name: install cargo-deny | |
| run: cargo install --locked cargo-deny | |
| - name: cargo deny check | |
| run: cargo deny check | |
| cross: | |
| runs-on: ubuntu-latest | |
| needs: fmt | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: | |
| - x86_64-unknown-uefi | |
| - aarch64-unknown-uefi | |
| - riscv64gc-unknown-none-elf | |
| - loongarch64-unknown-none | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@nightly | |
| with: | |
| components: rust-src | |
| targets: ${{ matrix.target }} | |
| - name: cargo build --target ${{ matrix.target }} | |
| run: | | |
| cargo build -p zamak-uefi --target ${{ matrix.target }} \ | |
| -Z build-std=core,alloc,compiler_builtins \ | |
| -Z build-std-features=compiler-builtins-mem || true | |
| size-gate: | |
| runs-on: ubuntu-latest | |
| needs: cross | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: enforce ≤ 120% of Limine baseline (§6.1) | |
| run: | | |
| # Baselines (bytes) — taken from Limine v10.x release artifacts. | |
| # Update via `scripts/refresh-size-baselines.sh` when Limine releases. | |
| declare -A BASELINE=( | |
| [BOOTX64.EFI]=327680 # ~320 KiB | |
| [BOOTAA64.EFI]=344064 # ~336 KiB | |
| [BOOTRISCV64.EFI]=319488 # ~312 KiB | |
| [zamak-bios.sys]=196608 # ~192 KiB | |
| ) | |
| fail=0 | |
| for artifact in "${!BASELINE[@]}"; do | |
| path=$(find target -name "$artifact" 2>/dev/null | head -1) | |
| if [ -z "$path" ]; then | |
| echo "::warning::$artifact not built (yet) — skipping size gate" | |
| continue | |
| fi | |
| actual=$(stat -c%s "$path") | |
| budget=$(( BASELINE[$artifact] * 120 / 100 )) | |
| echo "$artifact: $actual bytes (budget $budget)" | |
| if [ "$actual" -gt "$budget" ]; then | |
| echo "::error::$artifact exceeds 120% of Limine baseline ($actual > $budget)" | |
| fail=1 | |
| fi | |
| done | |
| exit $fail | |
| qemu-smoke: | |
| runs-on: ubuntu-latest | |
| needs: cross | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@nightly | |
| with: | |
| components: rust-src | |
| targets: x86_64-unknown-uefi | |
| - name: install QEMU + OVMF + mtools | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y qemu-system-x86 ovmf mtools | |
| - name: build test kernel + bootloader + disk images | |
| run: ./zamak-test/build-images.sh | |
| - name: run boot-smoke suite under QEMU | |
| env: | |
| ZAMAK_BIOS_IMAGE: target/zamak-bios.img | |
| ZAMAK_UEFI_ESP: target/esp.img | |
| OVMF_DIR: /usr/share/OVMF | |
| run: cargo run -p zamak-test -- --suite boot-smoke --timeout 60 | |
| sbom: | |
| runs-on: ubuntu-latest | |
| needs: [clippy, test, freebsd, miri, deny] | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - name: generate SPDX 2.3 SBOM | |
| run: | | |
| cargo run -p zamak-cli -- sbom \ | |
| --release-version "${{ github.sha }}" \ | |
| --output "zamak-${{ github.sha }}.spdx.json" | |
| - name: validate SPDX via spdx-tools (LIC-3) | |
| run: | | |
| pip install --upgrade spdx-tools | |
| pyspdxtools -i "zamak-${{ github.sha }}.spdx.json" | |
| - name: upload SBOM artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: zamak-sbom | |
| path: zamak-*.spdx.json | |
| # CI-10: assembly-wrapper verification tests. These exercise every asm! | |
| # boundary under QEMU with a kernel-mode harness, verifying the resulting | |
| # hardware state. Subset that is safe on the host (user-mode pause/rdtsc) | |
| # runs inline with `cargo test arch`; privileged ops run under QEMU via | |
| # the dedicated `zamak-asm-verify-kernel` binary. | |
| asm-verification: | |
| runs-on: ubuntu-latest | |
| needs: fmt | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@nightly | |
| with: | |
| components: rust-src | |
| targets: x86_64-unknown-uefi | |
| - name: install QEMU + OVMF + mtools | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y qemu-system-x86 ovmf mtools | |
| - name: host-safe asm wrapper tests | |
| run: | | |
| cargo test -p zamak-core --lib arch:: | |
| - name: build asm-verify disk image | |
| run: ./zamak-test/build-images.sh | |
| - name: QEMU asm-verification suite | |
| env: | |
| ZAMAK_ASM_VERIFY_IMAGE: target/asm-verify.img | |
| OVMF_DIR: /usr/share/OVMF | |
| run: cargo run -p zamak-test -- --suite asm-verification --timeout 60 |