| name | github-workflow-authoring |
| description | This skill should be used when creating or improving GitHub Actions CI/CD workflows for Breenix kernel development. Use for authoring new test workflows, optimizing existing CI pipelines, adding new test types, fixing workflow configuration issues, or adapting workflows for new kernel features. |
GitHub Workflow Authoring for Breenix
Create and improve GitHub Actions workflows for Breenix OS kernel development and testing.
Purpose
This skill provides patterns, templates, and best practices for authoring GitHub Actions workflows specifically for Breenix kernel development. It addresses the unique challenges of OS kernel CI/CD: QEMU virtualization, custom Rust targets, userspace binary building, timeout management, and kernel-specific test patterns.
When to Use This Skill
Use this skill when:
- Creating new test workflows: Adding CI for new kernel features or test suites
- Optimizing CI performance: Reducing build times, improving caching, tuning timeouts
- Fixing CI failures: Workflow configuration issues, missing dependencies, wrong environment
- Adapting workflows: Modifying workflows for new kernel capabilities or test requirements
- Debugging CI issues: Understanding why workflows fail, reproducing issues locally
- Adding test coverage: Expanding CI to cover more kernel subsystems or scenarios
Key Breenix CI Patterns
Rust Toolchain Requirements
Breenix requires specific Rust configuration:
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: nightly-2025-06-24 # Pinned for consistency
override: true
target: x86_64-unknown-none # Custom kernel target
components: rust-src, llvm-tools-preview
Critical: The Rust nightly version is pinned to avoid unexpected breakage from compiler changes.
System Dependencies
All kernel tests require QEMU and supporting tools:
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
qemu-system-x86 \
qemu-utils \
ovmf \
mtools \
dosfstools \
xorriso \
nasm \
lld
Userspace Binary Building
CRITICAL: Before running kernel tests that execute userspace code, userspace binaries must be built:
- name: Build userspace tests
run: |
export PATH="$PATH:$(rustc --print sysroot)/lib/rustlib/x86_64-unknown-linux-gnu/bin"
cd userspace/tests
./build.sh
Forgetting this step causes kernel tests to fail mysteriously!
Using xtask for Tests
Breenix uses the xtask pattern for complex test workflows:
- name: Run Ring-3 smoke test
run: cargo run -p xtask -- ring3-smoke
This handles:
- Building the kernel with correct features
- Starting QEMU with appropriate flags
- Monitoring serial output for success signals
- Timeout management (30s local, 60s CI)
- Cleanup and artifact collection
Timeout Strategies
Different workflows need different timeouts:
jobs:
quick-test:
timeout-minutes: 20 # Build + simple smoke test
full-integration:
timeout-minutes: 45 # Complete test suite with shared QEMU
code-quality:
timeout-minutes: 15 # Clippy and static analysis
Rule of thumb: CI environments are 2-3x slower than local development machines. Budget accordingly.
Caching for Performance
Proper caching reduces build times from ~10 minutes to ~2 minutes:
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}
Cache invalidates when Cargo.lock changes, ensuring fresh builds for dependency updates.
Log Artifact Upload
Always upload logs, especially on failure:
- name: Upload logs
if: always() # Run even if previous steps failed
uses: actions/upload-artifact@v4
with:
name: breenix-logs
path: |
logs/*.log
target/xtask_ring3_smoke_output.txt
target/xtask_ring3_enosys_output.txt
if-no-files-found: ignore
retention-days: 7
This enables post-mortem analysis of failed runs.
Workflow Patterns
Pattern 1: Smoke Test (Fast Feedback)
Runs on every push to provide quick feedback:
name: Ring-3 Smoke Test
on:
push:
branches: [ "**" ]
pull_request:
jobs:
ring3-smoke:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- name: Install Rust
# ... (see above)
- name: Cache cargo
# ... (see above)
- name: Install system dependencies
# ... (see above)
- name: Build userspace tests
# ... (see above)
- name: Run smoke test
run: cargo run -p xtask -- ring3-smoke
- name: Upload logs
if: always()
# ... (see above)
Purpose: Verify basic kernel functionality (boot, userspace execution) quickly.
Pattern 2: Code Quality (Static Analysis)
Runs on kernel code changes:
name: Code Quality
on:
push:
paths:
- 'kernel/**'
- '.github/workflows/code-quality.yml'
jobs:
clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
with:
components: clippy, rust-src
- name: Run Clippy
run: |
cd kernel
cargo clippy --target x86_64-unknown-none \
-- -Dclippy::debug_assert_with_mut_call
Purpose: Catch code quality issues before they reach main branch.
Pattern 3: Manual Trigger (Expensive Tests)
For tests that take too long to run on every commit:
name: Full Integration Tests
on:
workflow_dispatch: # Only run manually
jobs:
integration:
timeout-minutes: 45
# ... full test suite
Purpose: Comprehensive testing before releases or major merges.
Reference Files
The skill includes reference material in the references/ directory:
breenix-ci-patterns.md: Comprehensive CI patterns, timeout strategies, caching, success signals
To reference these during workflow authoring:
cat github-workflow-authoring/references/breenix-ci-patterns.md
Workflow Creation Process
When creating a new workflow:
- Identify the test type: Smoke test, integration test, static analysis, etc.
- Determine trigger: Every push, PR only, manual, or path-specific
- Set appropriate timeout: Based on test complexity and CI overhead
- Copy template from existing workflow: Start with
ring3-smoke.ymlorcode-quality.yml - Customize steps: Add specific build steps, test commands, or checks
- Add caching: Use cargo cache unless testing cache-sensitive issues
- Configure artifact upload: Always include logs for debugging
- Test locally first: Use the same commands that will run in CI
- Add to PR: Update .github/workflows/ and create PR for review
- Monitor first runs: Watch for environment-specific issues
Common Workflow Issues and Fixes
Issue: "rustup: command not found"
Cause: Rust toolchain not installed or wrong action version
Fix: Use actions-rs/toolchain@v1 or dtolnay/rust-toolchain
Issue: "error: target 'x86_64-unknown-none' may not be installed"
Cause: Missing custom target
Fix: Add target: x86_64-unknown-none to toolchain setup
Issue: "error: could not compile bootloader"
Cause: Missing rust-src component
Fix: Add rust-src to components list
Issue: "qemu-system-x86_64: command not found"
Cause: QEMU not installed in CI environment Fix: Add qemu-system-x86 to apt-get install list
Issue: Test times out but works locally
Cause: CI environment slower, or test hung Fix: Increase timeout-minutes or investigate kernel hang
Issue: Cache seems corrupted
Cause: Cache key collision or partial build artifacts Fix: Change cache key (add version suffix) or clear cache
Issue: Userspace test fails with "file not found"
Cause: Userspace binaries not built before kernel test Fix: Add userspace build step before kernel test runs
Advanced Patterns
Matrix Builds (Future)
Test multiple configurations:
strategy:
matrix:
mode: [uefi, bios]
features: [testing, production]
steps:
- run: cargo run --bin qemu-${{ matrix.mode }} --features ${{ matrix.features }}
Conditional Steps
Skip steps based on conditions:
- name: Upload logs
if: failure() # Only on failure
# or
if: always() # Always run
# or
if: success() # Only on success
Environment-Specific Behavior
env:
CI: true
RUST_BACKTRACE: full
BREENIX_TIMEOUT: 60 # Used by xtask
Best Practices
- Pin Rust version: Avoid unexpected breakage from nightly changes
- Cache aggressively: Cargo builds are slow, caching saves 5-8 minutes
- Fail fast: Set reasonable timeouts to avoid wasting CI minutes
- Upload artifacts: Always capture logs for post-mortem analysis
- Test locally first: Run the exact commands that CI will run
- Use xtask: Complex test logic belongs in xtask, not YAML
- Monitor CI time: If workflows exceed 20-30 minutes, consider splitting
- Document workflows: Add comments explaining non-obvious steps
Integration with Breenix Development
When adding new kernel features that require CI testing:
- Identify test requirements: What needs to be verified?
- Create or extend xtask: Add new test command (e.g.,
ring3-fork-test) - Add workflow: Either extend existing or create new workflow file
- Add success signal: Add kernel log marker for test completion
- Update workflow docs: Document the new test in CLAUDE.md or README
Example: Adding a New Test Workflow
Let's say you want to add CI for testing the fork() syscall:
name: Fork System Call Test
on:
push:
paths:
- 'kernel/src/process/**'
- 'kernel/src/syscall/**'
- 'userspace/tests/fork_test*'
jobs:
fork-test:
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: nightly-2025-06-24
override: true
target: x86_64-unknown-none
components: rust-src, llvm-tools-preview
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: cargo-${{ runner.os }}-fork-${{ hashFiles('**/Cargo.lock') }}
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y qemu-system-x86 ovmf nasm
- name: Build userspace tests
run: |
export PATH="$PATH:$(rustc --print sysroot)/lib/rustlib/x86_64-unknown-linux-gnu/bin"
cd userspace/tests
./build.sh
- name: Run fork test
run: cargo run -p xtask -- fork-test
- name: Upload logs
if: always()
uses: actions/upload-artifact@v4
with:
name: fork-test-logs
path: |
logs/*.log
target/xtask_fork_test_output.txt
retention-days: 7
Then update xtask/src/main.rs:
#[derive(StructOpt)]
enum Cmd {
Ring3Smoke,
Ring3Enosys,
ForkTest, // New test
}
fn main() -> Result<()> {
match Cmd::from_args() {
Cmd::Ring3Smoke => ring3_smoke(),
Cmd::Ring3Enosys => ring3_enosys(),
Cmd::ForkTest => fork_test(),
}
}
fn fork_test() -> Result<()> {
// Similar to ring3_smoke but looks for fork-specific signals
// ...
}
Troubleshooting CI Failures
When a workflow fails:
- Download artifacts: Get the log files from the Actions run
- Search for errors: Look for panic, double fault, timeout messages
- Compare with local: Run the exact same command locally
- Check environment: Verify Rust version, QEMU version, dependencies
- Reproduce in clean environment: Use Docker or fresh VM if needed
- Use ci-failure-analysis skill: Systematic analysis of CI failures
Summary
GitHub workflow authoring for Breenix requires understanding:
- Rust nightly toolchain with custom targets
- QEMU-based kernel testing patterns
- xtask for test orchestration
- Timeout management for CI environments
- Caching strategies for performance
- Log artifact collection for debugging
Always reference the existing workflows as templates, test locally before committing, and leverage the xtask pattern for complex test logic.