watchdog: Add runner #207
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: | |
| push: | |
| branches: ["main"] | |
| pull_request: | |
| branches: ["main"] | |
| workflow_dispatch: | |
| concurrency: | |
| cancel-in-progress: true | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| format: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dtolnay/rust-toolchain@nightly | |
| with: | |
| components: rustfmt | |
| - run: .github/ci/format.sh | |
| check: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: clippy, rustfmt, llvm-tools | |
| targets: thumbv6m-none-eabi,thumbv7m-none-eabi,thumbv7em-none-eabi,thumbv7em-none-eabihf,thumbv8m.main-none-eabihf,riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf | |
| - uses: dtolnay/rust-toolchain@nightly | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: ci-check | |
| # check.sh redirects cargo artifacts to target/ci/ via --target-dir | |
| # (so cargo-batch can share compilation across manifests). Tell | |
| # rust-cache about it, otherwise it only caches the per-crate | |
| # target/ dirs which stay empty. | |
| cache-directories: | | |
| target/ci | |
| - name: Install cargo-batch | |
| run: cargo install --locked --git https://github.com/embassy-rs/cargo-batch cargo --bin cargo-batch | |
| - run: .github/ci/check.sh | |
| test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: clippy, rustfmt, llvm-tools | |
| targets: thumbv6m-none-eabi,thumbv7m-none-eabi,thumbv7em-none-eabi,thumbv7em-none-eabihf,thumbv8m.main-none-eabihf,riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: ci-test | |
| # test.sh writes to target/ci/test via CARGO_TARGET_DIR; cache it | |
| # explicitly so rust-cache doesn't miss it. | |
| cache-directories: | | |
| target/ci | |
| - uses: taiki-e/install-action@v2 | |
| with: | |
| tool: nextest@0.9 | |
| - name: Install cargo-expand | |
| run: cargo install --locked cargo-expand | |
| - run: .github/ci/test.sh | |
| # Discover buildable examples for the matrix | |
| discover: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| stable: ${{ steps.discover.outputs.stable }} | |
| esp: ${{ steps.discover.outputs.esp }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - id: discover | |
| run: .github/ci/discover.sh | |
| # Build each stable-toolchain example in parallel. | |
| # Entries with bloat==true also compare binary sizes against the base branch. | |
| build: | |
| needs: discover | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| # Leave runner slots for format/check/test/build-esp. | |
| max-parallel: 15 | |
| matrix: | |
| include: ${{ fromJson(needs.discover.outputs.stable) }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| # Bloat entries need full history for git worktree to base revision. | |
| # Shallow clone is fast for this repo, so always fetch full history. | |
| fetch-depth: 0 | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: ci-build-${{ matrix.target }} | |
| - name: Install target and tools | |
| run: | | |
| rustup target add ${{ matrix.target }} | |
| cargo install flip-link 2>/dev/null || true | |
| - name: Build | |
| working-directory: ${{ matrix.dir }} | |
| run: | | |
| # For bloat examples, remap source paths so the absolute workspace | |
| # prefix doesn't affect binary size (panic messages embed file!() paths). | |
| if [[ "${{ matrix.bloat }}" == "true" ]]; then | |
| export RUSTFLAGS="--remap-path-prefix=$GITHUB_WORKSPACE=/rmk-build" | |
| fi | |
| cargo build --release | |
| # ── Bloat: size + bloaty diff HEAD vs BASE, upload data ── | |
| - name: Install bloat tools | |
| if: github.event_name == 'pull_request' && matrix.bloat | |
| run: | | |
| rustup component add llvm-tools | |
| cargo install cargo-binutils 2>/dev/null || true | |
| # bloaty isn't in apt; extract the pre-built binary from the Docker image | |
| # used by carlosperate/bloaty-action. | |
| id=$(docker create ghcr.io/carlosperate/bloaty-action:latest) | |
| sudo docker cp "$id:/usr/local/bin/bloaty" /usr/local/bin/bloaty | |
| docker rm "$id" >/dev/null | |
| - name: Measure sizes and compare with base | |
| if: github.event_name == 'pull_request' && matrix.bloat | |
| working-directory: ${{ matrix.dir }} | |
| env: | |
| BLOAT_BINS: ${{ matrix.bloat_bins }} | |
| run: | | |
| set -euo pipefail | |
| # Determine which binaries to size. | |
| if [[ -n "$BLOAT_BINS" ]]; then | |
| IFS=',' read -ra bins <<< "$BLOAT_BINS" | |
| else | |
| bins=(default) | |
| fi | |
| # ── Build BASE ── | |
| base_sha=$(git -C "$GITHUB_WORKSPACE" merge-base HEAD origin/main) | |
| worktree=$(mktemp -d) | |
| git -C "$GITHUB_WORKSPACE" worktree add --detach "$worktree" "$base_sha" | |
| trap 'git -C "$GITHUB_WORKSPACE" worktree remove --force "$worktree" 2>/dev/null; rm -rf "$worktree"' EXIT | |
| # Remap source paths so that HEAD and BASE binaries use the same | |
| # virtual prefix. Without this, absolute paths embedded by panic | |
| # messages (file!() macro) differ in length between $GITHUB_WORKSPACE | |
| # and the temp worktree, producing false size diffs in .rodata/.text. | |
| head_remap="--remap-path-prefix=$GITHUB_WORKSPACE=/rmk-build" | |
| base_remap="--remap-path-prefix=$worktree=/rmk-build" | |
| base_dir="$worktree/${{ matrix.dir }}" | |
| if [[ -d "$base_dir" ]]; then | |
| (cd "$base_dir" && RUSTFLAGS="$base_remap" cargo build --release) | |
| fi | |
| # ── Output directory ── | |
| safe_name=$(echo "${{ matrix.dir }}" | tr '/' '_') | |
| outdir="$GITHUB_WORKSPACE/bloat-data/$safe_name" | |
| mkdir -p "$outdir" | |
| for bin in "${bins[@]}"; do | |
| bin_flag="" | |
| bin_label="" | |
| bin_suffix="" | |
| if [[ "$bin" != "default" ]]; then | |
| bin_flag="--bin $bin" | |
| bin_label="$bin" | |
| bin_suffix="-$bin" | |
| fi | |
| # cargo size for HEAD — extract text/data/bss/total | |
| # RUSTFLAGS must match the Build step so cargo reuses the existing binary. | |
| RUSTFLAGS="$head_remap" cargo size --release $bin_flag 2>/dev/null > "$outdir/size-head${bin_suffix}.txt" | |
| read -r h_text h_data h_bss head_size < <(awk 'NR==2 {print $1, $2, $3, $4}' "$outdir/size-head${bin_suffix}.txt") | |
| # cargo size + bloaty for BASE | |
| if [[ -d "$base_dir" ]]; then | |
| (cd "$base_dir" && RUSTFLAGS="$base_remap" cargo size --release $bin_flag 2>/dev/null) > "$outdir/size-base${bin_suffix}.txt" | |
| read -r b_text b_data b_bss base_size < <(awk 'NR==2 {print $1, $2, $3, $4}' "$outdir/size-base${bin_suffix}.txt") | |
| # Section diffs | |
| d_text=$((h_text - b_text)) | |
| d_data=$((h_data - b_data)) | |
| d_bss=$((h_bss - b_bss)) | |
| # Find ELF paths for bloaty | |
| head_target_dir="target/${{ matrix.target }}/release" | |
| base_target_dir="$base_dir/target/${{ matrix.target }}/release" | |
| if [[ -n "$bin_label" ]]; then | |
| head_elf="$head_target_dir/$bin_label" | |
| base_elf="$base_target_dir/$bin_label" | |
| else | |
| head_elf=$(find "$head_target_dir" -maxdepth 1 -type f -executable ! -name "*.d" ! -name "*.rlib" ! -name "build-script-*" | head -1) | |
| base_elf=$(find "$base_target_dir" -maxdepth 1 -type f -executable ! -name "*.d" ! -name "*.rlib" ! -name "build-script-*" | head -1) | |
| fi | |
| if [[ -f "$head_elf" && -f "$base_elf" ]]; then | |
| bloaty "$head_elf" -- "$base_elf" > "$outdir/bloaty${bin_suffix}.txt" 2>&1 || true | |
| fi | |
| else | |
| base_size=0; d_text=0; d_data=0; d_bss=0 | |
| echo "(base not available)" > "$outdir/size-base${bin_suffix}.txt" | |
| fi | |
| # Format: dir|bin_label|base_total|head_total|text_diff|data_diff|bss_diff | |
| echo "${{ matrix.dir }}|${bin_label}|${base_size}|${head_size}|${d_text}|${d_data}|${d_bss}" >> "$outdir/size-data.txt" | |
| done | |
| echo "Size data:" | |
| cat "$outdir/size-data.txt" | |
| - name: Upload bloat data | |
| if: github.event_name == 'pull_request' && matrix.bloat | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: bloat-${{ hashFiles('bloat-data/*/size-data.txt') }} | |
| path: bloat-data/ | |
| retention-days: 1 | |
| # Assemble bloat report from matrix artifacts and save for the comment workflow | |
| bloat-report: | |
| if: github.event_name == 'pull_request' | |
| needs: build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/download-artifact@v7 | |
| with: | |
| path: bloat-artifacts | |
| pattern: bloat-* | |
| merge-multiple: true | |
| - name: Generate report | |
| run: | | |
| report=$(.github/ci/bloat-report.sh bloat-artifacts) | |
| mkdir -p bloat-comment | |
| echo "${{ github.event.pull_request.number }}" > bloat-comment/pr-number.txt | |
| echo "$report" > bloat-comment/report.md | |
| - name: Upload comment data | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: bloat-comment | |
| path: bloat-comment/ | |
| retention-days: 1 | |
| # Build ESP/xtensa examples (separate toolchain) | |
| build-esp: | |
| needs: discover | |
| if: fromJson(needs.discover.outputs.esp)[0] != null | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: cargo-bins/cargo-binstall@main | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: ci-build-esp | |
| # Both esp examples share one target dir (target-esp/, set in the | |
| # build step); point rust-cache at it so per-dep artifacts survive. | |
| workspaces: | | |
| examples/use_config/esp32s3_ble -> ../../../target-esp | |
| examples/use_rust/esp32s3_ble -> ../../../target-esp | |
| - name: Install espup and esp toolchain | |
| run: | | |
| cargo binstall espup -y | |
| espup install | |
| - name: Build ESP examples | |
| run: | | |
| source "$HOME/export-esp.sh" | |
| export CARGO_TARGET_DIR="$PWD/target-esp" | |
| for dir in examples/use_rust/esp32s3_ble examples/use_config/esp32s3_ble; do | |
| (cd "$dir" && CARGO_UNSTABLE_BUILD_STD=alloc,core cargo +esp build --release) | |
| done |