feat(firmware): ActionButton — one DCS-BIOS action per press #203
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: Firmware CI | |
| on: | |
| workflow_dispatch: | |
| schedule: | |
| # Weekly full build of every firmware project (canary). | |
| - cron: "0 8 * * 0" | |
| pull_request: | |
| paths: | |
| - "Firmware/**" | |
| - "tools/check_node_ids.py" | |
| - ".github/workflows/firmware-ci.yml" | |
| permissions: | |
| contents: read | |
| jobs: | |
| node-ids: | |
| name: Validate NODE_ID registry | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Check NODE_ID assignments | |
| run: python3 tools/check_node_ids.py | |
| firmware: | |
| name: Build supported PlatformIO projects | |
| # Full build (~20 min) runs only on the weekly schedule and on manual | |
| # dispatch — never on PRs or pushes, where it was slow feedback for little | |
| # value. Trigger an on-demand build from the Actions tab ("Run workflow"). | |
| if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Select firmware projects | |
| run: | | |
| set -euo pipefail | |
| python .github/scripts/select-platformio-projects.py \ | |
| --mode full \ | |
| --output "$RUNNER_TEMP/platformio-projects.txt" | |
| - name: Cache PlatformIO toolchain | |
| uses: actions/cache@v5 | |
| with: | |
| # Cache the EXTRACTED toolchains (packages/ + platforms/) — the STM32 + | |
| # RP2040 compiler/framework install that was previously redone every run, | |
| # not just the .cache download archives. This is the multi-minute win. | |
| # We deliberately do NOT cache any project .pio/build: in-repo libraries | |
| # (Firmware/Libraries/*) recompile from source on every run, so a core- | |
| # library edit can never reuse a stale object — only the toolchain is | |
| # reused. The key still busts on any platformio.ini change | |
| # (board / platform / lib_deps). | |
| path: | | |
| ~/.platformio/packages | |
| ~/.platformio/platforms | |
| ~/.platformio/.cache | |
| key: ${{ runner.os }}-platformio-firmware-${{ hashFiles('Firmware/**/platformio.ini') }} | |
| restore-keys: | | |
| ${{ runner.os }}-platformio-firmware- | |
| ${{ runner.os }}-platformio- | |
| - name: Install PlatformIO | |
| run: | | |
| set -euo pipefail | |
| python -m pip install --upgrade pip | |
| python -m pip install platformio | |
| - name: Build firmware projects | |
| run: | | |
| set -euo pipefail | |
| logs_dir="$RUNNER_TEMP/platformio-logs/firmware" | |
| mkdir -p "$logs_dir" | |
| failed=0 | |
| found=0 | |
| while IFS= read -r project_dir; do | |
| found=1 | |
| project_ini="$project_dir/platformio.ini" | |
| log_file="$logs_dir/$(printf '%s' "$project_dir" | tr '/ ' '__').log" | |
| echo "Building $project_dir" | |
| if platformio run -d "$project_dir" > "$log_file" 2>&1; then | |
| echo "PASS $project_dir" | |
| else | |
| failed=1 | |
| echo "::error file=$project_ini::PlatformIO build failed" | |
| echo "FAIL $project_dir" | |
| echo "::group::Last 120 lines from $project_dir" | |
| tail -n 120 "$log_file" | |
| echo "::endgroup::" | |
| fi | |
| done < "$RUNNER_TEMP/platformio-projects.txt" | |
| if [ "$found" -eq 0 ]; then | |
| echo "No PlatformIO projects were selected." >&2 | |
| exit 1 | |
| fi | |
| exit "$failed" | |
| - name: Upload PlatformIO logs | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: firmware-platformio-logs | |
| path: ${{ runner.temp }}/platformio-logs | |
| if-no-files-found: ignore | |
| retention-days: 7 |