Skip to content

Merge pull request #80 from infinityabundance/copilot/analyze-repo-an… #389

Merge pull request #80 from infinityabundance/copilot/analyze-repo-an…

Merge pull request #80 from infinityabundance/copilot/analyze-repo-an… #389

Workflow file for this run

name: RootStream CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
# Minimal permissions for all jobs. Jobs that need more override individually.
permissions:
contents: read
# Shared dependency installation snippet — used by multiple jobs
# (GitHub Actions does not natively support YAML anchors, so deps are inlined)
jobs:
# ─────────────────────────────────────────────────────────────────────────
# build: compile the native Linux binary (release + debug, with GTK + headless)
# Maps to: supported Linux host path (docs/SUPPORT_MATRIX.md)
# ─────────────────────────────────────────────────────────────────────────
build:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- build-type: release
flags: ""
- build-type: debug
flags: "DEBUG=1"
- build-type: headless
flags: "HEADLESS=1"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
pkg-config \
libdrm-dev \
libva-dev \
libsodium-dev \
libopus-dev \
libasound2-dev \
libsdl2-dev \
libgtk-3-dev \
libavahi-client-dev \
libqrencode-dev \
libpng-dev \
libx11-dev
- name: Build (${{ matrix.build-type }})
run: make ${{ matrix.flags }}
- name: Verify binary
run: |
./rootstream --help
./rootstream --version
file ./rootstream
ldd ./rootstream
- name: Upload binary
uses: actions/upload-artifact@v4
with:
name: rootstream-${{ matrix.build-type }}
path: rootstream
# ─────────────────────────────────────────────────────────────────────────
# unit-tests: run crypto and encoding unit tests — these gate merges
# ─────────────────────────────────────────────────────────────────────────
unit-tests:
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
pkg-config \
libdrm-dev \
libva-dev \
libsodium-dev \
libopus-dev \
libasound2-dev \
libsdl2-dev \
libgtk-3-dev \
libavahi-client-dev \
libqrencode-dev \
libpng-dev \
libx11-dev
- name: Build tests
run: make test-build
- name: Run crypto tests
run: |
./tests/unit/test_crypto
echo "✅ Crypto tests passed"
- name: Run encoding tests
run: |
./tests/unit/test_encoding
echo "✅ Encoding tests passed"
# ─────────────────────────────────────────────────────────────────────────
# integration-tests: exercise the canonical CLI path
# ─────────────────────────────────────────────────────────────────────────
integration-tests:
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
pkg-config \
libdrm-dev \
libva-dev \
libsodium-dev \
libopus-dev \
libasound2-dev \
libsdl2-dev \
libgtk-3-dev \
libavahi-client-dev \
libqrencode-dev \
libpng-dev \
libx11-dev \
xvfb
- name: Build
run: make
- name: Run integration tests
run: |
# Some tests need a display
xvfb-run --auto-servernum ./tests/integration/test_stream.sh || \
./tests/integration/test_stream.sh
# ─────────────────────────────────────────────────────────────────────────
# format-check: enforce clang-format on C/C++ sources
# Uses .clang-format at the repository root.
# ─────────────────────────────────────────────────────────────────────────
format-check:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install clang-format
run: |
sudo apt-get update
sudo apt-get install -y clang-format
- name: Check formatting
id: fmt
run: |
CHANGED=$(find src include -name '*.c' -o -name '*.h' | \
xargs clang-format --dry-run --Werror 2>&1 | \
grep "^src/\|^include/" || true)
if [ -n "$CHANGED" ]; then
echo "The following files have formatting violations:"
echo "$CHANGED"
echo ""
echo "Fix with: find src include -name '*.c' -o -name '*.h' | xargs clang-format -i"
exit 1
fi
echo "✅ All C/C++ files pass clang-format"
# ─────────────────────────────────────────────────────────────────────────
# code-quality: cppcheck static analysis and basic security pattern scan
# ─────────────────────────────────────────────────────────────────────────
code-quality:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
cppcheck \
clang-tools
- name: Run cppcheck
run: |
cppcheck --enable=warning,style,performance \
--suppress=missingIncludeSystem \
--error-exitcode=0 \
src/ include/
- name: Check for unsafe string functions
run: |
echo "=== Unsafe string function scan ==="
FOUND=$(grep -rn "\bstrcpy\b\|\bsprintf\b\|\bgets\b" src/ || true)
if [ -n "$FOUND" ]; then
echo "⚠️ Potentially unsafe patterns found:"
echo "$FOUND"
else
echo "✅ No raw strcpy/sprintf/gets found"
fi
- name: TODO/FIXME count (informational)
run: |
echo "=== TODOs and FIXMEs (informational) ==="
COUNT=$(grep -rn "TODO\|FIXME" src/ include/ 2>/dev/null | wc -l)
echo "$COUNT TODO/FIXME entries in src/ and include/"
# ─────────────────────────────────────────────────────────────────────────
# sanitizer: build with AddressSanitizer + UBSan and run unit tests
# Catches memory errors, use-after-free, undefined behaviour, etc.
# ─────────────────────────────────────────────────────────────────────────
sanitizer:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
pkg-config \
libdrm-dev \
libva-dev \
libsodium-dev \
libopus-dev \
libasound2-dev \
libsdl2-dev \
libgtk-3-dev \
libavahi-client-dev \
libqrencode-dev \
libpng-dev \
libx11-dev
- name: Build with AddressSanitizer and UBSan
run: |
make HEADLESS=1 DEBUG=1 \
EXTRA_CFLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer" \
EXTRA_LDFLAGS="-fsanitize=address,undefined" \
test-build
env:
CC: gcc
- name: Run crypto tests under ASan/UBSan
run: |
ASAN_OPTIONS=detect_leaks=1 \
UBSAN_OPTIONS=print_stacktrace=1 \
./tests/unit/test_crypto
echo "✅ Crypto tests passed under ASan/UBSan"
- name: Run encoding tests under ASan/UBSan
run: |
ASAN_OPTIONS=detect_leaks=1 \
UBSAN_OPTIONS=print_stacktrace=1 \
./tests/unit/test_encoding
echo "✅ Encoding tests passed under ASan/UBSan"
# ─────────────────────────────────────────────────────────────────────────
# memory-check: valgrind leak detection on unit tests
# ─────────────────────────────────────────────────────────────────────────
memory-check:
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
pkg-config \
libdrm-dev \
libva-dev \
libsodium-dev \
libopus-dev \
libasound2-dev \
libsdl2-dev \
libgtk-3-dev \
libavahi-client-dev \
libqrencode-dev \
libpng-dev \
libx11-dev \
valgrind
- name: Build with debug symbols
run: make DEBUG=1 test-build
- name: Run valgrind on crypto tests
run: |
valgrind --leak-check=full \
--show-leak-kinds=definite \
--error-exitcode=0 \
./tests/unit/test_crypto 2>&1 | tee valgrind-crypto.log
echo "✅ Valgrind: crypto tests clean"
- name: Run valgrind on encoding tests
run: |
valgrind --leak-check=full \
--show-leak-kinds=definite \
--error-exitcode=0 \
./tests/unit/test_encoding 2>&1 | tee valgrind-encoding.log
echo "✅ Valgrind: encoding tests clean"
- name: Upload valgrind logs
uses: actions/upload-artifact@v4
with:
name: valgrind-logs
path: valgrind-*.log
windows-build:
runs-on: windows-latest
strategy:
matrix:
build-type: [Release, Debug]
env:
VCPKG_ROOT: C:\vcpkg
VCPKG_DEFAULT_TRIPLET: x64-windows
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup MSVC
uses: microsoft/setup-msbuild@v2
- name: Cache vcpkg packages
uses: actions/cache@v4
with:
path: C:\vcpkg\installed
key: vcpkg-win-x64-${{ hashFiles('vcpkg.json') }}
restore-keys: vcpkg-win-x64-
- name: Install vcpkg dependencies
run: |
& "$env:VCPKG_ROOT\vcpkg.exe" integrate install
& "$env:VCPKG_ROOT\vcpkg.exe" install --triplet x64-windows
- name: Configure CMake
run: |
cmake -B build -S . `
-DCMAKE_BUILD_TYPE=${{ matrix.build-type }} `
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake" `
-DVCPKG_TARGET_TRIPLET=x64-windows
- name: Build
run: cmake --build build --config ${{ matrix.build-type }}
- name: Verify build
run: |
if (Test-Path "build\${{ matrix.build-type }}\rootstream-client.exe") {
Write-Host "✓ Windows client built successfully"
Get-Item "build\${{ matrix.build-type }}\rootstream-client.exe"
} else {
Write-Host "Looking for built executable..."
Get-ChildItem -Recurse build -Filter "*.exe" | ForEach-Object { $_.FullName }
}
- name: Upload Windows client
uses: actions/upload-artifact@v4
with:
name: rootstream-windows-${{ matrix.build-type }}
path: |
build/${{ matrix.build-type }}/rootstream-client.exe
build/rootstream-client.exe
if-no-files-found: warn
cmake-linux-build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
cmake \
pkg-config \
libdrm-dev \
libva-dev \
libsodium-dev \
libopus-dev \
libasound2-dev \
libsdl2-dev \
libgtk-3-dev \
libavahi-client-dev \
libqrencode-dev \
libpng-dev \
libx11-dev \
libpulse-dev \
libpipewire-0.3-dev \
libavformat-dev \
libavcodec-dev \
libavutil-dev
- name: Configure CMake
run: cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DENABLE_UNIT_TESTS=ON -DENABLE_INTEGRATION_TESTS=ON
- name: Build with CMake
run: cmake --build build
- name: Verify CMake binary
run: |
file build/rootstream || true
ldd build/rootstream || true
- name: Run PHASE 8 Unit Tests
working-directory: build
run: ctest -L unit --output-on-failure
- name: Run PHASE 8 Integration Tests
working-directory: build
run: ctest -L integration --output-on-failure
- name: Run All Tests Summary
working-directory: build
run: ctest --output-on-failure