Files
MetalOS/.github/workflows/qemu-test.yml
2025-12-28 22:09:59 +00:00

143 lines
3.7 KiB
YAML

name: QEMU Boot Test
on:
push:
branches: [ main, copilot/* ]
pull_request:
branches: [ main ]
workflow_dispatch:
jobs:
qemu-boot-test:
runs-on: ubuntu-latest
permissions:
contents: read
actions: write # For uploading artifacts
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
set -e # Exit on any error
sudo apt-get update
sudo apt-get install -y \
build-essential \
clang \
cmake \
nasm \
qemu-system-x86 \
ovmf \
mtools \
xorriso \
imagemagick \
python3 \
python3-pip
# Install Conan
pip3 install conan
# Configure Conan
conan profile detect --force
- name: Install Conan dependencies
run: |
conan install . --build=missing
- name: Configure CMake
run: |
mkdir -p build
cd build
CC=clang CXX=clang++ cmake .. -DCMAKE_TOOLCHAIN_FILE=../build/Release/generators/conan_toolchain.cmake
- name: Build bootloader and kernel
run: |
cd build
cmake --build .
- name: Create bootable image
run: |
cd build
cmake --build . --target image
- name: Start QEMU and capture screenshot
run: |
set -e # Exit on any error
# Start Xvfb for headless screenshot capture
export DISPLAY=:99
Xvfb :99 -screen 0 1920x1080x24 &
XVFB_PID=$!
sleep 2
# Verify disk image exists (created by cmake build)
if [ ! -f build/build/metalos.img ]; then
echo "Error: build/build/metalos.img not found!"
exit 1
fi
# Create directory for logs
mkdir -p build/logs
# Start QEMU in the background with a timeout
timeout 30s qemu-system-x86_64 \
-bios /usr/share/OVMF/OVMF_CODE.fd \
-drive format=raw,file=build/build/metalos.img \
-m 512M \
-display gtk \
-serial file:build/logs/serial.log \
-no-reboot &
QEMU_PID=$!
# Wait for boot (adjust timing as needed)
sleep 10
# Take screenshot using ImageMagick (optional - don't fail if this doesn't work)
# Using subshell to prevent 'set -e' from affecting this optional step
{ import -window root build/logs/qemu-screenshot.png; } || echo "Screenshot capture failed (non-fatal)"
# Gracefully stop QEMU (don't fail if already stopped)
kill $QEMU_PID 2>/dev/null || true
wait $QEMU_PID 2>/dev/null || true
# Stop Xvfb (don't fail if already stopped)
kill $XVFB_PID 2>/dev/null || true
echo "Boot test completed"
- name: Show serial output
if: always()
run: |
if [ -f build/logs/serial.log ]; then
echo "=== QEMU Serial Output ==="
cat build/logs/serial.log
else
echo "No serial output captured"
fi
- name: Upload screenshot
if: always()
uses: actions/upload-artifact@v4
with:
name: qemu-screenshot
path: build/logs/qemu-screenshot.png
if-no-files-found: warn
- name: Upload serial log
if: always()
uses: actions/upload-artifact@v4
with:
name: serial-log
path: build/logs/serial.log
if-no-files-found: warn
- name: Upload built disk image
if: always()
uses: actions/upload-artifact@v4
with:
name: metalos-disk-image
path: build/build/metalos.img
if-no-files-found: warn