docs(papr): ACE rig A/B result — safe (guaranteed non-negative) but +… #435
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: Build Matrix | |
| on: | |
| workflow_dispatch: | |
| pull_request: | |
| branches: | |
| - main | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - "v*" | |
| - "0.2.0-alpha*" | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: build-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| test: | |
| name: Test (${{ matrix.target }}) | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| target: linux | |
| - os: macos-latest | |
| target: macos | |
| - os: windows-latest | |
| target: windows | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| persist-credentials: false | |
| - name: Install Test Dependencies (Linux) | |
| if: runner.os == 'Linux' | |
| run: > | |
| sudo apt-get update && sudo apt-get install -y | |
| libhamlib-dev | |
| libgrpc++-dev | |
| libprotobuf-dev | |
| protobuf-compiler | |
| protobuf-compiler-grpc | |
| libabsl-dev | |
| libc-ares-dev | |
| libre2-dev | |
| - name: Install Test Dependencies (macOS) | |
| if: runner.os == 'macOS' | |
| run: brew install hamlib grpc protobuf abseil c-ares | |
| - name: Read vcpkg Version (Windows) | |
| if: runner.os == 'Windows' | |
| id: vcpkg-version | |
| shell: pwsh | |
| run: | | |
| $sha = git -C $env:VCPKG_INSTALLATION_ROOT rev-parse HEAD | |
| "sha=$sha" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append | |
| - name: Cache vcpkg Binaries (Windows) | |
| if: runner.os == 'Windows' | |
| uses: actions/cache@v4 | |
| with: | |
| path: ${{ github.workspace }}/vcpkg-cache | |
| key: vcpkg-${{ runner.os }}-${{ steps.vcpkg-version.outputs.sha }}-${{ hashFiles('.github/workflows/build-matrix.yml', 'CMakeLists.txt') }} | |
| restore-keys: | | |
| vcpkg-${{ runner.os }}-${{ steps.vcpkg-version.outputs.sha }}- | |
| - name: Free Disk Space (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| Get-PSDrive C, D | Format-Table -Property Name, @{n="FreeGB";e={[math]::Round($_.Free/1GB,1)}}, @{n="UsedGB";e={[math]::Round($_.Used/1GB,1)}} | |
| $targets = @( | |
| "C:\Android", | |
| "C:\Program Files (x86)\Android", | |
| "C:\Program Files\dotnet\sdk\NuGetFallbackFolder", | |
| "C:\hostedtoolcache\windows\go", | |
| "C:\hostedtoolcache\windows\Ruby", | |
| "C:\hostedtoolcache\windows\PyPy", | |
| "C:\hostedtoolcache\windows\Java_Temurin-Hotspot_jdk", | |
| "C:\ProgramData\chocolatey\lib\mingw", | |
| "C:\ProgramData\chocolatey\lib\android-sdk", | |
| "C:\ghcup" | |
| ) | |
| foreach ($t in $targets) { | |
| if (Test-Path $t) { | |
| Write-Host "Removing $t ..." | |
| Remove-Item -Path $t -Recurse -Force -ErrorAction SilentlyContinue | |
| } | |
| } | |
| Get-PSDrive C, D | Format-Table -Property Name, @{n="FreeGB";e={[math]::Round($_.Free/1GB,1)}}, @{n="UsedGB";e={[math]::Round($_.Used/1GB,1)}} | |
| - name: Install Test Dependencies (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| New-Item -ItemType Directory -Force "${{ github.workspace }}/vcpkg-cache" | Out-Null | |
| New-Item -ItemType Directory -Force "D:/vcpkg-bt" | Out-Null | |
| $env:VCPKG_BINARY_SOURCES = "clear;files,${{ github.workspace }}/vcpkg-cache,readwrite" | |
| vcpkg install grpc:x64-windows --x-buildtrees-root=D:/vcpkg-bt --clean-after-build | |
| "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
| - name: Configure CMake (Linux/macOS) | |
| if: runner.os != 'Windows' | |
| run: > | |
| cmake -S . -B build | |
| -DCMAKE_BUILD_TYPE=Debug | |
| -DULTRA_BUILD_TESTS=ON | |
| -DULTRA_BUILD_TOOLS=OFF | |
| -DULTRA_BUILD_GUI=OFF | |
| -DULTRA_USE_FFTW=OFF | |
| -DULTRA_FETCH_GRPC=OFF | |
| - name: Configure CMake (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: > | |
| cmake -S . -B build -A x64 | |
| -DULTRA_BUILD_TESTS=ON | |
| -DULTRA_BUILD_TOOLS=OFF | |
| -DULTRA_BUILD_GUI=OFF | |
| -DULTRA_USE_FFTW=OFF | |
| -DULTRA_FETCH_GRPC=OFF | |
| -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" | |
| -DVCPKG_TARGET_TRIPLET=x64-windows | |
| - name: Build Tests (Linux/macOS) | |
| if: runner.os != 'Windows' | |
| # --parallel 2: the ubuntu runner (2 vCPU / ~7 GB) OOM-kills cc1plus | |
| # when two heavy test TUs build concurrently (test_watterson_proof + | |
| # test_ofdm_snr_calibration, each compiling the full streaming-decoder | |
| # set — 2026-07-08 run 28916672556). Same bound as the sanitizer job. | |
| run: cmake --build build --parallel 2 | |
| - name: Build Tests (Windows) | |
| if: runner.os == 'Windows' | |
| # --parallel 2: vcpkg's z-applocal post-build step copies the SAME | |
| # runtime DLLs into the shared tests/Debug output dir for every test | |
| # target — at full parallelism two copies collide ("file is being used | |
| # by another process", run 28949911161). Two concurrent post-builds | |
| # make the race effectively improbable; same bound as Linux. | |
| run: cmake --build build --config Debug --parallel 2 | |
| - name: Run CTest (Linux/macOS) | |
| if: runner.os != 'Windows' | |
| run: ctest --test-dir build --output-on-failure --parallel 4 | |
| - name: Run CTest (Windows) | |
| if: runner.os == 'Windows' | |
| run: ctest --test-dir build -C Debug --output-on-failure --parallel 4 | |
| sanitizer: | |
| name: Sanitizer (linux) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| persist-credentials: false | |
| - name: Install Dependencies | |
| run: > | |
| sudo apt-get update && sudo apt-get install -y | |
| libhamlib-dev | |
| libgrpc++-dev | |
| libprotobuf-dev | |
| protobuf-compiler | |
| protobuf-compiler-grpc | |
| libabsl-dev | |
| libc-ares-dev | |
| libre2-dev | |
| - name: Configure ASAN/UBSAN | |
| run: > | |
| cmake -S . -B build-sanitizer | |
| -DCMAKE_BUILD_TYPE=Debug | |
| -DULTRA_BUILD_TESTS=ON | |
| -DULTRA_BUILD_TOOLS=OFF | |
| -DULTRA_BUILD_GUI=OFF | |
| -DULTRA_USE_FFTW=OFF | |
| -DULTRA_FETCH_GRPC=OFF | |
| -DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer -O1 -g1" | |
| -DCMAKE_C_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer -O1 -g1" | |
| -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address,undefined" | |
| # -O1/-g1 + capped parallelism: the full-parallel -O0/-g ASan build of the | |
| # large DSP TUs OOM-killed cc1plus on the 7 GB runner ("Killed signal | |
| # terminated program cc1plus", runs 28613422376 / 28634356779). -O1 is the | |
| # standard ASan operating point (halves cc1plus RSS and the test wall | |
| # time); -j2 bounds concurrent peak. | |
| - name: Build ASAN/UBSAN Tests | |
| run: cmake --build build-sanitizer --parallel 2 | |
| - name: Run ASAN/UBSAN CTest | |
| env: | |
| ASAN_OPTIONS: detect_leaks=1:halt_on_error=1 | |
| UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1 | |
| LSAN_OPTIONS: suppressions=${{ github.workspace }}/tests/lsan_suppressions.txt:print_suppressions=0 | |
| run: ctest --test-dir build-sanitizer --output-on-failure --parallel 4 | |
| coverage: | |
| name: Coverage (linux) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| persist-credentials: false | |
| - name: Install Coverage Toolchain | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| clang \ | |
| llvm \ | |
| libhamlib-dev \ | |
| libgrpc++-dev \ | |
| libprotobuf-dev \ | |
| protobuf-compiler \ | |
| protobuf-compiler-grpc \ | |
| libabsl-dev \ | |
| libc-ares-dev \ | |
| libre2-dev | |
| - name: Run Coverage Gate | |
| env: | |
| CC: clang | |
| CXX: clang++ | |
| LLVM_COV: llvm-cov | |
| LLVM_PROFDATA: llvm-profdata | |
| run: ./scripts/coverage_report.sh | |
| build: | |
| name: Build (${{ matrix.target }}) | |
| needs: | |
| - test | |
| - sanitizer | |
| - coverage | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| target: linux | |
| - os: macos-latest | |
| target: macos | |
| - os: windows-latest | |
| target: windows | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| persist-credentials: false | |
| - name: Install Linux GUI Dependencies | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| libsdl2-dev \ | |
| libgl1-mesa-dev \ | |
| libhamlib-dev \ | |
| libgrpc++-dev \ | |
| libprotobuf-dev \ | |
| protobuf-compiler \ | |
| protobuf-compiler-grpc \ | |
| libabsl-dev \ | |
| libc-ares-dev \ | |
| libre2-dev | |
| - name: Install macOS GUI Dependencies | |
| if: runner.os == 'macOS' | |
| run: brew install sdl2 hamlib grpc protobuf abseil c-ares | |
| - name: Read vcpkg Version (Windows) | |
| if: runner.os == 'Windows' | |
| id: vcpkg-version | |
| shell: pwsh | |
| run: | | |
| $sha = git -C $env:VCPKG_INSTALLATION_ROOT rev-parse HEAD | |
| "sha=$sha" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append | |
| - name: Cache vcpkg Binaries (Windows) | |
| if: runner.os == 'Windows' | |
| uses: actions/cache@v4 | |
| with: | |
| path: ${{ github.workspace }}/vcpkg-cache | |
| key: vcpkg-${{ runner.os }}-${{ steps.vcpkg-version.outputs.sha }}-${{ hashFiles('.github/workflows/build-matrix.yml', 'CMakeLists.txt') }} | |
| restore-keys: | | |
| vcpkg-${{ runner.os }}-${{ steps.vcpkg-version.outputs.sha }}- | |
| - name: Free Disk Space (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| Get-PSDrive C, D | Format-Table -Property Name, @{n="FreeGB";e={[math]::Round($_.Free/1GB,1)}}, @{n="UsedGB";e={[math]::Round($_.Used/1GB,1)}} | |
| $targets = @( | |
| "C:\Android", | |
| "C:\Program Files (x86)\Android", | |
| "C:\Program Files\dotnet\sdk\NuGetFallbackFolder", | |
| "C:\hostedtoolcache\windows\go", | |
| "C:\hostedtoolcache\windows\Ruby", | |
| "C:\hostedtoolcache\windows\PyPy", | |
| "C:\hostedtoolcache\windows\Java_Temurin-Hotspot_jdk", | |
| "C:\ProgramData\chocolatey\lib\mingw", | |
| "C:\ProgramData\chocolatey\lib\android-sdk", | |
| "C:\ghcup" | |
| ) | |
| foreach ($t in $targets) { | |
| if (Test-Path $t) { | |
| Write-Host "Removing $t ..." | |
| Remove-Item -Path $t -Recurse -Force -ErrorAction SilentlyContinue | |
| } | |
| } | |
| Get-PSDrive C, D | Format-Table -Property Name, @{n="FreeGB";e={[math]::Round($_.Free/1GB,1)}}, @{n="UsedGB";e={[math]::Round($_.Used/1GB,1)}} | |
| - name: Install Windows GUI Dependencies | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| New-Item -ItemType Directory -Force "${{ github.workspace }}/vcpkg-cache" | Out-Null | |
| New-Item -ItemType Directory -Force "D:/vcpkg-bt" | Out-Null | |
| $env:VCPKG_BINARY_SOURCES = "clear;files,${{ github.workspace }}/vcpkg-cache,readwrite" | |
| vcpkg install sdl2:x64-windows grpc:x64-windows --x-buildtrees-root=D:/vcpkg-bt --clean-after-build | |
| "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
| - name: Configure CMake (Linux/macOS) | |
| if: runner.os != 'Windows' | |
| run: > | |
| cmake -S . -B build | |
| -DCMAKE_BUILD_TYPE=Release | |
| -DULTRA_BUILD_TESTS=OFF | |
| -DULTRA_BUILD_GUI=ON | |
| -DULTRA_USE_FFTW=OFF | |
| -DULTRA_FETCH_GRPC=OFF | |
| - name: Configure CMake (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: > | |
| cmake -S . -B build -A x64 | |
| -DCMAKE_BUILD_TYPE=Release | |
| -DULTRA_BUILD_TESTS=OFF | |
| -DULTRA_BUILD_GUI=ON | |
| -DULTRA_USE_FFTW=OFF | |
| -DULTRA_FETCH_GRPC=OFF | |
| -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" | |
| -DVCPKG_TARGET_TRIPLET=x64-windows | |
| - name: Build (Linux/macOS) | |
| if: runner.os != 'Windows' | |
| run: cmake --build build --parallel | |
| - name: Build (Windows) | |
| if: runner.os == 'Windows' | |
| run: cmake --build build --config Release --parallel | |
| - name: Collect Bundle Files | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| ./packaging/package_operator_bundle.sh build "${{ matrix.target }}" package | |
| ls -la "package/projectultra-${{ matrix.target }}" | |
| ls -la "package/dev-tools-${{ matrix.target }}" | |
| - name: Create ZIP Bundle (Linux/macOS) | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| cd package | |
| zip -r "projectultra-${{ matrix.target }}.zip" "projectultra-${{ matrix.target }}" | |
| zip -r "dev-tools-${{ matrix.target }}.zip" "dev-tools-${{ matrix.target }}" | |
| - name: Create ZIP Bundle (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| Compress-Archive -Path "package/projectultra-windows/*" -DestinationPath "package/projectultra-windows.zip" -Force | |
| Compress-Archive -Path "package/dev-tools-windows/*" -DestinationPath "package/dev-tools-windows.zip" -Force | |
| - name: Upload Operator Bundle Artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: projectultra-${{ matrix.target }} | |
| path: package/projectultra-${{ matrix.target }}.zip | |
| if-no-files-found: error | |
| - name: Upload Dev Tools Artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dev-tools-${{ matrix.target }} | |
| path: package/dev-tools-${{ matrix.target }}.zip | |
| if-no-files-found: error | |
| release: | |
| name: Publish Release Assets | |
| if: startsWith(github.ref, 'refs/tags/') | |
| runs-on: ubuntu-latest | |
| needs: build | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Download Build Artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: projectultra-* | |
| path: release-artifacts | |
| merge-multiple: true | |
| - name: Publish GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: release-artifacts/*.zip | |
| generate_release_notes: true | |
| prerelease: ${{ contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta') || contains(github.ref_name, 'rc') }} |