feat(mqtt): per-topic control, CW keyer, radio state, AX.25, debug logging #3307
Workflow file for this run
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: CI | |
| on: | |
| pull_request: | |
| branches: [main] | |
| # Post-merge guard. We dropped the "Require branches up to date before | |
| # merging" branch-protection bit because it forced a CI rerun on every | |
| # PR whenever main moved (~15–25 min × N stale PRs per batch day). | |
| # The trade-off is: CI now runs on the merged commit itself, so any | |
| # semantic conflict that slipped past three-way merge surfaces on main | |
| # within ~10 min and triggers normal failure notifications. | |
| push: | |
| branches: [main] | |
| # Least-privilege GITHUB_TOKEN. CI only needs to read repo contents to | |
| # build and test — no writes, no token-bearing API calls. Any future job | |
| # that needs more (e.g. publishing a comment) must opt in at the job level. | |
| permissions: | |
| contents: read | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| container: ghcr.io/ten9876/aethersdr-ci:latest | |
| steps: | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - name: Setup DeepFilterNet3 (DFNR) | |
| run: bash scripts/setup/setup-deepfilter.sh | |
| - name: Configure | |
| run: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo | |
| - name: Build | |
| run: cmake --build build -j$(nproc) | |
| # Cross-platform build check — runs on every PR (no path gating). | |
| # | |
| # History: previously gated by a `check-paths` job on a hand-maintained | |
| # allow-list of files known to carry `#ifdef Q_OS_WIN` / `Q_OS_MAC` | |
| # branches (CMakeLists, third_party/, workflows, MainWindow, | |
| # AudioEngine). The allow-list was a chronic leaker — every time a | |
| # new platform-guarded path got added to a different file, the gap | |
| # surfaced as a release-time regression: #796 (origin), #2671 | |
| # (MainWindow added after a miss), #3052 (AudioEngine added after a | |
| # miss), #3210 (re-added after relapse), the v26.5.3 | |
| # ClientPhaseRotator.cpp M_PI MSVC break, and the CwSidetonePortAudioSink | |
| # WASAPI fix in #3241 (Windows-only logic never compiled by CI). An | |
| # always-on rule trades ~15-20 min of runner time per PR for a category | |
| # of regression we kept paying for. | |
| # | |
| # Caching strategy: | |
| # * Qt install — handled by jurplel/install-qt-action's cache: true | |
| # * FFTW3 third_party — actions/cache, keyed on the setup script + version | |
| # * MSVC object files — sccache via GitHub Actions cache backend | |
| # Net effect: cold cache ~5 min, warm cache ~2-3 min (was ~14 min). | |
| check-windows: | |
| runs-on: windows-latest | |
| env: | |
| SCCACHE_GHA_ENABLED: 'true' | |
| steps: | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - name: Install Qt | |
| uses: jurplel/install-qt-action@48d3ad6db93f3627c8ee7a0454bc6f3744f7e730 # v4.3.1 | |
| with: | |
| # 6.8.3 matches what community Windows builders are running and | |
| # exposes Qt 6.8.x MOC volume so we catch issues like #1910 (MSVC | |
| # COFF section limit, fixed by /bigobj) before they reach users. | |
| version: '6.8.3' | |
| modules: 'qtmultimedia qtwebsockets qtserialport qtshadertools' | |
| cache: true | |
| - name: Cache FFTW3 | |
| uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 | |
| with: | |
| path: third_party/fftw3 | |
| key: ${{ runner.os }}-fftw3-3.3.5-${{ hashFiles('scripts/setup/setup-fftw.ps1') }} | |
| - name: Install FFTW3 | |
| shell: pwsh | |
| run: .\scripts\setup\setup-fftw.ps1 | |
| - name: Setup DeepFilterNet3 (DFNR) | |
| shell: pwsh | |
| run: .\scripts\setup\setup-deepfilter.ps1 | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 | |
| # CMAKE_CXX_COMPILER_LAUNCHER is honoured by Ninja and Make | |
| # generators, NOT by the Visual Studio / MSBuild generator that | |
| # CMake selects by default on windows-latest. Switch to Ninja so | |
| # cl.exe invocations actually route through sccache. msvc-dev-cmd | |
| # puts the MSVC toolchain on PATH (cl.exe, link.exe, etc.) so | |
| # Ninja can find them. | |
| - name: Setup MSVC environment | |
| uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1 | |
| with: | |
| arch: x64 | |
| - name: Setup hidapi (HID encoder support) | |
| # Needed for the Ulanzi Dial Windows backend (#3239) and the | |
| # existing USB HID encoders (#3171). Without this, HAVE_HIDAPI | |
| # is undefined and the dial code falls back to a stub — CI | |
| # would miss real compile errors in that path. Runs after | |
| # msvc-dev-cmd so the script has cl.exe + link.exe on PATH. | |
| shell: pwsh | |
| run: .\scripts\setup\setup-hidapi.ps1 | |
| # zlib is bundled under third_party/zlib (1.3.1) — no vcpkg install | |
| # needed; CMake builds zlibstatic from source. (#2651) | |
| # Verify sccache can actually compile through the backend. GitHub | |
| # Actions Cache occasionally has outages; when that happens, sccache's | |
| # GHA backend can't read/write and every compile through sccache | |
| # fails. Pre-flight a tiny test compile so we can fall through to a | |
| # plain build instead of failing the whole job. | |
| - name: Test sccache health | |
| id: sccache_health | |
| shell: pwsh | |
| continue-on-error: true | |
| run: | | |
| 'int main(){return 0;}' | Out-File -Encoding ASCII test.cpp | |
| sccache cl /c test.cpp /Fo:test.obj 2>&1 | Tee-Object -Variable scOut | |
| $exit = $LASTEXITCODE | |
| Remove-Item test.cpp,test.obj -ErrorAction SilentlyContinue | |
| if ($exit -eq 0) { | |
| "healthy=true" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
| Write-Host "sccache OK" | |
| } else { | |
| "healthy=false" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
| Write-Host "::warning::sccache unhealthy (exit $exit) — building without compiler cache" | |
| } | |
| - name: Configure | |
| shell: pwsh | |
| run: | | |
| $launcher = "${{ steps.sccache_health.outputs.healthy }}" -eq "true" | |
| $cargs = @( | |
| "-B","build","-G","Ninja", | |
| "-DCMAKE_BUILD_TYPE=Release", | |
| "-DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=Embedded", | |
| "-DCMAKE_TOOLCHAIN_FILE=$env:CMAKE_TOOLCHAIN_FILE", | |
| "-DVCPKG_TARGET_TRIPLET=$env:VCPKG_TARGET_TRIPLET" | |
| ) | |
| if ($launcher) { | |
| $cargs += "-DCMAKE_C_COMPILER_LAUNCHER=sccache" | |
| $cargs += "-DCMAKE_CXX_COMPILER_LAUNCHER=sccache" | |
| } | |
| & cmake @cargs | |
| - name: Build Opus (RADE dependency) | |
| # ExternalProject dependency ordering via BUILD_BYPRODUCTS is correct, | |
| # but a separate step gives clearer CI failure attribution and avoids | |
| # any Ninja parallel-build ordering edge cases with IMPORTED targets. | |
| run: cmake --build build --target build_opus -j $env:NUMBER_OF_PROCESSORS | |
| - name: Build | |
| run: cmake --build build -j $env:NUMBER_OF_PROCESSORS | |
| - name: sccache stats | |
| if: always() | |
| run: sccache --show-stats | |
| # macOS build check — runs on every PR (no path gating), same rationale | |
| # as check-windows above. Catches Q_OS_MAC / CoreAudio / Cocoa-bridge | |
| # breakage that Linux clang misses, which is otherwise only discovered | |
| # at release tag time by macos-dmg.yml. Build-only (no code signing, | |
| # no DMG, no notarization — those stay in macos-dmg.yml on tag push). | |
| # Apple Silicon runner only; Intel coverage remains release-time-only. | |
| check-macos: | |
| runs-on: macos-15 | |
| steps: | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| - name: Install dependencies via Homebrew | |
| # Mirrors macos-dmg.yml's apple-silicon path. Homebrew Qt targets | |
| # the current OS, which is fine for the arm64 CI check; deployment- | |
| # target pinning is a release-time concern handled in macos-dmg.yml. | |
| run: | | |
| brew install ninja qt@6 qtkeychain fftw portaudio hidapi \ | |
| autoconf automake libtool | |
| - name: Setup DeepFilterNet3 (DFNR) | |
| run: bash scripts/setup/setup-deepfilter.sh | |
| - name: Set up ccache | |
| uses: hendrikmuhs/ccache-action@d62db5f07c26379fc4b4e0916f098a92573c3b03 # v1.2.23 | |
| with: | |
| key: ccache-macos-ci | |
| max-size: 500M | |
| - name: Configure | |
| run: | | |
| cmake -B build -G Ninja \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_C_COMPILER_LAUNCHER=ccache \ | |
| -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ | |
| -DCMAKE_PREFIX_PATH="$(brew --prefix qt@6);$(brew --prefix)" \ | |
| -DMQTT_TLS=OFF | |
| - name: Build Opus (RADE dependency) | |
| run: cmake --build build --target build_opus -j$(sysctl -n hw.ncpu) | |
| - name: Build | |
| run: cmake --build build -j$(sysctl -n hw.ncpu) |