From 2cc6d9be911d32928d467a76c6924197903af5a0 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Mon, 28 Sep 2026 20:14:54 -0700 Subject: [PATCH 01/12] perf(ci): compile fbuild once and share it across board jobs Every board job (~76 in the nightly sweep) recompiled the same board-independent fbuild-cli + fbuild-daemon debug build: 26,406s of runner time per sweep, ~350s of each ~550s job. A single fbuild_bin job now builds it and uploads an artifact; template_build.yml downloads it via the new fbuild-artifact input and skips soldr/apt/compile. Direct build-.yml dispatches keep the standalone compile path. Follows zackees/ci.yml policy-rust: compile once, runners only execute. --- .github/workflows/ci-full.yml | 37 +++++++++++++- .github/workflows/ci-test.yml | 37 +++++++++++++- .github/workflows/nightly-platforms.yml | 37 +++++++++++++- .github/workflows/template_build.yml | 28 +++++++++++ ci/render_workflows.py | 64 +++++++++++++++++++++++-- ci/test_fractional_workflows.py | 7 ++- 6 files changed, 201 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci-full.yml b/.github/workflows/ci-full.yml index 9b9ffde4..66537260 100644 --- a/.github/workflows/ci-full.yml +++ b/.github/workflows/ci-full.yml @@ -125,9 +125,43 @@ jobs: uses: ./.github/workflows/crate-gate.yml with: ref: ${{ needs.verify.outputs.candidate_sha }} - boards: + fbuild_bin: + name: Build fbuild (shared by board jobs) if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'ci-full') needs: verify + runs-on: ubuntu-latest + timeout-minutes: 30 + env: + CARGO_TERM_COLOR: always + RUSTFLAGS: "-D warnings" + SOLDR_TARGET_BLOCK_FREE_GB: "2" + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ needs.verify.outputs.candidate_sha }} + - uses: zackees/setup-soldr@dfbe9627f6cb0226716b61625b99a58949162720 + with: + cache-preset: foundation + prebuild-deps-flags: "" + prebuild-deps: none + linker: platform-default + cache-payload-warn-bytes: 2GiB + cache-key-suffix: fbuild-rust-debug + - run: | + sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 update + sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 install -y libudev-dev pkg-config + - run: soldr cargo build -p fbuild-cli -p fbuild-daemon + - uses: actions/upload-artifact@v7 + with: + name: fbuild-bin-linux-debug + path: | + target/debug/fbuild + target/debug/fbuild-daemon + if-no-files-found: error + retention-days: 1 + boards: + if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'ci-full') + needs: [verify, fbuild_bin] name: ${{ matrix.workflow_name }} strategy: fail-fast: false @@ -596,6 +630,7 @@ jobs: env-name: ${{ matrix.env_name }} firmware-ext: ${{ matrix.firmware_ext }} checkout_ref: ${{ needs.verify.outputs.candidate_sha }} + fbuild-artifact: fbuild-bin-linux-debug coverage: name: Full coverage if: always() diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml index d12f4928..0bf89f9b 100644 --- a/.github/workflows/ci-test.yml +++ b/.github/workflows/ci-test.yml @@ -55,9 +55,43 @@ jobs: uses: ./.github/workflows/check-ubuntu.yml with: ref: ${{ needs.verify.outputs.candidate_sha }} - boards: + fbuild_bin: + name: Build fbuild (shared by board jobs) if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'ci-test') needs: verify + runs-on: ubuntu-latest + timeout-minutes: 30 + env: + CARGO_TERM_COLOR: always + RUSTFLAGS: "-D warnings" + SOLDR_TARGET_BLOCK_FREE_GB: "2" + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ needs.verify.outputs.candidate_sha }} + - uses: zackees/setup-soldr@dfbe9627f6cb0226716b61625b99a58949162720 + with: + cache-preset: foundation + prebuild-deps-flags: "" + prebuild-deps: none + linker: platform-default + cache-payload-warn-bytes: 2GiB + cache-key-suffix: fbuild-rust-debug + - run: | + sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 update + sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 install -y libudev-dev pkg-config + - run: soldr cargo build -p fbuild-cli -p fbuild-daemon + - uses: actions/upload-artifact@v7 + with: + name: fbuild-bin-linux-debug + path: | + target/debug/fbuild + target/debug/fbuild-daemon + if-no-files-found: error + retention-days: 1 + boards: + if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'ci-test') + needs: [verify, fbuild_bin] name: ${{ matrix.workflow_name }} strategy: fail-fast: false @@ -76,6 +110,7 @@ jobs: env-name: ${{ matrix.env_name }} firmware-ext: ${{ matrix.firmware_ext }} checkout_ref: ${{ needs.verify.outputs.candidate_sha }} + fbuild-artifact: fbuild-bin-linux-debug coverage: name: ci-test coverage if: always() diff --git a/.github/workflows/nightly-platforms.yml b/.github/workflows/nightly-platforms.yml index 4364651c..29fe2bdf 100644 --- a/.github/workflows/nightly-platforms.yml +++ b/.github/workflows/nightly-platforms.yml @@ -49,9 +49,43 @@ jobs: echo "should_run=true" >> "$GITHUB_OUTPUT" fi + fbuild_bin: + name: Build fbuild (shared by board jobs) + if: needs.guard.outputs.should_run == 'true' + needs: guard + runs-on: ubuntu-latest + timeout-minutes: 30 + env: + CARGO_TERM_COLOR: always + RUSTFLAGS: "-D warnings" + SOLDR_TARGET_BLOCK_FREE_GB: "2" + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ github.sha }} + - uses: zackees/setup-soldr@dfbe9627f6cb0226716b61625b99a58949162720 + with: + cache-preset: foundation + prebuild-deps-flags: "" + prebuild-deps: none + linker: platform-default + cache-payload-warn-bytes: 2GiB + cache-key-suffix: fbuild-rust-debug + - run: | + sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 update + sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 install -y libudev-dev pkg-config + - run: soldr cargo build -p fbuild-cli -p fbuild-daemon + - uses: actions/upload-artifact@v7 + with: + name: fbuild-bin-linux-debug + path: | + target/debug/fbuild + target/debug/fbuild-daemon + if-no-files-found: error + retention-days: 1 build: name: ${{ matrix.workflow_name }} - needs: guard + needs: [guard, fbuild_bin] if: needs.guard.outputs.should_run == 'true' strategy: fail-fast: false @@ -443,3 +477,4 @@ jobs: test-dir: ${{ matrix.test_dir }} env-name: ${{ matrix.env_name }} firmware-ext: ${{ matrix.firmware_ext }} + fbuild-artifact: fbuild-bin-linux-debug diff --git a/.github/workflows/template_build.yml b/.github/workflows/template_build.yml index 75d3fe3c..c4355ed0 100644 --- a/.github/workflows/template_build.yml +++ b/.github/workflows/template_build.yml @@ -23,6 +23,17 @@ on: required: false type: string default: "" + fbuild-artifact: + required: false + type: string + default: "" + description: >- + Name of an uploaded artifact holding prebuilt `fbuild` + + `fbuild-daemon` debug binaries. When set, this job downloads them + instead of compiling fbuild itself (zackees/ci.yml "compile once, + runners only execute"): the per-board compile was ~350s of a ~550s + job, repeated across ~76 boards. Empty keeps the standalone + compile path for direct `build-.yml` dispatches. env: CARGO_TERM_COLOR: always @@ -47,6 +58,7 @@ jobs: - name: Setup soldr id: setup-soldr + if: inputs.fbuild-artifact == '' # Canary exact setup-soldr main SHA before v0 promotion. uses: zackees/setup-soldr@dfbe9627f6cb0226716b61625b99a58949162720 with: @@ -108,6 +120,9 @@ jobs: fbuild-build-${{ runner.os }}-${{ inputs.env-name }}- - name: Install Linux dependencies + # Build-time only (libudev headers for the Rust compile); the runtime + # libudev1 ships with the hosted image. + if: inputs.fbuild-artifact == '' timeout-minutes: 5 run: | sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 update @@ -124,9 +139,22 @@ jobs: esptool version - name: Build fbuild binaries + if: inputs.fbuild-artifact == '' run: | soldr cargo build -p fbuild-cli -p fbuild-daemon + - name: Download prebuilt fbuild binaries + if: inputs.fbuild-artifact != '' + uses: actions/download-artifact@v8 + with: + name: ${{ inputs.fbuild-artifact }} + path: target/debug + + - name: Restore executable bits on prebuilt binaries + if: inputs.fbuild-artifact != '' + # upload-artifact does not preserve file modes. + run: chmod +x target/debug/fbuild target/debug/fbuild-daemon + - name: Add fbuild to PATH run: echo "${{ github.workspace }}/target/debug" >> $GITHUB_PATH diff --git a/ci/render_workflows.py b/ci/render_workflows.py index 686ed301..d017339f 100644 --- a/ci/render_workflows.py +++ b/ci/render_workflows.py @@ -154,6 +154,56 @@ def execution_boards(boards: list[dict]) -> list[dict]: return list(unique.values()) +FBUILD_BIN_ARTIFACT = "fbuild-bin-linux-debug" + + +def render_fbuild_bin_job(needs: str, condition: str, ref: str) -> str: + """One job that compiles fbuild once and uploads it for every board job. + + zackees/ci.yml policy-rust "compile once, runners only execute": before + this, each of ~76 board jobs spent ~350s compiling the same + board-independent `fbuild-cli` + `fbuild-daemon` debug build. The + setup-soldr inputs mirror template_build.yml's standalone compile path so + both share one warm `fbuild-rust-debug` cache. + """ + return ( + " fbuild_bin:\n" + " name: Build fbuild (shared by board jobs)\n" + + condition + + f" needs: {needs}\n" + " runs-on: ubuntu-latest\n" + " timeout-minutes: 30\n" + " env:\n" + " CARGO_TERM_COLOR: always\n" + " RUSTFLAGS: \"-D warnings\"\n" + " SOLDR_TARGET_BLOCK_FREE_GB: \"2\"\n" + " steps:\n" + " - uses: actions/checkout@v6\n" + " with:\n" + f" ref: {ref}\n" + " - uses: zackees/setup-soldr@dfbe9627f6cb0226716b61625b99a58949162720\n" + " with:\n" + " cache-preset: foundation\n" + " prebuild-deps-flags: \"\"\n" + " prebuild-deps: none\n" + " linker: platform-default\n" + " cache-payload-warn-bytes: 2GiB\n" + " cache-key-suffix: fbuild-rust-debug\n" + " - run: |\n" + " sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 update\n" + " sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 install -y libudev-dev pkg-config\n" + " - run: soldr cargo build -p fbuild-cli -p fbuild-daemon\n" + " - uses: actions/upload-artifact@v7\n" + " with:\n" + f" name: {FBUILD_BIN_ARTIFACT}\n" + " path: |\n" + " target/debug/fbuild\n" + " target/debug/fbuild-daemon\n" + " if-no-files-found: error\n" + " retention-days: 1\n" + ) + + def render_ci(boards: list[dict], tier: str) -> str: full = tier == "full" minimal = tier == "minimal" @@ -307,9 +357,10 @@ def render_ci(boards: list[dict], tier: str) -> str: + host + policy + ("" if minimal else - " boards:\n" + render_fbuild_bin_job("verify", gate, verified_ref) + + " boards:\n" + gate - + " needs: verify\n" + + " needs: [verify, fbuild_bin]\n" + " name: ${{ matrix.workflow_name }}\n" + " strategy:\n" + " fail-fast: false\n" @@ -322,7 +373,8 @@ def render_ci(boards: list[dict], tier: str) -> str: + " test-dir: ${{ matrix.test_dir }}\n" + " env-name: ${{ matrix.env_name }}\n" + " firmware-ext: ${{ matrix.firmware_ext }}\n" - + f" checkout_ref: {verified_ref}\n") + + f" checkout_ref: {verified_ref}\n" + + f" fbuild-artifact: {FBUILD_BIN_ARTIFACT}\n") + ("" if minimal else " coverage:\n" + (" name: Full coverage\n" if full else " name: ci-test coverage\n") @@ -478,9 +530,10 @@ def render_nightly(boards: list[dict]) -> str: f" workflow_aliases: {json.dumps(b['workflow_aliases'])}\n" ) jobs_yaml = ( - " build:\n" + render_fbuild_bin_job("guard", " if: needs.guard.outputs.should_run == 'true'\n", "${{ github.sha }}") + + " build:\n" " name: ${{ matrix.workflow_name }}\n" - " needs: guard\n" + " needs: [guard, fbuild_bin]\n" " if: needs.guard.outputs.should_run == 'true'\n" " strategy:\n" # One broken board must not cancel the other 78 -- the whole point of @@ -493,6 +546,7 @@ def render_nightly(boards: list[dict]) -> str: " test-dir: ${{ matrix.test_dir }}\n" " env-name: ${{ matrix.env_name }}\n" " firmware-ext: ${{ matrix.firmware_ext }}\n" + f" fbuild-artifact: {FBUILD_BIN_ARTIFACT}\n" ) header = ( "# Daily safety-net sweep of every per-board build workflow.\n" diff --git a/ci/test_fractional_workflows.py b/ci/test_fractional_workflows.py index 573e4197..2be12b0c 100644 --- a/ci/test_fractional_workflows.py +++ b/ci/test_fractional_workflows.py @@ -172,7 +172,12 @@ def test_labeled_tiers_follow_head_sha_and_invalidate_removed_labels(self): self.assertIn("always()", workflow["jobs"]["coverage"]["if"]) self.assertIn("complete=false", workflow["jobs"]["coverage"]["steps"][0]["run"]) self.assertNotIn("invalidate", workflow["jobs"]) - self.assertEqual("verify", workflow["jobs"]["boards"]["needs"]) + self.assertEqual(["verify", "fbuild_bin"], workflow["jobs"]["boards"]["needs"]) + self.assertEqual("fbuild-bin-linux-debug", workflow["jobs"]["boards"]["with"]["fbuild-artifact"]) + self.assertEqual( + "${{ needs.verify.outputs.candidate_sha }}", + workflow["jobs"]["fbuild_bin"]["steps"][0]["with"]["ref"], + ) self.assertEqual("${{ needs.verify.outputs.candidate_sha }}", workflow["jobs"]["boards"]["with"]["checkout_ref"]) def test_selected_coverage_requires_every_requested_tier(self): From e89efc32cad0595ff5abc20ac82f353724cb4edd Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Mon, 28 Sep 2026 20:35:36 -0700 Subject: [PATCH 02/12] perf(ci): save board/toolchain/Rust caches only from main A single non-main board sweep saved 151 entries (~79 x ~1GB toolchain caches), pushing the repo to 35.8GB and evicting main's setup-soldr Rust build cache: the shared fbuild compile ran at 0/621 zccache hits (383s). Branches and PRs now restore main's entries but never save, per zackees/ci.yml CACHE-003. --- .github/workflows/ci-full.yml | 1 + .github/workflows/ci-test.yml | 1 + .github/workflows/nightly-platforms.yml | 1 + .github/workflows/template_build.yml | 9 +++++++-- ci/render_workflows.py | 1 + 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-full.yml b/.github/workflows/ci-full.yml index 66537260..1028b5cb 100644 --- a/.github/workflows/ci-full.yml +++ b/.github/workflows/ci-full.yml @@ -147,6 +147,7 @@ jobs: linker: platform-default cache-payload-warn-bytes: 2GiB cache-key-suffix: fbuild-rust-debug + save-cache: ${{ github.ref == 'refs/heads/main' && 'true' || 'false' }} - run: | sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 update sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 install -y libudev-dev pkg-config diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml index 0bf89f9b..d8e2a29e 100644 --- a/.github/workflows/ci-test.yml +++ b/.github/workflows/ci-test.yml @@ -77,6 +77,7 @@ jobs: linker: platform-default cache-payload-warn-bytes: 2GiB cache-key-suffix: fbuild-rust-debug + save-cache: ${{ github.ref == 'refs/heads/main' && 'true' || 'false' }} - run: | sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 update sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 install -y libudev-dev pkg-config diff --git a/.github/workflows/nightly-platforms.yml b/.github/workflows/nightly-platforms.yml index 29fe2bdf..1f2f22d3 100644 --- a/.github/workflows/nightly-platforms.yml +++ b/.github/workflows/nightly-platforms.yml @@ -71,6 +71,7 @@ jobs: linker: platform-default cache-payload-warn-bytes: 2GiB cache-key-suffix: fbuild-rust-debug + save-cache: ${{ github.ref == 'refs/heads/main' && 'true' || 'false' }} - run: | sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 update sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 install -y libudev-dev pkg-config diff --git a/.github/workflows/template_build.yml b/.github/workflows/template_build.yml index c4355ed0..7a279336 100644 --- a/.github/workflows/template_build.yml +++ b/.github/workflows/template_build.yml @@ -91,6 +91,10 @@ jobs: # `cache-payload-max-bytes` still defaults to 6 GiB. cache-payload-warn-bytes: 2GiB cache-key-suffix: fbuild-rust-debug + # Save only from the default branch; other refs restore main's. + # Branch sweeps re-saved ~79 x ~1GB entries and evicted main's + # Rust build cache (0% hit rate; zackees/ci.yml CACHE-003). + save-cache: ${{ github.ref == 'refs/heads/main' && 'true' || 'false' }} # Note: standalone `zccache-daemon` no longer runs separately. # As of soldr 1.12.11+ (soldr#977 / #980 L1) zccache is embedded @@ -202,7 +206,8 @@ jobs: echo "working tree clean after quick + release builds" - name: Save fbuild toolchains - if: always() + # Default branch only -- see the setup-soldr save-cache note above. + if: always() && github.ref == 'refs/heads/main' timeout-minutes: 10 uses: actions/cache/save@v5 with: @@ -210,7 +215,7 @@ jobs: key: fbuild-toolchain-${{ runner.os }}-${{ inputs.env-name }}-${{ hashFiles(format('{0}/platformio.ini', inputs.test-dir)) }} - name: Save platform build artifacts - if: always() + if: always() && github.ref == 'refs/heads/main' timeout-minutes: 10 uses: actions/cache/save@v5 with: diff --git a/ci/render_workflows.py b/ci/render_workflows.py index d017339f..d848e1ad 100644 --- a/ci/render_workflows.py +++ b/ci/render_workflows.py @@ -189,6 +189,7 @@ def render_fbuild_bin_job(needs: str, condition: str, ref: str) -> str: " linker: platform-default\n" " cache-payload-warn-bytes: 2GiB\n" " cache-key-suffix: fbuild-rust-debug\n" + " save-cache: ${{ github.ref == 'refs/heads/main' && 'true' || 'false' }}\n" " - run: |\n" " sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 update\n" " sudo apt-get -o Acquire::http::Timeout=30 -o Acquire::Retries=3 install -y libudev-dev pkg-config\n" From 6e70cebd9a7813b7a9c43c4cddd3c5c8ea056bfc Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Mon, 28 Sep 2026 20:53:49 -0700 Subject: [PATCH 03/12] ci: dispatch per-board workflows by changed paths so README badges stay current Since 9f4cc4dd removed per-board path triggers, build-.yml only ran when called from a matrix, which never updates that file's badge: every board badge was frozen (last runs 2026-09-15..21). nightly-platforms.yml is now a dispatcher. On push to main it selects boards whose trigger paths changed (ci/select_boards.py, reusing render_paths_for_board); on its schedule it selects every board. It compiles fbuild once and gh-workflow-runs each board workflow with its run id, so each board is its own run (badge moves) yet downloads the shared binary. Replaying the last 60 main pushes: 380 board runs vs 4,800 for all boards on every push (7%). --- .github/workflows/README.md | 20 +- .github/workflows/build-apollo3_red.yml | 16 +- .../build-apollo3_thing_explorable.yml | 16 +- .github/workflows/build-atmega8.yml | 14 +- .github/workflows/build-atmega8a.yml | 14 +- .github/workflows/build-attiny1604.yml | 14 +- .github/workflows/build-attiny1616.yml | 14 +- .github/workflows/build-attiny4313.yml | 14 +- .github/workflows/build-attiny85.yml | 14 +- .github/workflows/build-attiny88.yml | 14 +- .github/workflows/build-blackpill.yml | 16 +- .github/workflows/build-bluepill.yml | 16 +- .github/workflows/build-ch32l103.yml | 14 +- .github/workflows/build-ch32v003.yml | 14 +- .github/workflows/build-ch32v006.yml | 14 +- .github/workflows/build-ch32v103.yml | 14 +- .github/workflows/build-ch32v203.yml | 14 +- .github/workflows/build-ch32v208.yml | 14 +- .github/workflows/build-ch32v303.yml | 14 +- .github/workflows/build-ch32v307.yml | 14 +- .github/workflows/build-ch32x035.yml | 14 +- .github/workflows/build-clearcore.yml | 14 +- .github/workflows/build-due.yml | 14 +- .github/workflows/build-esp32c2.yml | 14 +- .github/workflows/build-esp32c3.yml | 14 +- .github/workflows/build-esp32c5.yml | 14 +- .github/workflows/build-esp32c6.yml | 14 +- .github/workflows/build-esp32dev.yml | 14 +- .github/workflows/build-esp32h2.yml | 14 +- .github/workflows/build-esp32p4.yml | 14 +- .github/workflows/build-esp32s2.yml | 14 +- .github/workflows/build-esp32s3.yml | 14 +- .github/workflows/build-esp8266.yml | 14 +- .github/workflows/build-giga-r1.yml | 16 +- .github/workflows/build-leonardo.yml | 16 +- .github/workflows/build-lpc804.yml | 14 +- .github/workflows/build-lpc845.yml | 16 +- .github/workflows/build-lpc845brk.yml | 14 +- .github/workflows/build-lpcxpresso804.yml | 14 +- .github/workflows/build-lpcxpresso845max.yml | 14 +- .github/workflows/build-matrix_portal_m4.yml | 16 +- .github/workflows/build-mgm240.yml | 16 +- .github/workflows/build-nano-every.yml | 16 +- .github/workflows/build-nano_every.yml | 16 +- .../workflows/build-nice_nano_nrf52840.yml | 16 +- .github/workflows/build-nrf52840-sense.yml | 16 +- .github/workflows/build-nrf52840_dk.yml | 16 +- .github/workflows/build-nrfmicro_nrf52840.yml | 16 +- .github/workflows/build-nucleo-f429zi.yml | 16 +- .github/workflows/build-nucleo-f439zi.yml | 16 +- .github/workflows/build-nucleo_f429zi.yml | 16 +- .github/workflows/build-nucleo_f439zi.yml | 16 +- .github/workflows/build-qtpy_m0.yml | 16 +- .github/workflows/build-rp2040.yml | 14 +- .github/workflows/build-rp2350.yml | 14 +- .github/workflows/build-rpipico.yml | 14 +- .github/workflows/build-rpipico2.yml | 14 +- .github/workflows/build-sam3x8e_due.yml | 16 +- .github/workflows/build-samd21.yml | 16 +- .github/workflows/build-samd21_zero.yml | 16 +- .github/workflows/build-samd51j.yml | 16 +- .github/workflows/build-samd51p.yml | 16 +- .github/workflows/build-stm32f103c8.yml | 14 +- .github/workflows/build-stm32f103cb.yml | 14 +- .github/workflows/build-stm32f103tb.yml | 14 +- .github/workflows/build-stm32f411ce.yml | 14 +- .github/workflows/build-stm32h747xi.yml | 14 +- .../workflows/build-supermini_nrf52840.yml | 14 +- .github/workflows/build-teensy30.yml | 14 +- .github/workflows/build-teensy31.yml | 14 +- .github/workflows/build-teensy32.yml | 14 +- .github/workflows/build-teensy35.yml | 14 +- .github/workflows/build-teensy36.yml | 14 +- .github/workflows/build-teensy40.yml | 14 +- .github/workflows/build-teensy41.yml | 14 +- .github/workflows/build-teensylc.yml | 14 +- .github/workflows/build-thingplusmatter.yml | 14 +- .github/workflows/build-tinystm.yml | 16 +- .github/workflows/build-uno-r4-wifi.yml | 14 +- .github/workflows/build-uno.yml | 14 +- .github/workflows/build-uno_r4_wifi.yml | 16 +- .github/workflows/nightly-platforms.yml | 457 ++---------------- .github/workflows/template_build.yml | 11 + ci/README.md | 1 + ci/render_workflows.py | 170 ++++--- ci/select_boards.py | 92 ++++ ci/test_fractional_workflows.py | 25 +- ci/test_select_boards.py | 70 +++ 88 files changed, 1410 insertions(+), 610 deletions(-) create mode 100644 ci/select_boards.py create mode 100644 ci/test_select_boards.py diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 22ef23a4..f9592f29 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -22,12 +22,20 @@ CI/CD workflows for the fbuild project, covering lint, test, documentation, and MSRV, board validation, and crate-gate statuses. The unselected tiers allocate no PR runners. The selected tier owns the Linux workspace check; when both labels are present, `ci-full` subsumes `ci-test`. -- The full and nightly board matrices execute identical build inputs once. - Each matrix row carries `workflow_aliases` so every listed board workflow - remains represented, including legacy spelling aliases. -- Per-board `build-*.yml` files are manual/reusable only. Their triggers are - generated by `ci/render_workflows.py`; the nightly sweep still runs every - board independently of PR labels. +- The full board matrix executes identical build inputs once. Each matrix + row carries `workflow_aliases` so every listed board workflow remains + represented, including legacy spelling aliases. +- Board jobs never compile fbuild themselves: one `fbuild_bin` job builds it + and uploads `fbuild-bin-linux-debug`, which `template_build.yml` downloads + (`fbuild-artifact` / `fbuild-run-id` inputs). Caches save only from `main`. +- **README badges.** A badge tracks runs of its own `build-.yml` file, + so `nightly-platforms.yml` is a dispatcher: it compiles fbuild once, then + `gh workflow run`s each selected board workflow with its run id. On push to + `main` it selects only boards whose trigger paths changed + (`ci/select_boards.py`: own test dir, family crate paths, own workflow file; + shared paths select the `core` boards); on its daily schedule it selects + every board (skipped when there were no commits in 24h). PRs never run the + full board set unless labelled `ci-full`. ## Independent lightweight checks (push/PR) diff --git a/.github/workflows/build-apollo3_red.yml b/.github/workflows/build-apollo3_red.yml index 26146948..0b9ec114 100644 --- a/.github/workflows/build-apollo3_red.yml +++ b/.github/workflows/build-apollo3_red.yml @@ -2,7 +2,16 @@ name: Build Apollo3 RedBoard # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "Apollo3 RedBoard" + workflow-name: "Ambiq Apollo3 Red" test-dir: "tests/platform/apollo3_red" env-name: "apollo3_red" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-apollo3_thing_explorable.yml b/.github/workflows/build-apollo3_thing_explorable.yml index 9c99f950..e864b02e 100644 --- a/.github/workflows/build-apollo3_thing_explorable.yml +++ b/.github/workflows/build-apollo3_thing_explorable.yml @@ -2,7 +2,16 @@ name: Build Apollo3 expLoRaBLE # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "Apollo3 expLoRaBLE" + workflow-name: "Apollo3 Thing Explorable" test-dir: "tests/platform/apollo3_thing_explorable" env-name: "apollo3_thing_explorable" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-atmega8.yml b/.github/workflows/build-atmega8.yml index 09794c49..6a10c17b 100644 --- a/.github/workflows/build-atmega8.yml +++ b/.github/workflows/build-atmega8.yml @@ -2,7 +2,16 @@ name: Build ATmega8 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/atmega8" env-name: "atmega8" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-atmega8a.yml b/.github/workflows/build-atmega8a.yml index cce5ff67..6bdcd024 100644 --- a/.github/workflows/build-atmega8a.yml +++ b/.github/workflows/build-atmega8a.yml @@ -2,7 +2,16 @@ name: Build ATmega8A # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/atmega8a" env-name: "atmega8a" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-attiny1604.yml b/.github/workflows/build-attiny1604.yml index 70c28fab..dad063d7 100644 --- a/.github/workflows/build-attiny1604.yml +++ b/.github/workflows/build-attiny1604.yml @@ -2,7 +2,16 @@ name: Build ATtiny1604 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/attiny1604" env-name: "attiny1604" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-attiny1616.yml b/.github/workflows/build-attiny1616.yml index 72c05001..40f6ef91 100644 --- a/.github/workflows/build-attiny1616.yml +++ b/.github/workflows/build-attiny1616.yml @@ -2,7 +2,16 @@ name: Build ATtiny1616 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/attiny1616" env-name: "attiny1616" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-attiny4313.yml b/.github/workflows/build-attiny4313.yml index e1523d90..1c5c95fe 100644 --- a/.github/workflows/build-attiny4313.yml +++ b/.github/workflows/build-attiny4313.yml @@ -2,7 +2,16 @@ name: Build ATtiny4313 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/attiny4313" env-name: "attiny4313" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-attiny85.yml b/.github/workflows/build-attiny85.yml index 8f11bebf..7d973a63 100644 --- a/.github/workflows/build-attiny85.yml +++ b/.github/workflows/build-attiny85.yml @@ -2,7 +2,16 @@ name: Build ATtiny85 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/attiny85" env-name: "attiny85" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-attiny88.yml b/.github/workflows/build-attiny88.yml index 41c7d69f..1e7cb77d 100644 --- a/.github/workflows/build-attiny88.yml +++ b/.github/workflows/build-attiny88.yml @@ -2,7 +2,16 @@ name: Build ATtiny88 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/attiny88" env-name: "attiny88" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-blackpill.yml b/.github/workflows/build-blackpill.yml index 3483befe..4cc0736f 100644 --- a/.github/workflows/build-blackpill.yml +++ b/.github/workflows/build-blackpill.yml @@ -2,7 +2,16 @@ name: Build BlackPill F411CE # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "BlackPill F411CE" + workflow-name: "STM32 BlackPill F411CE" test-dir: "tests/platform/blackpill_f411ce" env-name: "blackpill" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-bluepill.yml b/.github/workflows/build-bluepill.yml index 45794dbc..cfe603de 100644 --- a/.github/workflows/build-bluepill.yml +++ b/.github/workflows/build-bluepill.yml @@ -2,7 +2,16 @@ name: Build BluePill F103C8 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "BluePill F103C8" + workflow-name: "STM32 BluePill F103C8" test-dir: "tests/platform/bluepill_f103c8" env-name: "bluepill" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-ch32l103.yml b/.github/workflows/build-ch32l103.yml index 65a606dd..2b0eb578 100644 --- a/.github/workflows/build-ch32l103.yml +++ b/.github/workflows/build-ch32l103.yml @@ -2,7 +2,16 @@ name: Build CH32L103 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/ch32l103" env-name: "ch32l103" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-ch32v003.yml b/.github/workflows/build-ch32v003.yml index 1a68c574..9aa5660b 100644 --- a/.github/workflows/build-ch32v003.yml +++ b/.github/workflows/build-ch32v003.yml @@ -2,7 +2,16 @@ name: Build CH32V003 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/ch32v003" env-name: "ch32v003" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-ch32v006.yml b/.github/workflows/build-ch32v006.yml index 5efb0d60..8d371199 100644 --- a/.github/workflows/build-ch32v006.yml +++ b/.github/workflows/build-ch32v006.yml @@ -2,7 +2,16 @@ name: Build CH32V006 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/ch32v006" env-name: "ch32v006" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-ch32v103.yml b/.github/workflows/build-ch32v103.yml index eb9ef51c..8462af1d 100644 --- a/.github/workflows/build-ch32v103.yml +++ b/.github/workflows/build-ch32v103.yml @@ -2,7 +2,16 @@ name: Build CH32V103 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/ch32v103" env-name: "ch32v103" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-ch32v203.yml b/.github/workflows/build-ch32v203.yml index 29b3c6f7..eaae1cda 100644 --- a/.github/workflows/build-ch32v203.yml +++ b/.github/workflows/build-ch32v203.yml @@ -2,7 +2,16 @@ name: Build CH32V203 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/ch32v203" env-name: "ch32v203" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-ch32v208.yml b/.github/workflows/build-ch32v208.yml index eae5d1c6..0f4ecbfd 100644 --- a/.github/workflows/build-ch32v208.yml +++ b/.github/workflows/build-ch32v208.yml @@ -2,7 +2,16 @@ name: Build CH32V208 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/ch32v208" env-name: "ch32v208" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-ch32v303.yml b/.github/workflows/build-ch32v303.yml index fb0e13d1..855ad92c 100644 --- a/.github/workflows/build-ch32v303.yml +++ b/.github/workflows/build-ch32v303.yml @@ -2,7 +2,16 @@ name: Build CH32V303 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/ch32v303" env-name: "ch32v303" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-ch32v307.yml b/.github/workflows/build-ch32v307.yml index dc17f35a..1f0745fa 100644 --- a/.github/workflows/build-ch32v307.yml +++ b/.github/workflows/build-ch32v307.yml @@ -2,7 +2,16 @@ name: Build CH32V307 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/ch32v307" env-name: "ch32v307" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-ch32x035.yml b/.github/workflows/build-ch32x035.yml index 0ab6852b..88d503d9 100644 --- a/.github/workflows/build-ch32x035.yml +++ b/.github/workflows/build-ch32x035.yml @@ -2,7 +2,16 @@ name: Build CH32X035 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/ch32x035" env-name: "ch32x035" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-clearcore.yml b/.github/workflows/build-clearcore.yml index ebd71d32..71861b47 100644 --- a/.github/workflows/build-clearcore.yml +++ b/.github/workflows/build-clearcore.yml @@ -2,7 +2,16 @@ name: Build Teknic ClearCore (SAME53) # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/clearcore" env-name: "clearcore" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-due.yml b/.github/workflows/build-due.yml index 537609da..4e0e53c1 100644 --- a/.github/workflows/build-due.yml +++ b/.github/workflows/build-due.yml @@ -2,7 +2,16 @@ name: Build Arduino Due # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/due" env-name: "due" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-esp32c2.yml b/.github/workflows/build-esp32c2.yml index 3d320f69..4194d00a 100644 --- a/.github/workflows/build-esp32c2.yml +++ b/.github/workflows/build-esp32c2.yml @@ -2,7 +2,16 @@ name: Build ESP32-C2 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/esp32c2" env-name: "esp32c2" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-esp32c3.yml b/.github/workflows/build-esp32c3.yml index da8f6fd3..ff870118 100644 --- a/.github/workflows/build-esp32c3.yml +++ b/.github/workflows/build-esp32c3.yml @@ -2,7 +2,16 @@ name: Build ESP32-C3 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/esp32c3" env-name: "esp32c3" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-esp32c5.yml b/.github/workflows/build-esp32c5.yml index 7119efbc..38cc5a70 100644 --- a/.github/workflows/build-esp32c5.yml +++ b/.github/workflows/build-esp32c5.yml @@ -2,7 +2,16 @@ name: Build ESP32-C5 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/esp32c5" env-name: "esp32c5" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-esp32c6.yml b/.github/workflows/build-esp32c6.yml index 0141db29..d7dfe0f4 100644 --- a/.github/workflows/build-esp32c6.yml +++ b/.github/workflows/build-esp32c6.yml @@ -2,7 +2,16 @@ name: Build ESP32-C6 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/esp32c6" env-name: "esp32c6" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-esp32dev.yml b/.github/workflows/build-esp32dev.yml index 8428b437..9254fa13 100644 --- a/.github/workflows/build-esp32dev.yml +++ b/.github/workflows/build-esp32dev.yml @@ -2,7 +2,16 @@ name: Build ESP32 Dev # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/esp32dev" env-name: "esp32dev" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-esp32h2.yml b/.github/workflows/build-esp32h2.yml index 8cc34a15..7219ae4d 100644 --- a/.github/workflows/build-esp32h2.yml +++ b/.github/workflows/build-esp32h2.yml @@ -2,7 +2,16 @@ name: Build ESP32-H2 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/esp32h2" env-name: "esp32h2" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-esp32p4.yml b/.github/workflows/build-esp32p4.yml index 48bca262..2611dfe0 100644 --- a/.github/workflows/build-esp32p4.yml +++ b/.github/workflows/build-esp32p4.yml @@ -2,7 +2,16 @@ name: Build ESP32-P4 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/esp32p4" env-name: "esp32p4" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-esp32s2.yml b/.github/workflows/build-esp32s2.yml index 45f32d47..51e82e12 100644 --- a/.github/workflows/build-esp32s2.yml +++ b/.github/workflows/build-esp32s2.yml @@ -2,7 +2,16 @@ name: Build ESP32-S2 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/esp32s2" env-name: "esp32s2" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-esp32s3.yml b/.github/workflows/build-esp32s3.yml index a91fbe89..e47621d4 100644 --- a/.github/workflows/build-esp32s3.yml +++ b/.github/workflows/build-esp32s3.yml @@ -2,7 +2,16 @@ name: Build ESP32-S3 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/esp32s3" env-name: "esp32s3" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-esp8266.yml b/.github/workflows/build-esp8266.yml index 1c3d3661..b6351e96 100644 --- a/.github/workflows/build-esp8266.yml +++ b/.github/workflows/build-esp8266.yml @@ -2,7 +2,16 @@ name: Build ESP8266 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/esp8266" env-name: "esp8266" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-giga-r1.yml b/.github/workflows/build-giga-r1.yml index 0add7bd9..57c76630 100644 --- a/.github/workflows/build-giga-r1.yml +++ b/.github/workflows/build-giga-r1.yml @@ -2,7 +2,16 @@ name: Build Arduino Giga R1 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "Arduino Giga R1" + workflow-name: "Arduino GIGA R1 M7" test-dir: "tests/platform/giga_r1_m7" env-name: "giga_r1" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-leonardo.yml b/.github/workflows/build-leonardo.yml index b818564f..a2343ad5 100644 --- a/.github/workflows/build-leonardo.yml +++ b/.github/workflows/build-leonardo.yml @@ -2,7 +2,16 @@ name: Build Leonardo # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "Leonardo" + workflow-name: "Arduino Leonardo" test-dir: "tests/platform/leonardo" env-name: "leonardo" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-lpc804.yml b/.github/workflows/build-lpc804.yml index 2f234ef6..e5ddba20 100644 --- a/.github/workflows/build-lpc804.yml +++ b/.github/workflows/build-lpc804.yml @@ -2,7 +2,16 @@ name: Build LPC804 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/lpc804" env-name: "lpc804" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-lpc845.yml b/.github/workflows/build-lpc845.yml index 7e1b350c..34eec7af 100644 --- a/.github/workflows/build-lpc845.yml +++ b/.github/workflows/build-lpc845.yml @@ -2,7 +2,16 @@ name: Build LPC845 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "NXP LPC845-BRK" + workflow-name: "NXP LPC845" test-dir: "tests/platform/lpc845" env-name: "lpc845" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-lpc845brk.yml b/.github/workflows/build-lpc845brk.yml index f63b6900..33ad6d12 100644 --- a/.github/workflows/build-lpc845brk.yml +++ b/.github/workflows/build-lpc845brk.yml @@ -2,7 +2,16 @@ name: Build LPC845-BRK # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/lpc845brk" env-name: "lpc845brk" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-lpcxpresso804.yml b/.github/workflows/build-lpcxpresso804.yml index 59b37032..11684075 100644 --- a/.github/workflows/build-lpcxpresso804.yml +++ b/.github/workflows/build-lpcxpresso804.yml @@ -2,7 +2,16 @@ name: Build LPCXpresso804 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/lpcxpresso804" env-name: "lpcxpresso804" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-lpcxpresso845max.yml b/.github/workflows/build-lpcxpresso845max.yml index 8986905d..d4a81e89 100644 --- a/.github/workflows/build-lpcxpresso845max.yml +++ b/.github/workflows/build-lpcxpresso845max.yml @@ -2,7 +2,16 @@ name: Build LPCXpresso845-MAX # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/lpcxpresso845max" env-name: "lpcxpresso845max" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-matrix_portal_m4.yml b/.github/workflows/build-matrix_portal_m4.yml index 1567a3b2..83d67f3b 100644 --- a/.github/workflows/build-matrix_portal_m4.yml +++ b/.github/workflows/build-matrix_portal_m4.yml @@ -2,7 +2,16 @@ name: Build Matrix Portal M4 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "Matrix Portal M4" + workflow-name: "Adafruit Matrix Portal M4" test-dir: "tests/platform/matrix_portal_m4" env-name: "matrix_portal_m4" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-mgm240.yml b/.github/workflows/build-mgm240.yml index 57d4eb74..6089a392 100644 --- a/.github/workflows/build-mgm240.yml +++ b/.github/workflows/build-mgm240.yml @@ -2,7 +2,16 @@ name: Build MGM240 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "MGM240" + workflow-name: "Silicon Labs MGM240" test-dir: "tests/platform/mgm240" env-name: "mgm240" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-nano-every.yml b/.github/workflows/build-nano-every.yml index 967de7eb..23420257 100644 --- a/.github/workflows/build-nano-every.yml +++ b/.github/workflows/build-nano-every.yml @@ -2,7 +2,16 @@ name: Build Nano Every # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "Nano Every" + workflow-name: "Arduino Nano Every" test-dir: "tests/platform/nano_every" env-name: "nano_every" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-nano_every.yml b/.github/workflows/build-nano_every.yml index bc19075f..1d148e5b 100644 --- a/.github/workflows/build-nano_every.yml +++ b/.github/workflows/build-nano_every.yml @@ -2,7 +2,16 @@ name: Build Nano Every # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "Nano Every" + workflow-name: "Arduino Nano Every" test-dir: "tests/platform/nano_every" env-name: "nano_every" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-nice_nano_nrf52840.yml b/.github/workflows/build-nice_nano_nrf52840.yml index 9eaba594..a06e03fb 100644 --- a/.github/workflows/build-nice_nano_nrf52840.yml +++ b/.github/workflows/build-nice_nano_nrf52840.yml @@ -2,7 +2,16 @@ name: Build nice!nano nRF52840 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "nice!nano nRF52840" + workflow-name: "Nice!Nano nRF52840" test-dir: "tests/platform/nice_nano_nrf52840" env-name: "nice_nano_nrf52840" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-nrf52840-sense.yml b/.github/workflows/build-nrf52840-sense.yml index b3a9815d..6628da71 100644 --- a/.github/workflows/build-nrf52840-sense.yml +++ b/.github/workflows/build-nrf52840-sense.yml @@ -2,7 +2,16 @@ name: Build Adafruit Feather NRF52840 Sense # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "Adafruit Feather NRF52840 Sense" + workflow-name: "Adafruit Feather nRF52840 Sense" test-dir: "tests/platform/adafruit_feather_nrf52840_sense" env-name: "nrf52840_sense" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-nrf52840_dk.yml b/.github/workflows/build-nrf52840_dk.yml index 14ce1297..96a651ce 100644 --- a/.github/workflows/build-nrf52840_dk.yml +++ b/.github/workflows/build-nrf52840_dk.yml @@ -2,7 +2,16 @@ name: Build nRF52840 DK # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "nRF52840 DK" + workflow-name: "Nordic nRF52840-DK" test-dir: "tests/platform/nrf52840_dk" env-name: "nrf52840_dk" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-nrfmicro_nrf52840.yml b/.github/workflows/build-nrfmicro_nrf52840.yml index 59e2e0b8..fa30bcbf 100644 --- a/.github/workflows/build-nrfmicro_nrf52840.yml +++ b/.github/workflows/build-nrfmicro_nrf52840.yml @@ -2,7 +2,16 @@ name: Build nRFMicro nRF52840 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "nRFMicro nRF52840" + workflow-name: "nrfmicro nRF52840" test-dir: "tests/platform/nrfmicro_nrf52840" env-name: "nrfmicro_nrf52840" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-nucleo-f429zi.yml b/.github/workflows/build-nucleo-f429zi.yml index 549d5cae..cb2aae2b 100644 --- a/.github/workflows/build-nucleo-f429zi.yml +++ b/.github/workflows/build-nucleo-f429zi.yml @@ -2,7 +2,16 @@ name: Build Nucleo F429ZI # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "Nucleo F429ZI" + workflow-name: "ST Nucleo F429ZI" test-dir: "tests/platform/nucleo_f429zi" env-name: "nucleo_f429zi" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-nucleo-f439zi.yml b/.github/workflows/build-nucleo-f439zi.yml index e58e2e3e..6f5a5268 100644 --- a/.github/workflows/build-nucleo-f439zi.yml +++ b/.github/workflows/build-nucleo-f439zi.yml @@ -2,7 +2,16 @@ name: Build Nucleo F439ZI # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "Nucleo F439ZI" + workflow-name: "ST Nucleo F439ZI" test-dir: "tests/platform/nucleo_f439zi" env-name: "nucleo_f439zi" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-nucleo_f429zi.yml b/.github/workflows/build-nucleo_f429zi.yml index 8cfeecd6..24914975 100644 --- a/.github/workflows/build-nucleo_f429zi.yml +++ b/.github/workflows/build-nucleo_f429zi.yml @@ -2,7 +2,16 @@ name: Build Nucleo F429ZI # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "Nucleo F429ZI" + workflow-name: "ST Nucleo F429ZI" test-dir: "tests/platform/nucleo_f429zi" env-name: "nucleo_f429zi" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-nucleo_f439zi.yml b/.github/workflows/build-nucleo_f439zi.yml index f53e3659..ccac43c6 100644 --- a/.github/workflows/build-nucleo_f439zi.yml +++ b/.github/workflows/build-nucleo_f439zi.yml @@ -2,7 +2,16 @@ name: Build Nucleo F439ZI # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "Nucleo F439ZI" + workflow-name: "ST Nucleo F439ZI" test-dir: "tests/platform/nucleo_f439zi" env-name: "nucleo_f439zi" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-qtpy_m0.yml b/.github/workflows/build-qtpy_m0.yml index 15b11e49..d6b5f624 100644 --- a/.github/workflows/build-qtpy_m0.yml +++ b/.github/workflows/build-qtpy_m0.yml @@ -2,7 +2,16 @@ name: Build QT Py M0 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "QT Py M0" + workflow-name: "Adafruit QT Py M0" test-dir: "tests/platform/qtpy_m0" env-name: "qtpy_m0" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-rp2040.yml b/.github/workflows/build-rp2040.yml index 3e114153..d979599b 100644 --- a/.github/workflows/build-rp2040.yml +++ b/.github/workflows/build-rp2040.yml @@ -2,7 +2,16 @@ name: Build RP2040 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/rp2040" env-name: "rp2040" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-rp2350.yml b/.github/workflows/build-rp2350.yml index 8c4a9fc6..52296fee 100644 --- a/.github/workflows/build-rp2350.yml +++ b/.github/workflows/build-rp2350.yml @@ -2,7 +2,16 @@ name: Build RP2350 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/rp2350" env-name: "rp2350" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-rpipico.yml b/.github/workflows/build-rpipico.yml index 303fffbd..a324a7f2 100644 --- a/.github/workflows/build-rpipico.yml +++ b/.github/workflows/build-rpipico.yml @@ -2,7 +2,16 @@ name: Build Raspberry Pi Pico # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/rpipico" env-name: "rpipico" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-rpipico2.yml b/.github/workflows/build-rpipico2.yml index 6c5eb1e9..96c94683 100644 --- a/.github/workflows/build-rpipico2.yml +++ b/.github/workflows/build-rpipico2.yml @@ -2,7 +2,16 @@ name: Build Raspberry Pi Pico 2 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/rpipico2" env-name: "rpipico2" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-sam3x8e_due.yml b/.github/workflows/build-sam3x8e_due.yml index 32a16444..767aecc3 100644 --- a/.github/workflows/build-sam3x8e_due.yml +++ b/.github/workflows/build-sam3x8e_due.yml @@ -2,7 +2,16 @@ name: Build Arduino Due # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "Arduino Due" + workflow-name: "Atmel SAM3X8E (Due)" test-dir: "tests/platform/sam3x8e_due" env-name: "sam3x8e_due" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-samd21.yml b/.github/workflows/build-samd21.yml index b6815eac..5b0be7fb 100644 --- a/.github/workflows/build-samd21.yml +++ b/.github/workflows/build-samd21.yml @@ -2,7 +2,16 @@ name: Build SAMD21 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "SAMD21" + workflow-name: "Atmel SAMD21" test-dir: "tests/platform/samd21" env-name: "samd21" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-samd21_zero.yml b/.github/workflows/build-samd21_zero.yml index b053cba1..f0ee3c06 100644 --- a/.github/workflows/build-samd21_zero.yml +++ b/.github/workflows/build-samd21_zero.yml @@ -2,7 +2,16 @@ name: Build Arduino Zero # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "Arduino Zero" + workflow-name: "Arduino Zero (SAMD21)" test-dir: "tests/platform/samd21_zero" env-name: "samd21_zero" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-samd51j.yml b/.github/workflows/build-samd51j.yml index f3092129..92f9f30d 100644 --- a/.github/workflows/build-samd51j.yml +++ b/.github/workflows/build-samd51j.yml @@ -2,7 +2,16 @@ name: Build SAMD51J # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "SAMD51J" + workflow-name: "Atmel SAMD51J" test-dir: "tests/platform/samd51j" env-name: "samd51j" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-samd51p.yml b/.github/workflows/build-samd51p.yml index e2626954..fc263a72 100644 --- a/.github/workflows/build-samd51p.yml +++ b/.github/workflows/build-samd51p.yml @@ -2,7 +2,16 @@ name: Build SAMD51P # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "SAMD51P" + workflow-name: "Atmel SAMD51P" test-dir: "tests/platform/samd51p" env-name: "samd51p" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-stm32f103c8.yml b/.github/workflows/build-stm32f103c8.yml index 42a9ed2c..e8ac3459 100644 --- a/.github/workflows/build-stm32f103c8.yml +++ b/.github/workflows/build-stm32f103c8.yml @@ -2,7 +2,16 @@ name: Build STM32F103C8 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/stm32f103c8" env-name: "stm32f103c8" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-stm32f103cb.yml b/.github/workflows/build-stm32f103cb.yml index d05fc6f5..108d688f 100644 --- a/.github/workflows/build-stm32f103cb.yml +++ b/.github/workflows/build-stm32f103cb.yml @@ -2,7 +2,16 @@ name: Build STM32F103CB # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/stm32f103cb" env-name: "stm32f103cb" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-stm32f103tb.yml b/.github/workflows/build-stm32f103tb.yml index 2ccd4e57..c13b62ea 100644 --- a/.github/workflows/build-stm32f103tb.yml +++ b/.github/workflows/build-stm32f103tb.yml @@ -2,7 +2,16 @@ name: Build STM32F103TB # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/stm32f103tb" env-name: "stm32f103tb" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-stm32f411ce.yml b/.github/workflows/build-stm32f411ce.yml index c2bf07a7..221fad28 100644 --- a/.github/workflows/build-stm32f411ce.yml +++ b/.github/workflows/build-stm32f411ce.yml @@ -2,7 +2,16 @@ name: Build STM32F411CE # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/stm32f411ce" env-name: "stm32f411ce" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-stm32h747xi.yml b/.github/workflows/build-stm32h747xi.yml index ac7176cd..87796365 100644 --- a/.github/workflows/build-stm32h747xi.yml +++ b/.github/workflows/build-stm32h747xi.yml @@ -2,7 +2,16 @@ name: Build STM32H747XI # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/stm32h747xi" env-name: "stm32h747xi" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-supermini_nrf52840.yml b/.github/workflows/build-supermini_nrf52840.yml index c6b53ad9..89f0fd26 100644 --- a/.github/workflows/build-supermini_nrf52840.yml +++ b/.github/workflows/build-supermini_nrf52840.yml @@ -2,7 +2,16 @@ name: Build SuperMini nRF52840 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/supermini_nrf52840" env-name: "supermini_nrf52840" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-teensy30.yml b/.github/workflows/build-teensy30.yml index eb7e7002..934850b1 100644 --- a/.github/workflows/build-teensy30.yml +++ b/.github/workflows/build-teensy30.yml @@ -2,7 +2,16 @@ name: Build Teensy 3.0 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/teensy30" env-name: "teensy30" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-teensy31.yml b/.github/workflows/build-teensy31.yml index 2d15bab1..e82859d9 100644 --- a/.github/workflows/build-teensy31.yml +++ b/.github/workflows/build-teensy31.yml @@ -2,7 +2,16 @@ name: Build Teensy 3.1 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/teensy31" env-name: "teensy31" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-teensy32.yml b/.github/workflows/build-teensy32.yml index c8f152a4..2d586476 100644 --- a/.github/workflows/build-teensy32.yml +++ b/.github/workflows/build-teensy32.yml @@ -2,7 +2,16 @@ name: Build Teensy 3.2 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/teensy32" env-name: "teensy32" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-teensy35.yml b/.github/workflows/build-teensy35.yml index 851d13e5..7c0009de 100644 --- a/.github/workflows/build-teensy35.yml +++ b/.github/workflows/build-teensy35.yml @@ -2,7 +2,16 @@ name: Build Teensy 3.5 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/teensy35" env-name: "teensy35" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-teensy36.yml b/.github/workflows/build-teensy36.yml index 0fc1956f..eaa57538 100644 --- a/.github/workflows/build-teensy36.yml +++ b/.github/workflows/build-teensy36.yml @@ -2,7 +2,16 @@ name: Build Teensy 3.6 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/teensy36" env-name: "teensy36" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-teensy40.yml b/.github/workflows/build-teensy40.yml index 87af1f68..9b04e5bf 100644 --- a/.github/workflows/build-teensy40.yml +++ b/.github/workflows/build-teensy40.yml @@ -2,7 +2,16 @@ name: Build Teensy 4.0 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/teensy40" env-name: "teensy40" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-teensy41.yml b/.github/workflows/build-teensy41.yml index 0364ff9c..37749931 100644 --- a/.github/workflows/build-teensy41.yml +++ b/.github/workflows/build-teensy41.yml @@ -2,7 +2,16 @@ name: Build Teensy 4.1 # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/teensy41" env-name: "teensy41" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-teensylc.yml b/.github/workflows/build-teensylc.yml index 907cb30c..856dca72 100644 --- a/.github/workflows/build-teensylc.yml +++ b/.github/workflows/build-teensylc.yml @@ -2,7 +2,16 @@ name: Build Teensy LC # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/teensylc" env-name: "teensylc" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-thingplusmatter.yml b/.github/workflows/build-thingplusmatter.yml index df3eaec6..582be71b 100644 --- a/.github/workflows/build-thingplusmatter.yml +++ b/.github/workflows/build-thingplusmatter.yml @@ -2,7 +2,16 @@ name: Build SparkFun Thing Plus Matter # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/sparkfun_thingplusmatter" env-name: "thingplusmatter" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-tinystm.yml b/.github/workflows/build-tinystm.yml index 123952db..dd1e489a 100644 --- a/.github/workflows/build-tinystm.yml +++ b/.github/workflows/build-tinystm.yml @@ -2,7 +2,16 @@ name: Build TinySTM103TB # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "TinySTM103TB" + workflow-name: "HY TinySTM103TB" test-dir: "tests/platform/hy_tinystm103tb" env-name: "tinystm" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-uno-r4-wifi.yml b/.github/workflows/build-uno-r4-wifi.yml index ff5decc6..004a8e13 100644 --- a/.github/workflows/build-uno-r4-wifi.yml +++ b/.github/workflows/build-uno-r4-wifi.yml @@ -2,7 +2,16 @@ name: Build Arduino Uno R4 WiFi # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/uno_r4_wifi" env-name: "uno_r4_wifi" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-uno.yml b/.github/workflows/build-uno.yml index e742f092..d802b1d3 100644 --- a/.github/workflows/build-uno.yml +++ b/.github/workflows/build-uno.yml @@ -2,7 +2,16 @@ name: Build Arduino Uno # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -18,3 +27,6 @@ jobs: test-dir: "tests/platform/uno" env-name: "uno" firmware-ext: "hex" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/build-uno_r4_wifi.yml b/.github/workflows/build-uno_r4_wifi.yml index 262791c0..435ad3c9 100644 --- a/.github/workflows/build-uno_r4_wifi.yml +++ b/.github/workflows/build-uno_r4_wifi.yml @@ -2,7 +2,16 @@ name: Build UNO R4 WiFi # >>> RENDERED-ON-BEGIN (ci/render_workflows.py) -- do not edit by hand <<< on: - workflow_dispatch: {} + workflow_dispatch: + inputs: + fbuild-run-id: + description: 'Run holding a prebuilt fbuild artifact (empty: compile here)' + type: string + default: '' + checkout_ref: + description: 'Commit to build (empty: the dispatched ref)' + type: string + default: '' workflow_call: {} concurrency: @@ -14,7 +23,10 @@ jobs: build: uses: ./.github/workflows/template_build.yml with: - workflow-name: "UNO R4 WiFi" + workflow-name: "Arduino Uno R4 WiFi" test-dir: "tests/platform/uno_r4_wifi" env-name: "uno_r4_wifi" firmware-ext: "bin" + checkout_ref: ${{ inputs.checkout_ref }} + fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} + fbuild-run-id: ${{ inputs.fbuild-run-id }} diff --git a/.github/workflows/nightly-platforms.yml b/.github/workflows/nightly-platforms.yml index 1f2f22d3..f814bcc3 100644 --- a/.github/workflows/nightly-platforms.yml +++ b/.github/workflows/nightly-platforms.yml @@ -1,5 +1,5 @@ -# Daily safety-net sweep of every per-board build workflow. -# See FastLED/fbuild#835. +# Board dispatcher: path-selected on push to main, all boards nightly. +# See FastLED/fbuild#835 and ci/select_boards.py. # # This file is AUTOGENERATED from ci/board_families.json. # Edit the SOT and re-run `uv run python ci/render_workflows.py`. @@ -7,6 +7,8 @@ name: Nightly Platforms on: + push: + branches: [main] schedule: # 11:00 UTC = 03:00 PST (winter) / 04:00 PDT (summer). GitHub cron # has no timezone, so one of the two has to drift; 3am standard @@ -15,44 +17,43 @@ on: workflow_dispatch: inputs: force: - description: 'Run all platform builds even without recent commits' + description: 'Dispatch all platform builds even without recent commits' type: boolean default: false jobs: - guard: - name: Guard (skip on quiet days) + plan: + name: Select boards runs-on: ubuntu-latest outputs: - should_run: ${{ steps.check.outputs.should_run }} + workflows: ${{ steps.select.outputs.workflows }} steps: - uses: actions/checkout@v6 with: fetch-depth: 0 - - id: check + - uses: astral-sh/setup-uv@v3 + - id: select env: - FORCE: ${{ inputs.force }} + EVENT: ${{ github.event_name }} + BEFORE: ${{ github.event.before }} run: | - if [ "$FORCE" = "true" ]; then - echo "force=true -- running nightly sweep regardless of commit activity" - echo "should_run=true" >> "$GITHUB_OUTPUT" + if [ "$EVENT" = push ]; then + args=(--base "$BEFORE" --head "$GITHUB_SHA") + elif [ "$EVENT" = schedule ] && [ -z "$(git log --since='24 hours ago' --oneline HEAD)" ]; then + echo 'No commits in the last 24h -- nothing to dispatch' + echo 'workflows=[]' >> "$GITHUB_OUTPUT" exit 0 - fi - # Scheduled runs check out the default branch's HEAD; on - # workflow_dispatch from a feature branch this checks that - # branch instead, which is the right behavior for manual runs. - if [ -z "$(git log --since='24 hours ago' --oneline HEAD)" ]; then - echo "No commits in the last 24h -- skipping nightly platform sweep" - echo "should_run=false" >> "$GITHUB_OUTPUT" else - echo "Recent commits found -- running full nightly sweep" - echo "should_run=true" >> "$GITHUB_OUTPUT" + args=(--all) fi + workflows=$(cd ci && uv run --no-project python select_boards.py "${args[@]}") + echo "selected: $workflows" + echo "workflows=$workflows" >> "$GITHUB_OUTPUT" fbuild_bin: name: Build fbuild (shared by board jobs) - if: needs.guard.outputs.should_run == 'true' - needs: guard + if: needs.plan.outputs.workflows != '[]' + needs: plan runs-on: ubuntu-latest timeout-minutes: 30 env: @@ -84,398 +85,20 @@ jobs: target/debug/fbuild-daemon if-no-files-found: error retention-days: 1 - build: - name: ${{ matrix.workflow_name }} - needs: [guard, fbuild_bin] - if: needs.guard.outputs.should_run == 'true' - strategy: - fail-fast: false - matrix: - include: - - workflow_name: "Ambiq Apollo3 Red" - test_dir: "tests/platform/apollo3_red" - env_name: "apollo3_red" - firmware_ext: "bin" - workflow_aliases: ["build-apollo3_red.yml"] - - workflow_name: "Apollo3 Thing Explorable" - test_dir: "tests/platform/apollo3_thing_explorable" - env_name: "apollo3_thing_explorable" - firmware_ext: "bin" - workflow_aliases: ["build-apollo3_thing_explorable.yml"] - - workflow_name: "ATmega8" - test_dir: "tests/platform/atmega8" - env_name: "atmega8" - firmware_ext: "hex" - workflow_aliases: ["build-atmega8.yml"] - - workflow_name: "ATmega8A" - test_dir: "tests/platform/atmega8a" - env_name: "atmega8a" - firmware_ext: "hex" - workflow_aliases: ["build-atmega8a.yml"] - - workflow_name: "ATtiny1604" - test_dir: "tests/platform/attiny1604" - env_name: "attiny1604" - firmware_ext: "hex" - workflow_aliases: ["build-attiny1604.yml"] - - workflow_name: "ATtiny1616" - test_dir: "tests/platform/attiny1616" - env_name: "attiny1616" - firmware_ext: "hex" - workflow_aliases: ["build-attiny1616.yml"] - - workflow_name: "ATtiny4313" - test_dir: "tests/platform/attiny4313" - env_name: "attiny4313" - firmware_ext: "hex" - workflow_aliases: ["build-attiny4313.yml"] - - workflow_name: "ATtiny85" - test_dir: "tests/platform/attiny85" - env_name: "attiny85" - firmware_ext: "hex" - workflow_aliases: ["build-attiny85.yml"] - - workflow_name: "ATtiny88" - test_dir: "tests/platform/attiny88" - env_name: "attiny88" - firmware_ext: "hex" - workflow_aliases: ["build-attiny88.yml"] - - workflow_name: "STM32 BlackPill F411CE" - test_dir: "tests/platform/blackpill_f411ce" - env_name: "blackpill" - firmware_ext: "hex" - workflow_aliases: ["build-blackpill.yml"] - - workflow_name: "STM32 BluePill F103C8" - test_dir: "tests/platform/bluepill_f103c8" - env_name: "bluepill" - firmware_ext: "hex" - workflow_aliases: ["build-bluepill.yml"] - - workflow_name: "CH32L103" - test_dir: "tests/platform/ch32l103" - env_name: "ch32l103" - firmware_ext: "bin" - workflow_aliases: ["build-ch32l103.yml"] - - workflow_name: "CH32V003" - test_dir: "tests/platform/ch32v003" - env_name: "ch32v003" - firmware_ext: "bin" - workflow_aliases: ["build-ch32v003.yml"] - - workflow_name: "CH32V006" - test_dir: "tests/platform/ch32v006" - env_name: "ch32v006" - firmware_ext: "bin" - workflow_aliases: ["build-ch32v006.yml"] - - workflow_name: "CH32V103" - test_dir: "tests/platform/ch32v103" - env_name: "ch32v103" - firmware_ext: "bin" - workflow_aliases: ["build-ch32v103.yml"] - - workflow_name: "CH32V203" - test_dir: "tests/platform/ch32v203" - env_name: "ch32v203" - firmware_ext: "bin" - workflow_aliases: ["build-ch32v203.yml"] - - workflow_name: "CH32V208" - test_dir: "tests/platform/ch32v208" - env_name: "ch32v208" - firmware_ext: "bin" - workflow_aliases: ["build-ch32v208.yml"] - - workflow_name: "CH32V303" - test_dir: "tests/platform/ch32v303" - env_name: "ch32v303" - firmware_ext: "bin" - workflow_aliases: ["build-ch32v303.yml"] - - workflow_name: "CH32V307" - test_dir: "tests/platform/ch32v307" - env_name: "ch32v307" - firmware_ext: "bin" - workflow_aliases: ["build-ch32v307.yml"] - - workflow_name: "CH32X035" - test_dir: "tests/platform/ch32x035" - env_name: "ch32x035" - firmware_ext: "bin" - workflow_aliases: ["build-ch32x035.yml"] - - workflow_name: "Teknic ClearCore (SAME53)" - test_dir: "tests/platform/clearcore" - env_name: "clearcore" - firmware_ext: "bin" - workflow_aliases: ["build-clearcore.yml"] - - workflow_name: "Arduino Due" - test_dir: "tests/platform/due" - env_name: "due" - firmware_ext: "bin" - workflow_aliases: ["build-due.yml"] - - workflow_name: "ESP32-C2" - test_dir: "tests/platform/esp32c2" - env_name: "esp32c2" - firmware_ext: "bin" - workflow_aliases: ["build-esp32c2.yml"] - - workflow_name: "ESP32-C3" - test_dir: "tests/platform/esp32c3" - env_name: "esp32c3" - firmware_ext: "bin" - workflow_aliases: ["build-esp32c3.yml"] - - workflow_name: "ESP32-C5" - test_dir: "tests/platform/esp32c5" - env_name: "esp32c5" - firmware_ext: "bin" - workflow_aliases: ["build-esp32c5.yml"] - - workflow_name: "ESP32-C6" - test_dir: "tests/platform/esp32c6" - env_name: "esp32c6" - firmware_ext: "bin" - workflow_aliases: ["build-esp32c6.yml"] - - workflow_name: "ESP32 Dev" - test_dir: "tests/platform/esp32dev" - env_name: "esp32dev" - firmware_ext: "bin" - workflow_aliases: ["build-esp32dev.yml"] - - workflow_name: "ESP32-H2" - test_dir: "tests/platform/esp32h2" - env_name: "esp32h2" - firmware_ext: "bin" - workflow_aliases: ["build-esp32h2.yml"] - - workflow_name: "ESP32-P4" - test_dir: "tests/platform/esp32p4" - env_name: "esp32p4" - firmware_ext: "bin" - workflow_aliases: ["build-esp32p4.yml"] - - workflow_name: "ESP32-S2" - test_dir: "tests/platform/esp32s2" - env_name: "esp32s2" - firmware_ext: "bin" - workflow_aliases: ["build-esp32s2.yml"] - - workflow_name: "ESP32-S3" - test_dir: "tests/platform/esp32s3" - env_name: "esp32s3" - firmware_ext: "bin" - workflow_aliases: ["build-esp32s3.yml"] - - workflow_name: "ESP8266" - test_dir: "tests/platform/esp8266" - env_name: "esp8266" - firmware_ext: "bin" - workflow_aliases: ["build-esp8266.yml"] - - workflow_name: "Arduino GIGA R1 M7" - test_dir: "tests/platform/giga_r1_m7" - env_name: "giga_r1" - firmware_ext: "bin" - workflow_aliases: ["build-giga-r1.yml"] - - workflow_name: "Arduino Leonardo" - test_dir: "tests/platform/leonardo" - env_name: "leonardo" - firmware_ext: "hex" - workflow_aliases: ["build-leonardo.yml"] - - workflow_name: "NXP LPCXpresso804" - test_dir: "tests/platform/lpc804" - env_name: "lpc804" - firmware_ext: "bin" - workflow_aliases: ["build-lpc804.yml"] - - workflow_name: "NXP LPC845" - test_dir: "tests/platform/lpc845" - env_name: "lpc845" - firmware_ext: "bin" - workflow_aliases: ["build-lpc845.yml"] - - workflow_name: "NXP LPC845-BRK" - test_dir: "tests/platform/lpc845brk" - env_name: "lpc845brk" - firmware_ext: "bin" - workflow_aliases: ["build-lpc845brk.yml"] - - workflow_name: "NXP LPCXpresso804" - test_dir: "tests/platform/lpcxpresso804" - env_name: "lpcxpresso804" - firmware_ext: "bin" - workflow_aliases: ["build-lpcxpresso804.yml"] - - workflow_name: "NXP LPCXpresso845-MAX" - test_dir: "tests/platform/lpcxpresso845max" - env_name: "lpcxpresso845max" - firmware_ext: "bin" - workflow_aliases: ["build-lpcxpresso845max.yml"] - - workflow_name: "Adafruit Matrix Portal M4" - test_dir: "tests/platform/matrix_portal_m4" - env_name: "matrix_portal_m4" - firmware_ext: "bin" - workflow_aliases: ["build-matrix_portal_m4.yml"] - - workflow_name: "Silicon Labs MGM240" - test_dir: "tests/platform/mgm240" - env_name: "mgm240" - firmware_ext: "bin" - workflow_aliases: ["build-mgm240.yml"] - - workflow_name: "Arduino Nano Every" - test_dir: "tests/platform/nano_every" - env_name: "nano_every" - firmware_ext: "hex" - workflow_aliases: ["build-nano-every.yml", "build-nano_every.yml"] - - workflow_name: "Nice!Nano nRF52840" - test_dir: "tests/platform/nice_nano_nrf52840" - env_name: "nice_nano_nrf52840" - firmware_ext: "hex" - workflow_aliases: ["build-nice_nano_nrf52840.yml"] - - workflow_name: "Adafruit Feather nRF52840 Sense" - test_dir: "tests/platform/adafruit_feather_nrf52840_sense" - env_name: "nrf52840_sense" - firmware_ext: "hex" - workflow_aliases: ["build-nrf52840-sense.yml"] - - workflow_name: "Nordic nRF52840-DK" - test_dir: "tests/platform/nrf52840_dk" - env_name: "nrf52840_dk" - firmware_ext: "hex" - workflow_aliases: ["build-nrf52840_dk.yml"] - - workflow_name: "nrfmicro nRF52840" - test_dir: "tests/platform/nrfmicro_nrf52840" - env_name: "nrfmicro_nrf52840" - firmware_ext: "hex" - workflow_aliases: ["build-nrfmicro_nrf52840.yml"] - - workflow_name: "ST Nucleo F429ZI" - test_dir: "tests/platform/nucleo_f429zi" - env_name: "nucleo_f429zi" - firmware_ext: "hex" - workflow_aliases: ["build-nucleo-f429zi.yml", "build-nucleo_f429zi.yml"] - - workflow_name: "ST Nucleo F439ZI" - test_dir: "tests/platform/nucleo_f439zi" - env_name: "nucleo_f439zi" - firmware_ext: "hex" - workflow_aliases: ["build-nucleo-f439zi.yml", "build-nucleo_f439zi.yml"] - - workflow_name: "Adafruit QT Py M0" - test_dir: "tests/platform/qtpy_m0" - env_name: "qtpy_m0" - firmware_ext: "bin" - workflow_aliases: ["build-qtpy_m0.yml"] - - workflow_name: "RP2040" - test_dir: "tests/platform/rp2040" - env_name: "rp2040" - firmware_ext: "bin" - workflow_aliases: ["build-rp2040.yml"] - - workflow_name: "RP2350" - test_dir: "tests/platform/rp2350" - env_name: "rp2350" - firmware_ext: "bin" - workflow_aliases: ["build-rp2350.yml"] - - workflow_name: "Raspberry Pi Pico" - test_dir: "tests/platform/rpipico" - env_name: "rpipico" - firmware_ext: "bin" - workflow_aliases: ["build-rpipico.yml"] - - workflow_name: "Raspberry Pi Pico 2" - test_dir: "tests/platform/rpipico2" - env_name: "rpipico2" - firmware_ext: "bin" - workflow_aliases: ["build-rpipico2.yml"] - - workflow_name: "Atmel SAM3X8E (Due)" - test_dir: "tests/platform/sam3x8e_due" - env_name: "sam3x8e_due" - firmware_ext: "bin" - workflow_aliases: ["build-sam3x8e_due.yml"] - - workflow_name: "Atmel SAMD21" - test_dir: "tests/platform/samd21" - env_name: "samd21" - firmware_ext: "bin" - workflow_aliases: ["build-samd21.yml"] - - workflow_name: "Arduino Zero (SAMD21)" - test_dir: "tests/platform/samd21_zero" - env_name: "samd21_zero" - firmware_ext: "bin" - workflow_aliases: ["build-samd21_zero.yml"] - - workflow_name: "Atmel SAMD51J" - test_dir: "tests/platform/samd51j" - env_name: "samd51j" - firmware_ext: "bin" - workflow_aliases: ["build-samd51j.yml"] - - workflow_name: "Atmel SAMD51P" - test_dir: "tests/platform/samd51p" - env_name: "samd51p" - firmware_ext: "bin" - workflow_aliases: ["build-samd51p.yml"] - - workflow_name: "STM32F103C8" - test_dir: "tests/platform/stm32f103c8" - env_name: "stm32f103c8" - firmware_ext: "hex" - workflow_aliases: ["build-stm32f103c8.yml"] - - workflow_name: "STM32F103CB" - test_dir: "tests/platform/stm32f103cb" - env_name: "stm32f103cb" - firmware_ext: "hex" - workflow_aliases: ["build-stm32f103cb.yml"] - - workflow_name: "STM32F103TB" - test_dir: "tests/platform/stm32f103tb" - env_name: "stm32f103tb" - firmware_ext: "hex" - workflow_aliases: ["build-stm32f103tb.yml"] - - workflow_name: "STM32F411CE" - test_dir: "tests/platform/stm32f411ce" - env_name: "stm32f411ce" - firmware_ext: "hex" - workflow_aliases: ["build-stm32f411ce.yml"] - - workflow_name: "STM32H747XI" - test_dir: "tests/platform/stm32h747xi" - env_name: "stm32h747xi" - firmware_ext: "bin" - workflow_aliases: ["build-stm32h747xi.yml"] - - workflow_name: "SuperMini nRF52840" - test_dir: "tests/platform/supermini_nrf52840" - env_name: "supermini_nrf52840" - firmware_ext: "hex" - workflow_aliases: ["build-supermini_nrf52840.yml"] - - workflow_name: "Teensy 3.0" - test_dir: "tests/platform/teensy30" - env_name: "teensy30" - firmware_ext: "hex" - workflow_aliases: ["build-teensy30.yml"] - - workflow_name: "Teensy 3.1" - test_dir: "tests/platform/teensy31" - env_name: "teensy31" - firmware_ext: "hex" - workflow_aliases: ["build-teensy31.yml"] - - workflow_name: "Teensy 3.2" - test_dir: "tests/platform/teensy32" - env_name: "teensy32" - firmware_ext: "hex" - workflow_aliases: ["build-teensy32.yml"] - - workflow_name: "Teensy 3.5" - test_dir: "tests/platform/teensy35" - env_name: "teensy35" - firmware_ext: "hex" - workflow_aliases: ["build-teensy35.yml"] - - workflow_name: "Teensy 3.6" - test_dir: "tests/platform/teensy36" - env_name: "teensy36" - firmware_ext: "hex" - workflow_aliases: ["build-teensy36.yml"] - - workflow_name: "Teensy 4.0" - test_dir: "tests/platform/teensy40" - env_name: "teensy40" - firmware_ext: "hex" - workflow_aliases: ["build-teensy40.yml"] - - workflow_name: "Teensy 4.1" - test_dir: "tests/platform/teensy41" - env_name: "teensy41" - firmware_ext: "hex" - workflow_aliases: ["build-teensy41.yml"] - - workflow_name: "Teensy LC" - test_dir: "tests/platform/teensylc" - env_name: "teensylc" - firmware_ext: "hex" - workflow_aliases: ["build-teensylc.yml"] - - workflow_name: "SparkFun Thing Plus Matter" - test_dir: "tests/platform/sparkfun_thingplusmatter" - env_name: "thingplusmatter" - firmware_ext: "bin" - workflow_aliases: ["build-thingplusmatter.yml"] - - workflow_name: "HY TinySTM103TB" - test_dir: "tests/platform/hy_tinystm103tb" - env_name: "tinystm" - firmware_ext: "hex" - workflow_aliases: ["build-tinystm.yml"] - - workflow_name: "Arduino Uno R4 WiFi" - test_dir: "tests/platform/uno_r4_wifi" - env_name: "uno_r4_wifi" - firmware_ext: "bin" - workflow_aliases: ["build-uno-r4-wifi.yml", "build-uno_r4_wifi.yml"] - - workflow_name: "Arduino Uno" - test_dir: "tests/platform/uno" - env_name: "uno" - firmware_ext: "hex" - workflow_aliases: ["build-uno.yml"] - uses: ./.github/workflows/template_build.yml - with: - workflow-name: ${{ matrix.workflow_name }} - test-dir: ${{ matrix.test_dir }} - env-name: ${{ matrix.env_name }} - firmware-ext: ${{ matrix.firmware_ext }} - fbuild-artifact: fbuild-bin-linux-debug + dispatch: + name: Dispatch board workflows + needs: [plan, fbuild_bin] + runs-on: ubuntu-latest + permissions: + actions: write + steps: + - env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + WORKFLOWS: ${{ needs.plan.outputs.workflows }} + run: | + for wf in $(echo "$WORKFLOWS" | jq -r '.[]'); do + gh workflow run "$wf" --ref "$GITHUB_REF_NAME" \ + -f fbuild-run-id="$GITHUB_RUN_ID" -f checkout_ref="$GITHUB_SHA" + echo "dispatched $wf" + done diff --git a/.github/workflows/template_build.yml b/.github/workflows/template_build.yml index 7a279336..e9bab2d9 100644 --- a/.github/workflows/template_build.yml +++ b/.github/workflows/template_build.yml @@ -34,6 +34,15 @@ on: runners only execute"): the per-board compile was ~350s of a ~550s job, repeated across ~76 boards. Empty keeps the standalone compile path for direct `build-.yml` dispatches. + fbuild-run-id: + required: false + type: string + default: "" + description: >- + Workflow run that uploaded `fbuild-artifact`. Empty means this run. + Set when nightly-platforms.yml dispatches `build-.yml` as + its own run (so the board's README badge updates) while still + reusing the dispatcher's single fbuild compile. env: CARGO_TERM_COLOR: always @@ -153,6 +162,8 @@ jobs: with: name: ${{ inputs.fbuild-artifact }} path: target/debug + run-id: ${{ inputs.fbuild-run-id || github.run_id }} + github-token: ${{ github.token }} - name: Restore executable bits on prebuilt binaries if: inputs.fbuild-artifact != '' diff --git a/ci/README.md b/ci/README.md index f3172ca1..411b9b7b 100644 --- a/ci/README.md +++ b/ci/README.md @@ -15,6 +15,7 @@ Python scripts for CI, packaging, and development tooling. All invoked via `uv r - **`lint.py`** -- Workspace linting (rustfmt + clippy), supports single-file and auto-fix modes - **`platform_boundary_research.py`** -- Host-independent phase-1 inventory and cross-host drift check for FastLED/fbuild#1307 - **`render_workflows.py`** -- Re-renders the `on:` and `concurrency:` blocks of `.github/workflows/build-*.yml` and the full `nightly-platforms.yml` from `board_families.json` + `ci_common_paths.txt`. CI invokes `--check` to enforce no drift. See [docs/DEVELOPMENT.md](../docs/DEVELOPMENT.md#ci-per-board-build-triggers) and FastLED/fbuild#835. +- **`select_boards.py`** -- Picks which `build-.yml` workflows `nightly-platforms.yml` dispatches: path-selected from a push diff, or `--all` for the nightly badge refresh. Tested by `test_select_boards.py`. - **`board_families.json`** -- SOT: per-board metadata (workflow / test_dir / env_name / family) plus the family → crate-path mapping consumed by `render_workflows.py`. - **`ci_common_paths.txt`** -- SOT: paths whose changes force-run *every* per-board build workflow. - **`test.py`** -- Workspace test runner with `--full` (stress + integration) and per-crate filtering diff --git a/ci/render_workflows.py b/ci/render_workflows.py index d848e1ad..dbd05cc7 100644 --- a/ci/render_workflows.py +++ b/ci/render_workflows.py @@ -135,13 +135,41 @@ def render_concurrency_block(board: dict) -> str: def render_on_block(board: dict, families: dict, common_paths: list[str]) -> str: + # Board workflows run as their own runs only when nightly-platforms.yml + # dispatches them (path-selected on push to main, all boards on the + # nightly schedule) -- that is what keeps each README badge current. return ( "on:\n" - " workflow_dispatch: {}\n" + " workflow_dispatch:\n" + " inputs:\n" + " fbuild-run-id:\n" + " description: 'Run holding a prebuilt fbuild artifact (empty: compile here)'\n" + " type: string\n" + " default: ''\n" + " checkout_ref:\n" + " description: 'Commit to build (empty: the dispatched ref)'\n" + " type: string\n" + " default: ''\n" " workflow_call: {}\n" ) + render_concurrency_block(board) +def render_board_jobs(board: dict) -> str: + return ( + "jobs:\n" + " build:\n" + " uses: ./.github/workflows/template_build.yml\n" + " with:\n" + f" workflow-name: {json.dumps(board['workflow_name'])}\n" + f" test-dir: {json.dumps(board['test_dir'])}\n" + f" env-name: {json.dumps(board['env_name'])}\n" + f" firmware-ext: {json.dumps(board['firmware_ext'])}\n" + " checkout_ref: ${{ inputs.checkout_ref }}\n" + f" fbuild-artifact: ${{{{ inputs.fbuild-run-id && '{FBUILD_BIN_ARTIFACT}' || '' }}}}\n" + " fbuild-run-id: ${{ inputs.fbuild-run-id }}\n" + ) + + def execution_boards(boards: list[dict]) -> list[dict]: """Run identical build inputs once while retaining every workflow alias.""" unique: dict[tuple[str, str, str], dict] = {} @@ -495,63 +523,32 @@ def _job_id(workflow: str) -> str: def render_nightly(boards: list[dict]) -> str: - """Render .github/workflows/nightly-platforms.yml from the SOT. - - Fan-out: ONE matrix job that calls `template_build.yml` directly, once - per board. A single guard job decides whether the sweep runs at all -- - if no commits landed in the last 24h, the build job is skipped via - `if:`. workflow_dispatch exposes a `force` boolean to bypass the guard - for manual reruns. - - This deliberately does NOT do the obvious thing of emitting one - `uses: ./.github/workflows/build-.yml` job per board. GitHub caps - a single workflow file at **20 unique reusable workflows**, counting the - whole nested tree. Referencing all ~79 per-board workflows blew straight - past that cap, and the failure mode gives you nothing to debug: the run - is created, immediately reports "This run likely failed because of a - workflow file issue", and produces **zero jobs** and no logs. The YAML is - perfectly valid, so neither a linter nor `yaml.safe_load` flags it. - - Calling the shared template with a matrix keeps the unique-reusable count - at 1 no matter how many boards the SOT grows to. - - Matrix keys use underscores, not hyphens, on purpose: `matrix.test-dir` - parses as a subtraction in a GitHub expression, silently yielding an - empty value rather than an error. The hyphenated names are reintroduced - only in the `with:` block, where they are input keys rather than - expressions. + """Render .github/workflows/nightly-platforms.yml: the board dispatcher. + + README badges track runs of each `build-.yml` *file*; a board + built from inside another workflow (a matrix over template_build.yml) + never moves its badge. So this workflow compiles fbuild once, then + `gh workflow run`s each selected board workflow as its own run, passing + this run's id so the board downloads the prebuilt binary instead of + compiling it (GITHUB_TOKEN-created `workflow_dispatch` runs are the one + event GitHub allows to start new runs). + + Selection (ci/select_boards.py): + - push to main: only boards whose trigger paths the push touched + (own test dir, family crate paths, own workflow file; shared paths + select the `core` boards only). + - schedule: every board, so every badge refreshes daily -- skipped + when no commits landed in 24h (nothing could have changed). + - workflow_dispatch: every board. + + The dispatcher does not call the ~80 board workflows as reusable + workflows: GitHub caps a workflow file at 20 unique reusable workflows + and fails such a run with zero jobs and no logs. """ - matrix_entries: list[str] = [] - for b in execution_boards(boards): - matrix_entries.append( - f" - workflow_name: {json.dumps(b['workflow_name'])}\n" - f" test_dir: {json.dumps(b['test_dir'])}\n" - f" env_name: {json.dumps(b['env_name'])}\n" - f" firmware_ext: {json.dumps(b['firmware_ext'])}\n" - f" workflow_aliases: {json.dumps(b['workflow_aliases'])}\n" - ) - jobs_yaml = ( - render_fbuild_bin_job("guard", " if: needs.guard.outputs.should_run == 'true'\n", "${{ github.sha }}") - + " build:\n" - " name: ${{ matrix.workflow_name }}\n" - " needs: [guard, fbuild_bin]\n" - " if: needs.guard.outputs.should_run == 'true'\n" - " strategy:\n" - # One broken board must not cancel the other 78 -- the whole point of - # a nightly sweep is a complete picture of what is red. - " fail-fast: false\n" - " matrix:\n" - " include:\n" + "".join(matrix_entries) + " uses: ./.github/workflows/template_build.yml\n" - " with:\n" - " workflow-name: ${{ matrix.workflow_name }}\n" - " test-dir: ${{ matrix.test_dir }}\n" - " env-name: ${{ matrix.env_name }}\n" - " firmware-ext: ${{ matrix.firmware_ext }}\n" - f" fbuild-artifact: {FBUILD_BIN_ARTIFACT}\n" - ) + del boards # selection reads the SOT at run time via ci/select_boards.py header = ( - "# Daily safety-net sweep of every per-board build workflow.\n" - "# See FastLED/fbuild#835.\n" + "# Board dispatcher: path-selected on push to main, all boards nightly.\n" + "# See FastLED/fbuild#835 and ci/select_boards.py.\n" "#\n" "# This file is AUTOGENERATED from ci/board_families.json.\n" "# Edit the SOT and re-run `uv run python ci/render_workflows.py`.\n" @@ -559,6 +556,8 @@ def render_nightly(boards: list[dict]) -> str: "name: Nightly Platforms\n" "\n" "on:\n" + " push:\n" + " branches: [main]\n" " schedule:\n" " # 11:00 UTC = 03:00 PST (winter) / 04:00 PDT (summer). GitHub cron\n" " # has no timezone, so one of the two has to drift; 3am standard\n" @@ -567,42 +566,62 @@ def render_nightly(boards: list[dict]) -> str: " workflow_dispatch:\n" " inputs:\n" " force:\n" - " description: 'Run all platform builds even without recent commits'\n" + " description: 'Dispatch all platform builds even without recent commits'\n" " type: boolean\n" " default: false\n" "\n" "jobs:\n" - " guard:\n" - " name: Guard (skip on quiet days)\n" + " plan:\n" + " name: Select boards\n" " runs-on: ubuntu-latest\n" " outputs:\n" - " should_run: ${{ steps.check.outputs.should_run }}\n" + " workflows: ${{ steps.select.outputs.workflows }}\n" " steps:\n" " - uses: actions/checkout@v6\n" " with:\n" " fetch-depth: 0\n" - " - id: check\n" + " - uses: astral-sh/setup-uv@v3\n" + " - id: select\n" " env:\n" - " FORCE: ${{ inputs.force }}\n" + " EVENT: ${{ github.event_name }}\n" + " BEFORE: ${{ github.event.before }}\n" " run: |\n" - " if [ \"$FORCE\" = \"true\" ]; then\n" - " echo \"force=true -- running nightly sweep regardless of commit activity\"\n" - " echo \"should_run=true\" >> \"$GITHUB_OUTPUT\"\n" + " if [ \"$EVENT\" = push ]; then\n" + " args=(--base \"$BEFORE\" --head \"$GITHUB_SHA\")\n" + " elif [ \"$EVENT\" = schedule ] && [ -z \"$(git log --since='24 hours ago' --oneline HEAD)\" ]; then\n" + " echo 'No commits in the last 24h -- nothing to dispatch'\n" + " echo 'workflows=[]' >> \"$GITHUB_OUTPUT\"\n" " exit 0\n" - " fi\n" - " # Scheduled runs check out the default branch's HEAD; on\n" - " # workflow_dispatch from a feature branch this checks that\n" - " # branch instead, which is the right behavior for manual runs.\n" - " if [ -z \"$(git log --since='24 hours ago' --oneline HEAD)\" ]; then\n" - " echo \"No commits in the last 24h -- skipping nightly platform sweep\"\n" - " echo \"should_run=false\" >> \"$GITHUB_OUTPUT\"\n" " else\n" - " echo \"Recent commits found -- running full nightly sweep\"\n" - " echo \"should_run=true\" >> \"$GITHUB_OUTPUT\"\n" + " args=(--all)\n" " fi\n" + " workflows=$(cd ci && uv run --no-project python select_boards.py \"${args[@]}\")\n" + " echo \"selected: $workflows\"\n" + " echo \"workflows=$workflows\" >> \"$GITHUB_OUTPUT\"\n" "\n" ) - return header + jobs_yaml + dispatch = ( + " dispatch:\n" + " name: Dispatch board workflows\n" + " needs: [plan, fbuild_bin]\n" + " runs-on: ubuntu-latest\n" + " permissions:\n" + " actions: write\n" + " steps:\n" + " - env:\n" + " GH_TOKEN: ${{ github.token }}\n" + " GH_REPO: ${{ github.repository }}\n" + " WORKFLOWS: ${{ needs.plan.outputs.workflows }}\n" + " run: |\n" + " for wf in $(echo \"$WORKFLOWS\" | jq -r '.[]'); do\n" + " gh workflow run \"$wf\" --ref \"$GITHUB_REF_NAME\" \\\n" + " -f fbuild-run-id=\"$GITHUB_RUN_ID\" -f checkout_ref=\"$GITHUB_SHA\"\n" + " echo \"dispatched $wf\"\n" + " done\n" + ) + return header + render_fbuild_bin_job( + "plan", " if: needs.plan.outputs.workflows != '[]'\n", "${{ github.sha }}" + ) + dispatch def write_if_changed(path: Path, new_text: str, check: bool, drift: list[Path], updated: list[Path]) -> None: @@ -656,6 +675,7 @@ def main() -> int: old = path.read_text(encoding="utf-8") new_on = render_on_block(board, families, common_paths) new = rewrite(old, new_on) + new = new[: new.index("\njobs:\n") + 1] + render_board_jobs(board) write_if_changed(path, new, args.check, drift, updated) write_if_changed(NIGHTLY_PATH, render_nightly(boards), args.check, drift, updated) diff --git a/ci/select_boards.py b/ci/select_boards.py new file mode 100644 index 00000000..014f0de3 --- /dev/null +++ b/ci/select_boards.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +"""Pick which per-board build workflows a push to main should dispatch. + +A board is selected when a changed file matches one of its trigger paths +(`render_workflows.render_paths_for_board`): its own test dir, its family's +crate paths, its own workflow file, and -- for the `core` boards only -- the +shared paths in ci/ci_common_paths.txt. The nightly sweep passes `--all` so +every board's README badge refreshes at least daily. + +Prints a JSON array of workflow file names (sorted) for the dispatcher job in +nightly-platforms.yml. An unknown diff (first push, force-push, missing base) +selects every board rather than silently skipping coverage. +""" +from __future__ import annotations + +import argparse +import json +import re +import subprocess +import sys +from functools import lru_cache + +from render_workflows import load_common_paths, load_sot, render_paths_for_board + +ZERO_SHA = "0" * 40 + + +@lru_cache(maxsize=None) +def _compile(pattern: str) -> re.Pattern[str]: + # GitHub `paths:` semantics: `**` spans directories, `*` stays in one. + out = [] + i = 0 + while i < len(pattern): + if pattern.startswith("**", i): + out.append(".*") + i += 2 + elif pattern[i] == "*": + out.append("[^/]*") + i += 1 + else: + out.append(re.escape(pattern[i])) + i += 1 + return re.compile("".join(out) + r"\Z") + + +def path_matches(pattern: str, path: str) -> bool: + return _compile(pattern).match(path) is not None + + +def select_workflows(boards, families, common_paths, changed): + """Workflows to run for `changed` files; `None` means the diff is unknown.""" + if changed is None: + return sorted(b["workflow"] for b in boards) + selected = [] + for board in boards: + patterns = render_paths_for_board(board, families, common_paths) + if any(path_matches(p, f) for p in patterns for f in changed): + selected.append(board["workflow"]) + return sorted(selected) + + +def changed_files(base: str, head: str): + if not base or base == ZERO_SHA: + return None + result = subprocess.run( + ["git", "diff", "--name-only", base, head], + capture_output=True, + text=True, + check=False, + ) + if result.returncode != 0: + print(f"git diff {base}..{head} failed; selecting all boards:\n{result.stderr}", file=sys.stderr) + return None + return [line for line in result.stdout.splitlines() if line] + + +def main() -> int: + ap = argparse.ArgumentParser(description=__doc__) + ap.add_argument("--all", action="store_true", help="select every board (scheduled sweep)") + ap.add_argument("--base", default="", help="diff base commit (push event `before`)") + ap.add_argument("--head", default="HEAD", help="diff head commit") + args = ap.parse_args() + + sot = load_sot() + changed = None if args.all else changed_files(args.base, args.head) + workflows = select_workflows(sot["boards"], sot["families"], load_common_paths(), changed) + print(json.dumps(workflows)) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/ci/test_fractional_workflows.py b/ci/test_fractional_workflows.py index 2be12b0c..5c55279c 100644 --- a/ci/test_fractional_workflows.py +++ b/ci/test_fractional_workflows.py @@ -127,12 +127,27 @@ def test_fast_matrix_matches_selected_boards(self): for cell in matrix: self.assertIn(cell, full_matrix) - def test_nightly_deduplicates_identical_builds_but_keeps_aliases(self): - boards = render_workflows.load_sot()["boards"] + def test_nightly_dispatches_board_workflows_as_their_own_runs(self): + # Badges track runs of each build-.yml file, so the nightly / + # push-to-main path must dispatch them (not build in a matrix). nightly = self.load("nightly-platforms.yml") - matrix = nightly["jobs"]["build"]["strategy"]["matrix"]["include"] - self.assertEqual(len(render_workflows.execution_boards(boards)), len(matrix)) - self.assertEqual({b["workflow"] for b in boards}, {alias for b in matrix for alias in b["workflow_aliases"]}) + self.assertEqual({"plan", "fbuild_bin", "dispatch"}, set(nightly["jobs"])) + self.assertEqual(["main"], nightly[True]["push"]["branches"]) + self.assertIn("schedule", nightly[True]) + self.assertIn("select_boards.py", nightly["jobs"]["plan"]["steps"][2]["run"]) + self.assertEqual("write", nightly["jobs"]["dispatch"]["permissions"]["actions"]) + run = nightly["jobs"]["dispatch"]["steps"][0]["run"] + self.assertIn("gh workflow run", run) + self.assertIn('fbuild-run-id="$GITHUB_RUN_ID"', run) + + def test_board_workflows_reuse_a_dispatched_fbuild_binary(self): + for board in render_workflows.load_sot()["boards"]: + with self.subTest(workflow=board["workflow"]): + wf = self.load(board["workflow"]) + self.assertIn("fbuild-run-id", wf[True]["workflow_dispatch"]["inputs"]) + with_ = wf["jobs"]["build"]["with"] + self.assertEqual("${{ inputs.fbuild-run-id }}", with_["fbuild-run-id"]) + self.assertEqual(board["test_dir"], with_["test-dir"]) def test_ordinary_minimal_and_opt_in_test_are_distinct(self): minimal = self.load("ci-minimal.yml") diff --git a/ci/test_select_boards.py b/ci/test_select_boards.py new file mode 100644 index 00000000..13619623 --- /dev/null +++ b/ci/test_select_boards.py @@ -0,0 +1,70 @@ +"""Tests for path-based board selection (ci/select_boards.py). + +A push to main dispatches only the per-board workflows whose trigger paths +the push touched; the nightly sweep dispatches every board so README badges +refresh on a schedule. +""" +from __future__ import annotations + +import sys +import unittest +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parent)) + +from select_boards import path_matches, select_workflows # noqa: E402 + +FAMILIES = { + "avr": {"crate_paths": ["crates/fbuild-build-mcu/src/avr/**"]}, + "esp32": {"crate_paths": ["crates/fbuild-build-esp/src/esp32/**"]}, +} +COMMON = ["crates/fbuild-core/**", "Cargo.lock", "crates/fbuild-build-mcu/*argo.toml"] +BOARDS = [ + {"workflow": "build-uno.yml", "test_dir": "tests/platform/uno", "family": "avr", "core": True}, + {"workflow": "build-attiny85.yml", "test_dir": "tests/platform/attiny85", "family": "avr"}, + {"workflow": "build-esp32c3.yml", "test_dir": "tests/platform/esp32c3", "family": "esp32"}, +] + + +def select(changed): + return select_workflows(BOARDS, FAMILIES, COMMON, changed) + + +class PathMatchTests(unittest.TestCase): + def test_double_star_crosses_directories(self): + self.assertTrue(path_matches("crates/fbuild-core/**", "crates/fbuild-core/src/a/b.rs")) + + def test_single_star_stays_in_one_segment(self): + self.assertTrue(path_matches("crates/fbuild-build-mcu/*argo.toml", "crates/fbuild-build-mcu/Cargo.toml")) + self.assertFalse(path_matches("crates/x/*.rs", "crates/x/sub/a.rs")) + + def test_literal(self): + self.assertTrue(path_matches("Cargo.lock", "Cargo.lock")) + self.assertFalse(path_matches("Cargo.lock", "sub/Cargo.lock")) + + +class SelectTests(unittest.TestCase): + def test_docs_only_selects_nothing(self): + self.assertEqual([], select(["README.md", "docs/x.md"])) + + def test_board_test_dir_selects_only_that_board(self): + self.assertEqual(["build-attiny85.yml"], select(["tests/platform/attiny85/platformio.ini"])) + + def test_family_code_selects_the_family(self): + self.assertEqual( + ["build-attiny85.yml", "build-uno.yml"], + select(["crates/fbuild-build-mcu/src/avr/mod.rs"]), + ) + + def test_shared_code_selects_core_boards_only(self): + self.assertEqual(["build-uno.yml"], select(["crates/fbuild-core/src/lib.rs"])) + + def test_own_workflow_file_selects_board(self): + self.assertEqual(["build-esp32c3.yml"], select([".github/workflows/build-esp32c3.yml"])) + + def test_unknown_diff_selects_everything(self): + self.assertEqual(sorted(b["workflow"] for b in BOARDS), select(None)) + + +if __name__ == "__main__": + unittest.main() From d4f58d0054512fe7a52408adbb10c6c5d3611552 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Mon, 28 Sep 2026 21:38:56 -0700 Subject: [PATCH 04/12] perf(ci): make the ~1GB per-board toolchain cache opt-in per family Measured on 50 boards: builds without the cache took 1738s total vs 2248s with the cache (restore + save + builds); a cold download is faster than the cache round-trip. Only silabs (MGM240: 569s cold, a ~480MB silabs-core download at a few MB/s) opts in, recorded in board_families.json. This also stops main from saving ~79 x ~1GB entries per sweep, which would evict the setup-soldr Rust build cache the shared fbuild compile depends on. The cross-board restore fallback is dropped: another board's cache is mostly the wrong toolchain. --- .github/workflows/build-apollo3_red.yml | 1 + .../build-apollo3_thing_explorable.yml | 1 + .github/workflows/build-atmega8.yml | 1 + .github/workflows/build-atmega8a.yml | 1 + .github/workflows/build-attiny1604.yml | 1 + .github/workflows/build-attiny1616.yml | 1 + .github/workflows/build-attiny4313.yml | 1 + .github/workflows/build-attiny85.yml | 1 + .github/workflows/build-attiny88.yml | 1 + .github/workflows/build-blackpill.yml | 1 + .github/workflows/build-bluepill.yml | 1 + .github/workflows/build-ch32l103.yml | 1 + .github/workflows/build-ch32v003.yml | 1 + .github/workflows/build-ch32v006.yml | 1 + .github/workflows/build-ch32v103.yml | 1 + .github/workflows/build-ch32v203.yml | 1 + .github/workflows/build-ch32v208.yml | 1 + .github/workflows/build-ch32v303.yml | 1 + .github/workflows/build-ch32v307.yml | 1 + .github/workflows/build-ch32x035.yml | 1 + .github/workflows/build-clearcore.yml | 1 + .github/workflows/build-due.yml | 1 + .github/workflows/build-esp32c2.yml | 1 + .github/workflows/build-esp32c3.yml | 1 + .github/workflows/build-esp32c5.yml | 1 + .github/workflows/build-esp32c6.yml | 1 + .github/workflows/build-esp32dev.yml | 1 + .github/workflows/build-esp32h2.yml | 1 + .github/workflows/build-esp32p4.yml | 1 + .github/workflows/build-esp32s2.yml | 1 + .github/workflows/build-esp32s3.yml | 1 + .github/workflows/build-esp8266.yml | 1 + .github/workflows/build-giga-r1.yml | 1 + .github/workflows/build-leonardo.yml | 1 + .github/workflows/build-lpc804.yml | 1 + .github/workflows/build-lpc845.yml | 1 + .github/workflows/build-lpc845brk.yml | 1 + .github/workflows/build-lpcxpresso804.yml | 1 + .github/workflows/build-lpcxpresso845max.yml | 1 + .github/workflows/build-matrix_portal_m4.yml | 1 + .github/workflows/build-mgm240.yml | 1 + .github/workflows/build-nano-every.yml | 1 + .github/workflows/build-nano_every.yml | 1 + .../workflows/build-nice_nano_nrf52840.yml | 1 + .github/workflows/build-nrf52840-sense.yml | 1 + .github/workflows/build-nrf52840_dk.yml | 1 + .github/workflows/build-nrfmicro_nrf52840.yml | 1 + .github/workflows/build-nucleo-f429zi.yml | 1 + .github/workflows/build-nucleo-f439zi.yml | 1 + .github/workflows/build-nucleo_f429zi.yml | 1 + .github/workflows/build-nucleo_f439zi.yml | 1 + .github/workflows/build-qtpy_m0.yml | 1 + .github/workflows/build-rp2040.yml | 1 + .github/workflows/build-rp2350.yml | 1 + .github/workflows/build-rpipico.yml | 1 + .github/workflows/build-rpipico2.yml | 1 + .github/workflows/build-sam3x8e_due.yml | 1 + .github/workflows/build-samd21.yml | 1 + .github/workflows/build-samd21_zero.yml | 1 + .github/workflows/build-samd51j.yml | 1 + .github/workflows/build-samd51p.yml | 1 + .github/workflows/build-stm32f103c8.yml | 1 + .github/workflows/build-stm32f103cb.yml | 1 + .github/workflows/build-stm32f103tb.yml | 1 + .github/workflows/build-stm32f411ce.yml | 1 + .github/workflows/build-stm32h747xi.yml | 1 + .../workflows/build-supermini_nrf52840.yml | 1 + .github/workflows/build-teensy30.yml | 1 + .github/workflows/build-teensy31.yml | 1 + .github/workflows/build-teensy32.yml | 1 + .github/workflows/build-teensy35.yml | 1 + .github/workflows/build-teensy36.yml | 1 + .github/workflows/build-teensy40.yml | 1 + .github/workflows/build-teensy41.yml | 1 + .github/workflows/build-teensylc.yml | 1 + .github/workflows/build-thingplusmatter.yml | 1 + .github/workflows/build-tinystm.yml | 1 + .github/workflows/build-uno-r4-wifi.yml | 1 + .github/workflows/build-uno.yml | 1 + .github/workflows/build-uno_r4_wifi.yml | 1 + .github/workflows/ci-full.yml | 77 +++++++++++++++++++ .github/workflows/ci-test.yml | 2 + .github/workflows/template_build.yml | 15 +++- ci/board_families.json | 4 +- ci/render_workflows.py | 26 +++++-- ci/test_fractional_workflows.py | 10 +++ 86 files changed, 204 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-apollo3_red.yml b/.github/workflows/build-apollo3_red.yml index 0b9ec114..db7d5f27 100644 --- a/.github/workflows/build-apollo3_red.yml +++ b/.github/workflows/build-apollo3_red.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-apollo3_thing_explorable.yml b/.github/workflows/build-apollo3_thing_explorable.yml index e864b02e..208ba5c2 100644 --- a/.github/workflows/build-apollo3_thing_explorable.yml +++ b/.github/workflows/build-apollo3_thing_explorable.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-atmega8.yml b/.github/workflows/build-atmega8.yml index 6a10c17b..3d74d32d 100644 --- a/.github/workflows/build-atmega8.yml +++ b/.github/workflows/build-atmega8.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-atmega8a.yml b/.github/workflows/build-atmega8a.yml index 6bdcd024..48fcf6db 100644 --- a/.github/workflows/build-atmega8a.yml +++ b/.github/workflows/build-atmega8a.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-attiny1604.yml b/.github/workflows/build-attiny1604.yml index dad063d7..72082fbc 100644 --- a/.github/workflows/build-attiny1604.yml +++ b/.github/workflows/build-attiny1604.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-attiny1616.yml b/.github/workflows/build-attiny1616.yml index 40f6ef91..5bd3b4f0 100644 --- a/.github/workflows/build-attiny1616.yml +++ b/.github/workflows/build-attiny1616.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-attiny4313.yml b/.github/workflows/build-attiny4313.yml index 1c5c95fe..63f491e2 100644 --- a/.github/workflows/build-attiny4313.yml +++ b/.github/workflows/build-attiny4313.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-attiny85.yml b/.github/workflows/build-attiny85.yml index 7d973a63..09c44119 100644 --- a/.github/workflows/build-attiny85.yml +++ b/.github/workflows/build-attiny85.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-attiny88.yml b/.github/workflows/build-attiny88.yml index 1e7cb77d..f393f62c 100644 --- a/.github/workflows/build-attiny88.yml +++ b/.github/workflows/build-attiny88.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-blackpill.yml b/.github/workflows/build-blackpill.yml index 4cc0736f..f678f914 100644 --- a/.github/workflows/build-blackpill.yml +++ b/.github/workflows/build-blackpill.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-bluepill.yml b/.github/workflows/build-bluepill.yml index cfe603de..8b60d845 100644 --- a/.github/workflows/build-bluepill.yml +++ b/.github/workflows/build-bluepill.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32l103.yml b/.github/workflows/build-ch32l103.yml index 2b0eb578..d7c818c6 100644 --- a/.github/workflows/build-ch32l103.yml +++ b/.github/workflows/build-ch32l103.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32v003.yml b/.github/workflows/build-ch32v003.yml index 9aa5660b..5777af83 100644 --- a/.github/workflows/build-ch32v003.yml +++ b/.github/workflows/build-ch32v003.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32v006.yml b/.github/workflows/build-ch32v006.yml index 8d371199..c51c2989 100644 --- a/.github/workflows/build-ch32v006.yml +++ b/.github/workflows/build-ch32v006.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32v103.yml b/.github/workflows/build-ch32v103.yml index 8462af1d..7fd88b1e 100644 --- a/.github/workflows/build-ch32v103.yml +++ b/.github/workflows/build-ch32v103.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32v203.yml b/.github/workflows/build-ch32v203.yml index eaae1cda..94930778 100644 --- a/.github/workflows/build-ch32v203.yml +++ b/.github/workflows/build-ch32v203.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32v208.yml b/.github/workflows/build-ch32v208.yml index 0f4ecbfd..f5ec5608 100644 --- a/.github/workflows/build-ch32v208.yml +++ b/.github/workflows/build-ch32v208.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32v303.yml b/.github/workflows/build-ch32v303.yml index 855ad92c..dd31b648 100644 --- a/.github/workflows/build-ch32v303.yml +++ b/.github/workflows/build-ch32v303.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32v307.yml b/.github/workflows/build-ch32v307.yml index 1f0745fa..64059e1e 100644 --- a/.github/workflows/build-ch32v307.yml +++ b/.github/workflows/build-ch32v307.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32x035.yml b/.github/workflows/build-ch32x035.yml index 88d503d9..dccbf91d 100644 --- a/.github/workflows/build-ch32x035.yml +++ b/.github/workflows/build-ch32x035.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-clearcore.yml b/.github/workflows/build-clearcore.yml index 71861b47..1d8e3035 100644 --- a/.github/workflows/build-clearcore.yml +++ b/.github/workflows/build-clearcore.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-due.yml b/.github/workflows/build-due.yml index 4e0e53c1..c7071a8d 100644 --- a/.github/workflows/build-due.yml +++ b/.github/workflows/build-due.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32c2.yml b/.github/workflows/build-esp32c2.yml index 4194d00a..d233ab15 100644 --- a/.github/workflows/build-esp32c2.yml +++ b/.github/workflows/build-esp32c2.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32c3.yml b/.github/workflows/build-esp32c3.yml index ff870118..f01672b8 100644 --- a/.github/workflows/build-esp32c3.yml +++ b/.github/workflows/build-esp32c3.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32c5.yml b/.github/workflows/build-esp32c5.yml index 38cc5a70..e0cb23f2 100644 --- a/.github/workflows/build-esp32c5.yml +++ b/.github/workflows/build-esp32c5.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32c6.yml b/.github/workflows/build-esp32c6.yml index d7dfe0f4..1a05a622 100644 --- a/.github/workflows/build-esp32c6.yml +++ b/.github/workflows/build-esp32c6.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32dev.yml b/.github/workflows/build-esp32dev.yml index 9254fa13..53774ad9 100644 --- a/.github/workflows/build-esp32dev.yml +++ b/.github/workflows/build-esp32dev.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32h2.yml b/.github/workflows/build-esp32h2.yml index 7219ae4d..4c45b754 100644 --- a/.github/workflows/build-esp32h2.yml +++ b/.github/workflows/build-esp32h2.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32p4.yml b/.github/workflows/build-esp32p4.yml index 2611dfe0..ad4b5a6c 100644 --- a/.github/workflows/build-esp32p4.yml +++ b/.github/workflows/build-esp32p4.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32s2.yml b/.github/workflows/build-esp32s2.yml index 51e82e12..eac215fa 100644 --- a/.github/workflows/build-esp32s2.yml +++ b/.github/workflows/build-esp32s2.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32s3.yml b/.github/workflows/build-esp32s3.yml index e47621d4..be457f88 100644 --- a/.github/workflows/build-esp32s3.yml +++ b/.github/workflows/build-esp32s3.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-esp8266.yml b/.github/workflows/build-esp8266.yml index b6351e96..295bc952 100644 --- a/.github/workflows/build-esp8266.yml +++ b/.github/workflows/build-esp8266.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-giga-r1.yml b/.github/workflows/build-giga-r1.yml index 57c76630..fc771e90 100644 --- a/.github/workflows/build-giga-r1.yml +++ b/.github/workflows/build-giga-r1.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-leonardo.yml b/.github/workflows/build-leonardo.yml index a2343ad5..1a9dd0c0 100644 --- a/.github/workflows/build-leonardo.yml +++ b/.github/workflows/build-leonardo.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-lpc804.yml b/.github/workflows/build-lpc804.yml index e5ddba20..aaa4142c 100644 --- a/.github/workflows/build-lpc804.yml +++ b/.github/workflows/build-lpc804.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-lpc845.yml b/.github/workflows/build-lpc845.yml index 34eec7af..95137f56 100644 --- a/.github/workflows/build-lpc845.yml +++ b/.github/workflows/build-lpc845.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-lpc845brk.yml b/.github/workflows/build-lpc845brk.yml index 33ad6d12..403d5020 100644 --- a/.github/workflows/build-lpc845brk.yml +++ b/.github/workflows/build-lpc845brk.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-lpcxpresso804.yml b/.github/workflows/build-lpcxpresso804.yml index 11684075..39b05f77 100644 --- a/.github/workflows/build-lpcxpresso804.yml +++ b/.github/workflows/build-lpcxpresso804.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-lpcxpresso845max.yml b/.github/workflows/build-lpcxpresso845max.yml index d4a81e89..4cb0c25c 100644 --- a/.github/workflows/build-lpcxpresso845max.yml +++ b/.github/workflows/build-lpcxpresso845max.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-matrix_portal_m4.yml b/.github/workflows/build-matrix_portal_m4.yml index 83d67f3b..946a82a2 100644 --- a/.github/workflows/build-matrix_portal_m4.yml +++ b/.github/workflows/build-matrix_portal_m4.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-mgm240.yml b/.github/workflows/build-mgm240.yml index 6089a392..ab4aa11d 100644 --- a/.github/workflows/build-mgm240.yml +++ b/.github/workflows/build-mgm240.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: true diff --git a/.github/workflows/build-nano-every.yml b/.github/workflows/build-nano-every.yml index 23420257..ad8fc822 100644 --- a/.github/workflows/build-nano-every.yml +++ b/.github/workflows/build-nano-every.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-nano_every.yml b/.github/workflows/build-nano_every.yml index 1d148e5b..58d0045c 100644 --- a/.github/workflows/build-nano_every.yml +++ b/.github/workflows/build-nano_every.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-nice_nano_nrf52840.yml b/.github/workflows/build-nice_nano_nrf52840.yml index a06e03fb..f49b7c10 100644 --- a/.github/workflows/build-nice_nano_nrf52840.yml +++ b/.github/workflows/build-nice_nano_nrf52840.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-nrf52840-sense.yml b/.github/workflows/build-nrf52840-sense.yml index 6628da71..9bbae930 100644 --- a/.github/workflows/build-nrf52840-sense.yml +++ b/.github/workflows/build-nrf52840-sense.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-nrf52840_dk.yml b/.github/workflows/build-nrf52840_dk.yml index 96a651ce..5806a7a5 100644 --- a/.github/workflows/build-nrf52840_dk.yml +++ b/.github/workflows/build-nrf52840_dk.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-nrfmicro_nrf52840.yml b/.github/workflows/build-nrfmicro_nrf52840.yml index fa30bcbf..323e4d11 100644 --- a/.github/workflows/build-nrfmicro_nrf52840.yml +++ b/.github/workflows/build-nrfmicro_nrf52840.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-nucleo-f429zi.yml b/.github/workflows/build-nucleo-f429zi.yml index cb2aae2b..7c76d719 100644 --- a/.github/workflows/build-nucleo-f429zi.yml +++ b/.github/workflows/build-nucleo-f429zi.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-nucleo-f439zi.yml b/.github/workflows/build-nucleo-f439zi.yml index 6f5a5268..f8b3bbc3 100644 --- a/.github/workflows/build-nucleo-f439zi.yml +++ b/.github/workflows/build-nucleo-f439zi.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-nucleo_f429zi.yml b/.github/workflows/build-nucleo_f429zi.yml index 24914975..5aa3a823 100644 --- a/.github/workflows/build-nucleo_f429zi.yml +++ b/.github/workflows/build-nucleo_f429zi.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-nucleo_f439zi.yml b/.github/workflows/build-nucleo_f439zi.yml index ccac43c6..d20744d4 100644 --- a/.github/workflows/build-nucleo_f439zi.yml +++ b/.github/workflows/build-nucleo_f439zi.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-qtpy_m0.yml b/.github/workflows/build-qtpy_m0.yml index d6b5f624..c72b190f 100644 --- a/.github/workflows/build-qtpy_m0.yml +++ b/.github/workflows/build-qtpy_m0.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-rp2040.yml b/.github/workflows/build-rp2040.yml index d979599b..0d9586e8 100644 --- a/.github/workflows/build-rp2040.yml +++ b/.github/workflows/build-rp2040.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-rp2350.yml b/.github/workflows/build-rp2350.yml index 52296fee..b82a33a4 100644 --- a/.github/workflows/build-rp2350.yml +++ b/.github/workflows/build-rp2350.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-rpipico.yml b/.github/workflows/build-rpipico.yml index a324a7f2..81a364fc 100644 --- a/.github/workflows/build-rpipico.yml +++ b/.github/workflows/build-rpipico.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-rpipico2.yml b/.github/workflows/build-rpipico2.yml index 96c94683..041aa8c3 100644 --- a/.github/workflows/build-rpipico2.yml +++ b/.github/workflows/build-rpipico2.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-sam3x8e_due.yml b/.github/workflows/build-sam3x8e_due.yml index 767aecc3..7bcb7c6e 100644 --- a/.github/workflows/build-sam3x8e_due.yml +++ b/.github/workflows/build-sam3x8e_due.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-samd21.yml b/.github/workflows/build-samd21.yml index 5b0be7fb..60957d51 100644 --- a/.github/workflows/build-samd21.yml +++ b/.github/workflows/build-samd21.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-samd21_zero.yml b/.github/workflows/build-samd21_zero.yml index f0ee3c06..090428b2 100644 --- a/.github/workflows/build-samd21_zero.yml +++ b/.github/workflows/build-samd21_zero.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-samd51j.yml b/.github/workflows/build-samd51j.yml index 92f9f30d..9c710074 100644 --- a/.github/workflows/build-samd51j.yml +++ b/.github/workflows/build-samd51j.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-samd51p.yml b/.github/workflows/build-samd51p.yml index fc263a72..88dd7054 100644 --- a/.github/workflows/build-samd51p.yml +++ b/.github/workflows/build-samd51p.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-stm32f103c8.yml b/.github/workflows/build-stm32f103c8.yml index e8ac3459..0bbe3c02 100644 --- a/.github/workflows/build-stm32f103c8.yml +++ b/.github/workflows/build-stm32f103c8.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-stm32f103cb.yml b/.github/workflows/build-stm32f103cb.yml index 108d688f..8008ae3b 100644 --- a/.github/workflows/build-stm32f103cb.yml +++ b/.github/workflows/build-stm32f103cb.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-stm32f103tb.yml b/.github/workflows/build-stm32f103tb.yml index c13b62ea..dd0b9a5d 100644 --- a/.github/workflows/build-stm32f103tb.yml +++ b/.github/workflows/build-stm32f103tb.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-stm32f411ce.yml b/.github/workflows/build-stm32f411ce.yml index 221fad28..042f1132 100644 --- a/.github/workflows/build-stm32f411ce.yml +++ b/.github/workflows/build-stm32f411ce.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-stm32h747xi.yml b/.github/workflows/build-stm32h747xi.yml index 87796365..0fedfe49 100644 --- a/.github/workflows/build-stm32h747xi.yml +++ b/.github/workflows/build-stm32h747xi.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-supermini_nrf52840.yml b/.github/workflows/build-supermini_nrf52840.yml index 89f0fd26..6f7ca9ad 100644 --- a/.github/workflows/build-supermini_nrf52840.yml +++ b/.github/workflows/build-supermini_nrf52840.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-teensy30.yml b/.github/workflows/build-teensy30.yml index 934850b1..b6dc1280 100644 --- a/.github/workflows/build-teensy30.yml +++ b/.github/workflows/build-teensy30.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-teensy31.yml b/.github/workflows/build-teensy31.yml index e82859d9..d2291785 100644 --- a/.github/workflows/build-teensy31.yml +++ b/.github/workflows/build-teensy31.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-teensy32.yml b/.github/workflows/build-teensy32.yml index 2d586476..54b3815f 100644 --- a/.github/workflows/build-teensy32.yml +++ b/.github/workflows/build-teensy32.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-teensy35.yml b/.github/workflows/build-teensy35.yml index 7c0009de..4855a86c 100644 --- a/.github/workflows/build-teensy35.yml +++ b/.github/workflows/build-teensy35.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-teensy36.yml b/.github/workflows/build-teensy36.yml index eaa57538..4607fd2d 100644 --- a/.github/workflows/build-teensy36.yml +++ b/.github/workflows/build-teensy36.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-teensy40.yml b/.github/workflows/build-teensy40.yml index 9b04e5bf..f1861271 100644 --- a/.github/workflows/build-teensy40.yml +++ b/.github/workflows/build-teensy40.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-teensy41.yml b/.github/workflows/build-teensy41.yml index 37749931..231cd4c1 100644 --- a/.github/workflows/build-teensy41.yml +++ b/.github/workflows/build-teensy41.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-teensylc.yml b/.github/workflows/build-teensylc.yml index 856dca72..8e8033ea 100644 --- a/.github/workflows/build-teensylc.yml +++ b/.github/workflows/build-teensylc.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-thingplusmatter.yml b/.github/workflows/build-thingplusmatter.yml index 582be71b..9fc3dd81 100644 --- a/.github/workflows/build-thingplusmatter.yml +++ b/.github/workflows/build-thingplusmatter.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-tinystm.yml b/.github/workflows/build-tinystm.yml index dd1e489a..eeb6c7ff 100644 --- a/.github/workflows/build-tinystm.yml +++ b/.github/workflows/build-tinystm.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-uno-r4-wifi.yml b/.github/workflows/build-uno-r4-wifi.yml index 004a8e13..e57d52fa 100644 --- a/.github/workflows/build-uno-r4-wifi.yml +++ b/.github/workflows/build-uno-r4-wifi.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-uno.yml b/.github/workflows/build-uno.yml index d802b1d3..9d1656ce 100644 --- a/.github/workflows/build-uno.yml +++ b/.github/workflows/build-uno.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/build-uno_r4_wifi.yml b/.github/workflows/build-uno_r4_wifi.yml index 435ad3c9..bfab9b0c 100644 --- a/.github/workflows/build-uno_r4_wifi.yml +++ b/.github/workflows/build-uno_r4_wifi.yml @@ -30,3 +30,4 @@ jobs: checkout_ref: ${{ inputs.checkout_ref }} fbuild-artifact: ${{ inputs.fbuild-run-id && 'fbuild-bin-linux-debug' || '' }} fbuild-run-id: ${{ inputs.fbuild-run-id }} + toolchain-cache: false diff --git a/.github/workflows/ci-full.yml b/.github/workflows/ci-full.yml index 1028b5cb..41c72172 100644 --- a/.github/workflows/ci-full.yml +++ b/.github/workflows/ci-full.yml @@ -174,456 +174,532 @@ jobs: env_name: "apollo3_red" firmware_ext: "bin" workflow_aliases: ["build-apollo3_red.yml"] + toolchain_cache: false - workflow: "build-apollo3_thing_explorable.yml" workflow_name: "Apollo3 Thing Explorable" test_dir: "tests/platform/apollo3_thing_explorable" env_name: "apollo3_thing_explorable" firmware_ext: "bin" workflow_aliases: ["build-apollo3_thing_explorable.yml"] + toolchain_cache: false - workflow: "build-atmega8.yml" workflow_name: "ATmega8" test_dir: "tests/platform/atmega8" env_name: "atmega8" firmware_ext: "hex" workflow_aliases: ["build-atmega8.yml"] + toolchain_cache: false - workflow: "build-atmega8a.yml" workflow_name: "ATmega8A" test_dir: "tests/platform/atmega8a" env_name: "atmega8a" firmware_ext: "hex" workflow_aliases: ["build-atmega8a.yml"] + toolchain_cache: false - workflow: "build-attiny1604.yml" workflow_name: "ATtiny1604" test_dir: "tests/platform/attiny1604" env_name: "attiny1604" firmware_ext: "hex" workflow_aliases: ["build-attiny1604.yml"] + toolchain_cache: false - workflow: "build-attiny1616.yml" workflow_name: "ATtiny1616" test_dir: "tests/platform/attiny1616" env_name: "attiny1616" firmware_ext: "hex" workflow_aliases: ["build-attiny1616.yml"] + toolchain_cache: false - workflow: "build-attiny4313.yml" workflow_name: "ATtiny4313" test_dir: "tests/platform/attiny4313" env_name: "attiny4313" firmware_ext: "hex" workflow_aliases: ["build-attiny4313.yml"] + toolchain_cache: false - workflow: "build-attiny85.yml" workflow_name: "ATtiny85" test_dir: "tests/platform/attiny85" env_name: "attiny85" firmware_ext: "hex" workflow_aliases: ["build-attiny85.yml"] + toolchain_cache: false - workflow: "build-attiny88.yml" workflow_name: "ATtiny88" test_dir: "tests/platform/attiny88" env_name: "attiny88" firmware_ext: "hex" workflow_aliases: ["build-attiny88.yml"] + toolchain_cache: false - workflow: "build-blackpill.yml" workflow_name: "STM32 BlackPill F411CE" test_dir: "tests/platform/blackpill_f411ce" env_name: "blackpill" firmware_ext: "hex" workflow_aliases: ["build-blackpill.yml"] + toolchain_cache: false - workflow: "build-bluepill.yml" workflow_name: "STM32 BluePill F103C8" test_dir: "tests/platform/bluepill_f103c8" env_name: "bluepill" firmware_ext: "hex" workflow_aliases: ["build-bluepill.yml"] + toolchain_cache: false - workflow: "build-ch32l103.yml" workflow_name: "CH32L103" test_dir: "tests/platform/ch32l103" env_name: "ch32l103" firmware_ext: "bin" workflow_aliases: ["build-ch32l103.yml"] + toolchain_cache: false - workflow: "build-ch32v003.yml" workflow_name: "CH32V003" test_dir: "tests/platform/ch32v003" env_name: "ch32v003" firmware_ext: "bin" workflow_aliases: ["build-ch32v003.yml"] + toolchain_cache: false - workflow: "build-ch32v006.yml" workflow_name: "CH32V006" test_dir: "tests/platform/ch32v006" env_name: "ch32v006" firmware_ext: "bin" workflow_aliases: ["build-ch32v006.yml"] + toolchain_cache: false - workflow: "build-ch32v103.yml" workflow_name: "CH32V103" test_dir: "tests/platform/ch32v103" env_name: "ch32v103" firmware_ext: "bin" workflow_aliases: ["build-ch32v103.yml"] + toolchain_cache: false - workflow: "build-ch32v203.yml" workflow_name: "CH32V203" test_dir: "tests/platform/ch32v203" env_name: "ch32v203" firmware_ext: "bin" workflow_aliases: ["build-ch32v203.yml"] + toolchain_cache: false - workflow: "build-ch32v208.yml" workflow_name: "CH32V208" test_dir: "tests/platform/ch32v208" env_name: "ch32v208" firmware_ext: "bin" workflow_aliases: ["build-ch32v208.yml"] + toolchain_cache: false - workflow: "build-ch32v303.yml" workflow_name: "CH32V303" test_dir: "tests/platform/ch32v303" env_name: "ch32v303" firmware_ext: "bin" workflow_aliases: ["build-ch32v303.yml"] + toolchain_cache: false - workflow: "build-ch32v307.yml" workflow_name: "CH32V307" test_dir: "tests/platform/ch32v307" env_name: "ch32v307" firmware_ext: "bin" workflow_aliases: ["build-ch32v307.yml"] + toolchain_cache: false - workflow: "build-ch32x035.yml" workflow_name: "CH32X035" test_dir: "tests/platform/ch32x035" env_name: "ch32x035" firmware_ext: "bin" workflow_aliases: ["build-ch32x035.yml"] + toolchain_cache: false - workflow: "build-clearcore.yml" workflow_name: "Teknic ClearCore (SAME53)" test_dir: "tests/platform/clearcore" env_name: "clearcore" firmware_ext: "bin" workflow_aliases: ["build-clearcore.yml"] + toolchain_cache: false - workflow: "build-due.yml" workflow_name: "Arduino Due" test_dir: "tests/platform/due" env_name: "due" firmware_ext: "bin" workflow_aliases: ["build-due.yml"] + toolchain_cache: false - workflow: "build-esp32c2.yml" workflow_name: "ESP32-C2" test_dir: "tests/platform/esp32c2" env_name: "esp32c2" firmware_ext: "bin" workflow_aliases: ["build-esp32c2.yml"] + toolchain_cache: false - workflow: "build-esp32c3.yml" workflow_name: "ESP32-C3" test_dir: "tests/platform/esp32c3" env_name: "esp32c3" firmware_ext: "bin" workflow_aliases: ["build-esp32c3.yml"] + toolchain_cache: false - workflow: "build-esp32c5.yml" workflow_name: "ESP32-C5" test_dir: "tests/platform/esp32c5" env_name: "esp32c5" firmware_ext: "bin" workflow_aliases: ["build-esp32c5.yml"] + toolchain_cache: false - workflow: "build-esp32c6.yml" workflow_name: "ESP32-C6" test_dir: "tests/platform/esp32c6" env_name: "esp32c6" firmware_ext: "bin" workflow_aliases: ["build-esp32c6.yml"] + toolchain_cache: false - workflow: "build-esp32dev.yml" workflow_name: "ESP32 Dev" test_dir: "tests/platform/esp32dev" env_name: "esp32dev" firmware_ext: "bin" workflow_aliases: ["build-esp32dev.yml"] + toolchain_cache: false - workflow: "build-esp32h2.yml" workflow_name: "ESP32-H2" test_dir: "tests/platform/esp32h2" env_name: "esp32h2" firmware_ext: "bin" workflow_aliases: ["build-esp32h2.yml"] + toolchain_cache: false - workflow: "build-esp32p4.yml" workflow_name: "ESP32-P4" test_dir: "tests/platform/esp32p4" env_name: "esp32p4" firmware_ext: "bin" workflow_aliases: ["build-esp32p4.yml"] + toolchain_cache: false - workflow: "build-esp32s2.yml" workflow_name: "ESP32-S2" test_dir: "tests/platform/esp32s2" env_name: "esp32s2" firmware_ext: "bin" workflow_aliases: ["build-esp32s2.yml"] + toolchain_cache: false - workflow: "build-esp32s3.yml" workflow_name: "ESP32-S3" test_dir: "tests/platform/esp32s3" env_name: "esp32s3" firmware_ext: "bin" workflow_aliases: ["build-esp32s3.yml"] + toolchain_cache: false - workflow: "build-esp8266.yml" workflow_name: "ESP8266" test_dir: "tests/platform/esp8266" env_name: "esp8266" firmware_ext: "bin" workflow_aliases: ["build-esp8266.yml"] + toolchain_cache: false - workflow: "build-giga-r1.yml" workflow_name: "Arduino GIGA R1 M7" test_dir: "tests/platform/giga_r1_m7" env_name: "giga_r1" firmware_ext: "bin" workflow_aliases: ["build-giga-r1.yml"] + toolchain_cache: false - workflow: "build-leonardo.yml" workflow_name: "Arduino Leonardo" test_dir: "tests/platform/leonardo" env_name: "leonardo" firmware_ext: "hex" workflow_aliases: ["build-leonardo.yml"] + toolchain_cache: false - workflow: "build-lpc804.yml" workflow_name: "NXP LPCXpresso804" test_dir: "tests/platform/lpc804" env_name: "lpc804" firmware_ext: "bin" workflow_aliases: ["build-lpc804.yml"] + toolchain_cache: false - workflow: "build-lpc845.yml" workflow_name: "NXP LPC845" test_dir: "tests/platform/lpc845" env_name: "lpc845" firmware_ext: "bin" workflow_aliases: ["build-lpc845.yml"] + toolchain_cache: false - workflow: "build-lpc845brk.yml" workflow_name: "NXP LPC845-BRK" test_dir: "tests/platform/lpc845brk" env_name: "lpc845brk" firmware_ext: "bin" workflow_aliases: ["build-lpc845brk.yml"] + toolchain_cache: false - workflow: "build-lpcxpresso804.yml" workflow_name: "NXP LPCXpresso804" test_dir: "tests/platform/lpcxpresso804" env_name: "lpcxpresso804" firmware_ext: "bin" workflow_aliases: ["build-lpcxpresso804.yml"] + toolchain_cache: false - workflow: "build-lpcxpresso845max.yml" workflow_name: "NXP LPCXpresso845-MAX" test_dir: "tests/platform/lpcxpresso845max" env_name: "lpcxpresso845max" firmware_ext: "bin" workflow_aliases: ["build-lpcxpresso845max.yml"] + toolchain_cache: false - workflow: "build-matrix_portal_m4.yml" workflow_name: "Adafruit Matrix Portal M4" test_dir: "tests/platform/matrix_portal_m4" env_name: "matrix_portal_m4" firmware_ext: "bin" workflow_aliases: ["build-matrix_portal_m4.yml"] + toolchain_cache: false - workflow: "build-mgm240.yml" workflow_name: "Silicon Labs MGM240" test_dir: "tests/platform/mgm240" env_name: "mgm240" firmware_ext: "bin" workflow_aliases: ["build-mgm240.yml"] + toolchain_cache: true - workflow: "build-nano-every.yml" workflow_name: "Arduino Nano Every" test_dir: "tests/platform/nano_every" env_name: "nano_every" firmware_ext: "hex" workflow_aliases: ["build-nano-every.yml", "build-nano_every.yml"] + toolchain_cache: false - workflow: "build-nice_nano_nrf52840.yml" workflow_name: "Nice!Nano nRF52840" test_dir: "tests/platform/nice_nano_nrf52840" env_name: "nice_nano_nrf52840" firmware_ext: "hex" workflow_aliases: ["build-nice_nano_nrf52840.yml"] + toolchain_cache: false - workflow: "build-nrf52840-sense.yml" workflow_name: "Adafruit Feather nRF52840 Sense" test_dir: "tests/platform/adafruit_feather_nrf52840_sense" env_name: "nrf52840_sense" firmware_ext: "hex" workflow_aliases: ["build-nrf52840-sense.yml"] + toolchain_cache: false - workflow: "build-nrf52840_dk.yml" workflow_name: "Nordic nRF52840-DK" test_dir: "tests/platform/nrf52840_dk" env_name: "nrf52840_dk" firmware_ext: "hex" workflow_aliases: ["build-nrf52840_dk.yml"] + toolchain_cache: false - workflow: "build-nrfmicro_nrf52840.yml" workflow_name: "nrfmicro nRF52840" test_dir: "tests/platform/nrfmicro_nrf52840" env_name: "nrfmicro_nrf52840" firmware_ext: "hex" workflow_aliases: ["build-nrfmicro_nrf52840.yml"] + toolchain_cache: false - workflow: "build-nucleo-f429zi.yml" workflow_name: "ST Nucleo F429ZI" test_dir: "tests/platform/nucleo_f429zi" env_name: "nucleo_f429zi" firmware_ext: "hex" workflow_aliases: ["build-nucleo-f429zi.yml", "build-nucleo_f429zi.yml"] + toolchain_cache: false - workflow: "build-nucleo-f439zi.yml" workflow_name: "ST Nucleo F439ZI" test_dir: "tests/platform/nucleo_f439zi" env_name: "nucleo_f439zi" firmware_ext: "hex" workflow_aliases: ["build-nucleo-f439zi.yml", "build-nucleo_f439zi.yml"] + toolchain_cache: false - workflow: "build-qtpy_m0.yml" workflow_name: "Adafruit QT Py M0" test_dir: "tests/platform/qtpy_m0" env_name: "qtpy_m0" firmware_ext: "bin" workflow_aliases: ["build-qtpy_m0.yml"] + toolchain_cache: false - workflow: "build-rp2040.yml" workflow_name: "RP2040" test_dir: "tests/platform/rp2040" env_name: "rp2040" firmware_ext: "bin" workflow_aliases: ["build-rp2040.yml"] + toolchain_cache: false - workflow: "build-rp2350.yml" workflow_name: "RP2350" test_dir: "tests/platform/rp2350" env_name: "rp2350" firmware_ext: "bin" workflow_aliases: ["build-rp2350.yml"] + toolchain_cache: false - workflow: "build-rpipico.yml" workflow_name: "Raspberry Pi Pico" test_dir: "tests/platform/rpipico" env_name: "rpipico" firmware_ext: "bin" workflow_aliases: ["build-rpipico.yml"] + toolchain_cache: false - workflow: "build-rpipico2.yml" workflow_name: "Raspberry Pi Pico 2" test_dir: "tests/platform/rpipico2" env_name: "rpipico2" firmware_ext: "bin" workflow_aliases: ["build-rpipico2.yml"] + toolchain_cache: false - workflow: "build-sam3x8e_due.yml" workflow_name: "Atmel SAM3X8E (Due)" test_dir: "tests/platform/sam3x8e_due" env_name: "sam3x8e_due" firmware_ext: "bin" workflow_aliases: ["build-sam3x8e_due.yml"] + toolchain_cache: false - workflow: "build-samd21.yml" workflow_name: "Atmel SAMD21" test_dir: "tests/platform/samd21" env_name: "samd21" firmware_ext: "bin" workflow_aliases: ["build-samd21.yml"] + toolchain_cache: false - workflow: "build-samd21_zero.yml" workflow_name: "Arduino Zero (SAMD21)" test_dir: "tests/platform/samd21_zero" env_name: "samd21_zero" firmware_ext: "bin" workflow_aliases: ["build-samd21_zero.yml"] + toolchain_cache: false - workflow: "build-samd51j.yml" workflow_name: "Atmel SAMD51J" test_dir: "tests/platform/samd51j" env_name: "samd51j" firmware_ext: "bin" workflow_aliases: ["build-samd51j.yml"] + toolchain_cache: false - workflow: "build-samd51p.yml" workflow_name: "Atmel SAMD51P" test_dir: "tests/platform/samd51p" env_name: "samd51p" firmware_ext: "bin" workflow_aliases: ["build-samd51p.yml"] + toolchain_cache: false - workflow: "build-stm32f103c8.yml" workflow_name: "STM32F103C8" test_dir: "tests/platform/stm32f103c8" env_name: "stm32f103c8" firmware_ext: "hex" workflow_aliases: ["build-stm32f103c8.yml"] + toolchain_cache: false - workflow: "build-stm32f103cb.yml" workflow_name: "STM32F103CB" test_dir: "tests/platform/stm32f103cb" env_name: "stm32f103cb" firmware_ext: "hex" workflow_aliases: ["build-stm32f103cb.yml"] + toolchain_cache: false - workflow: "build-stm32f103tb.yml" workflow_name: "STM32F103TB" test_dir: "tests/platform/stm32f103tb" env_name: "stm32f103tb" firmware_ext: "hex" workflow_aliases: ["build-stm32f103tb.yml"] + toolchain_cache: false - workflow: "build-stm32f411ce.yml" workflow_name: "STM32F411CE" test_dir: "tests/platform/stm32f411ce" env_name: "stm32f411ce" firmware_ext: "hex" workflow_aliases: ["build-stm32f411ce.yml"] + toolchain_cache: false - workflow: "build-stm32h747xi.yml" workflow_name: "STM32H747XI" test_dir: "tests/platform/stm32h747xi" env_name: "stm32h747xi" firmware_ext: "bin" workflow_aliases: ["build-stm32h747xi.yml"] + toolchain_cache: false - workflow: "build-supermini_nrf52840.yml" workflow_name: "SuperMini nRF52840" test_dir: "tests/platform/supermini_nrf52840" env_name: "supermini_nrf52840" firmware_ext: "hex" workflow_aliases: ["build-supermini_nrf52840.yml"] + toolchain_cache: false - workflow: "build-teensy30.yml" workflow_name: "Teensy 3.0" test_dir: "tests/platform/teensy30" env_name: "teensy30" firmware_ext: "hex" workflow_aliases: ["build-teensy30.yml"] + toolchain_cache: false - workflow: "build-teensy31.yml" workflow_name: "Teensy 3.1" test_dir: "tests/platform/teensy31" env_name: "teensy31" firmware_ext: "hex" workflow_aliases: ["build-teensy31.yml"] + toolchain_cache: false - workflow: "build-teensy32.yml" workflow_name: "Teensy 3.2" test_dir: "tests/platform/teensy32" env_name: "teensy32" firmware_ext: "hex" workflow_aliases: ["build-teensy32.yml"] + toolchain_cache: false - workflow: "build-teensy35.yml" workflow_name: "Teensy 3.5" test_dir: "tests/platform/teensy35" env_name: "teensy35" firmware_ext: "hex" workflow_aliases: ["build-teensy35.yml"] + toolchain_cache: false - workflow: "build-teensy36.yml" workflow_name: "Teensy 3.6" test_dir: "tests/platform/teensy36" env_name: "teensy36" firmware_ext: "hex" workflow_aliases: ["build-teensy36.yml"] + toolchain_cache: false - workflow: "build-teensy40.yml" workflow_name: "Teensy 4.0" test_dir: "tests/platform/teensy40" env_name: "teensy40" firmware_ext: "hex" workflow_aliases: ["build-teensy40.yml"] + toolchain_cache: false - workflow: "build-teensy41.yml" workflow_name: "Teensy 4.1" test_dir: "tests/platform/teensy41" env_name: "teensy41" firmware_ext: "hex" workflow_aliases: ["build-teensy41.yml"] + toolchain_cache: false - workflow: "build-teensylc.yml" workflow_name: "Teensy LC" test_dir: "tests/platform/teensylc" env_name: "teensylc" firmware_ext: "hex" workflow_aliases: ["build-teensylc.yml"] + toolchain_cache: false - workflow: "build-thingplusmatter.yml" workflow_name: "SparkFun Thing Plus Matter" test_dir: "tests/platform/sparkfun_thingplusmatter" env_name: "thingplusmatter" firmware_ext: "bin" workflow_aliases: ["build-thingplusmatter.yml"] + toolchain_cache: false - workflow: "build-tinystm.yml" workflow_name: "HY TinySTM103TB" test_dir: "tests/platform/hy_tinystm103tb" env_name: "tinystm" firmware_ext: "hex" workflow_aliases: ["build-tinystm.yml"] + toolchain_cache: false - workflow: "build-uno-r4-wifi.yml" workflow_name: "Arduino Uno R4 WiFi" test_dir: "tests/platform/uno_r4_wifi" env_name: "uno_r4_wifi" firmware_ext: "bin" workflow_aliases: ["build-uno-r4-wifi.yml", "build-uno_r4_wifi.yml"] + toolchain_cache: false - workflow: "build-uno.yml" workflow_name: "Arduino Uno" test_dir: "tests/platform/uno" env_name: "uno" firmware_ext: "hex" workflow_aliases: ["build-uno.yml"] + toolchain_cache: false uses: ./.github/workflows/template_build.yml with: workflow-name: ${{ matrix.workflow_name }} @@ -632,6 +708,7 @@ jobs: firmware-ext: ${{ matrix.firmware_ext }} checkout_ref: ${{ needs.verify.outputs.candidate_sha }} fbuild-artifact: fbuild-bin-linux-debug + toolchain-cache: ${{ matrix.toolchain_cache }} coverage: name: Full coverage if: always() diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml index d8e2a29e..3c12e449 100644 --- a/.github/workflows/ci-test.yml +++ b/.github/workflows/ci-test.yml @@ -104,6 +104,7 @@ jobs: env_name: "uno" firmware_ext: "hex" workflow_aliases: ["build-uno.yml"] + toolchain_cache: false uses: ./.github/workflows/template_build.yml with: workflow-name: ${{ matrix.workflow_name }} @@ -112,6 +113,7 @@ jobs: firmware-ext: ${{ matrix.firmware_ext }} checkout_ref: ${{ needs.verify.outputs.candidate_sha }} fbuild-artifact: fbuild-bin-linux-debug + toolchain-cache: ${{ matrix.toolchain_cache }} coverage: name: ci-test coverage if: always() diff --git a/.github/workflows/template_build.yml b/.github/workflows/template_build.yml index e9bab2d9..8a65cf55 100644 --- a/.github/workflows/template_build.yml +++ b/.github/workflows/template_build.yml @@ -34,6 +34,15 @@ on: runners only execute"): the per-board compile was ~350s of a ~550s job, repeated across ~76 boards. Empty keeps the standalone compile path for direct `build-.yml` dispatches. + toolchain-cache: + required: false + type: boolean + default: false + description: >- + Restore/save the ~1GB ~/.fbuild/prod/cache toolchain cache. Off by + default: for most boards a cold download is faster than the cache + round-trip. Opted in per family in ci/board_families.json with the + measurement that justifies it. fbuild-run-id: required: false type: string @@ -114,14 +123,16 @@ jobs: # ipc shutdown path. See FastLED/fbuild#855. - name: Restore fbuild toolchains + if: inputs.toolchain-cache timeout-minutes: 10 uses: actions/cache/restore@v5 with: path: ~/.fbuild/prod/cache key: fbuild-toolchain-${{ runner.os }}-${{ inputs.env-name }}-${{ hashFiles(format('{0}/platformio.ini', inputs.test-dir)) }} + # No cross-board fallback: another board's ~1GB cache is mostly + # the wrong toolchain. restore-keys: | fbuild-toolchain-${{ runner.os }}-${{ inputs.env-name }}- - fbuild-toolchain-${{ runner.os }}- - name: Restore platform build artifacts timeout-minutes: 10 @@ -218,7 +229,7 @@ jobs: - name: Save fbuild toolchains # Default branch only -- see the setup-soldr save-cache note above. - if: always() && github.ref == 'refs/heads/main' + if: always() && inputs.toolchain-cache && github.ref == 'refs/heads/main' timeout-minutes: 10 uses: actions/cache/save@v5 with: diff --git a/ci/board_families.json b/ci/board_families.json index 7f3554b0..3725e536 100644 --- a/ci/board_families.json +++ b/ci/board_families.json @@ -60,7 +60,9 @@ "silabs": { "crate_paths": [ "crates/fbuild-build-arm/src/silabs/**" - ] + ], + "toolchain_cache": true, + "_toolchain_cache_why": "Measured 2026-09-29: cold MGM240 build 569s, almost all a ~480MB silabs-core download at a few MB/s. Every other family builds faster cold than restoring+saving its ~1GB toolchain cache (50 boards: 1738s cold vs 2248s cached)." }, "renesas": { "crate_paths": [ diff --git a/ci/render_workflows.py b/ci/render_workflows.py index dbd05cc7..3b5cbf4e 100644 --- a/ci/render_workflows.py +++ b/ci/render_workflows.py @@ -154,7 +154,16 @@ def render_on_block(board: dict, families: dict, common_paths: list[str]) -> str ) + render_concurrency_block(board) -def render_board_jobs(board: dict) -> str: +def toolchain_cache(board: dict, families: dict) -> bool: + """Whether a board restores/saves its ~1GB fbuild toolchain cache. + + Opt-in per family, justified by a measurement recorded in the SOT: for + most families a cold download is faster than the cache round-trip. + """ + return bool(families[board["family"]].get("toolchain_cache", False)) + + +def render_board_jobs(board: dict, families: dict) -> str: return ( "jobs:\n" " build:\n" @@ -167,6 +176,7 @@ def render_board_jobs(board: dict) -> str: " checkout_ref: ${{ inputs.checkout_ref }}\n" f" fbuild-artifact: ${{{{ inputs.fbuild-run-id && '{FBUILD_BIN_ARTIFACT}' || '' }}}}\n" " fbuild-run-id: ${{ inputs.fbuild-run-id }}\n" + f" toolchain-cache: {json.dumps(toolchain_cache(board, families))}\n" ) @@ -233,7 +243,7 @@ def render_fbuild_bin_job(needs: str, condition: str, ref: str) -> str: ) -def render_ci(boards: list[dict], tier: str) -> str: +def render_ci(boards: list[dict], tier: str, families: dict) -> str: full = tier == "full" minimal = tier == "minimal" selected = execution_boards(boards if full else [b for b in boards if b.get("fractional", False)]) @@ -244,6 +254,7 @@ def render_ci(boards: list[dict], tier: str) -> str: f" env_name: {json.dumps(b['env_name'])}\n" f" firmware_ext: {json.dumps(b['firmware_ext'])}\n" f" workflow_aliases: {json.dumps(b['workflow_aliases'])}\n" + f" toolchain_cache: {json.dumps(toolchain_cache(b, families))}\n" for b in selected ) if not selected: @@ -403,7 +414,8 @@ def render_ci(boards: list[dict], tier: str) -> str: + " env-name: ${{ matrix.env_name }}\n" + " firmware-ext: ${{ matrix.firmware_ext }}\n" + f" checkout_ref: {verified_ref}\n" - + f" fbuild-artifact: {FBUILD_BIN_ARTIFACT}\n") + + f" fbuild-artifact: {FBUILD_BIN_ARTIFACT}\n" + + " toolchain-cache: ${{ matrix.toolchain_cache }}\n") + ("" if minimal else " coverage:\n" + (" name: Full coverage\n" if full else " name: ci-test coverage\n") @@ -675,13 +687,13 @@ def main() -> int: old = path.read_text(encoding="utf-8") new_on = render_on_block(board, families, common_paths) new = rewrite(old, new_on) - new = new[: new.index("\njobs:\n") + 1] + render_board_jobs(board) + new = new[: new.index("\njobs:\n") + 1] + render_board_jobs(board, families) write_if_changed(path, new, args.check, drift, updated) write_if_changed(NIGHTLY_PATH, render_nightly(boards), args.check, drift, updated) - write_if_changed(MINIMAL_PATH, render_ci(boards, "minimal"), args.check, drift, updated) - write_if_changed(TEST_PATH, render_ci(boards, "test"), args.check, drift, updated) - write_if_changed(FULL_PATH, render_ci(boards, "full"), args.check, drift, updated) + write_if_changed(MINIMAL_PATH, render_ci(boards, "minimal", families), args.check, drift, updated) + write_if_changed(TEST_PATH, render_ci(boards, "test", families), args.check, drift, updated) + write_if_changed(FULL_PATH, render_ci(boards, "full", families), args.check, drift, updated) if args.check and drift: print("Drift detected -- the following workflows are out of sync with the SOT:", file=sys.stderr) diff --git a/ci/test_fractional_workflows.py b/ci/test_fractional_workflows.py index 5c55279c..8513857a 100644 --- a/ci/test_fractional_workflows.py +++ b/ci/test_fractional_workflows.py @@ -148,6 +148,16 @@ def test_board_workflows_reuse_a_dispatched_fbuild_binary(self): with_ = wf["jobs"]["build"]["with"] self.assertEqual("${{ inputs.fbuild-run-id }}", with_["fbuild-run-id"]) self.assertEqual(board["test_dir"], with_["test-dir"]) + self.assertEqual( + render_workflows.toolchain_cache(board, render_workflows.load_sot()["families"]), + with_["toolchain-cache"], + ) + + def test_toolchain_cache_is_opt_in_with_a_recorded_measurement(self): + for name, family in render_workflows.load_sot()["families"].items(): + with self.subTest(family=name): + if family.get("toolchain_cache"): + self.assertIn("_toolchain_cache_why", family) def test_ordinary_minimal_and_opt_in_test_are_distinct(self): minimal = self.load("ci-minimal.yml") From 5d14bf61b4f94b6fffff808da59f4ed850ba22c7 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Mon, 28 Sep 2026 22:14:37 -0700 Subject: [PATCH 05/12] perf(test): stop sleeping real retry backoffs in unit tests The ubuntu PR gate's Test step spent ~130s of test time on three things: - fbuild-packages-fetch retry tests used production backoffs (1+2+4+8s) serialized behind network_test_guard; they now use the existing FAST_RETRY_TIMING via a new get_with_retry_timed. - lock_recovers_stale_lock_dir planted an owner-less lock and waited out the real 30s MISSING_OWNER_GRACE; it now plants a dead-PID owner, which the acquire loop reclaims immediately. - resolve_rejects_corrupt_cache_entry refetched from an unresolvable host, which is retried with production backoff (15s); a local 404 fails the refetch immediately. Coverage of each contract is unchanged, and the production backoff constants stay asserted. Local: fbuild-packages-fetch lib tests 102.4s -> 1.7s, fbuild-toolchain 15.4s -> 0.2s. --- .../fbuild-packages-fetch/src/downloader.rs | 10 ++- .../src/downloader_tests.rs | 70 +++++++++++++------ .../fbuild-packages-fetch/src/install_lock.rs | 4 +- crates/fbuild-toolchain/src/lnk/resolver.rs | 25 ++++++- 4 files changed, 82 insertions(+), 27 deletions(-) diff --git a/crates/fbuild-packages-fetch/src/downloader.rs b/crates/fbuild-packages-fetch/src/downloader.rs index c35bc589..2cd91852 100644 --- a/crates/fbuild-packages-fetch/src/downloader.rs +++ b/crates/fbuild-packages-fetch/src/downloader.rs @@ -352,10 +352,14 @@ pub async fn download_file(url: &str, dest_dir: &Path) -> Result { /// attempts. A non-2xx HTTP status is treated as a hard failure /// (only server-side 5xx is retried). async fn get_with_retry(url: &str) -> Result> { - get_with_retry_using(http::client(), url).await + get_with_retry_timed(http::client(), url, RetryTiming::PRODUCTION).await } -async fn get_with_retry_using(client: &reqwest::Client, url: &str) -> Result> { +async fn get_with_retry_timed( + client: &reqwest::Client, + url: &str, + timing: RetryTiming, +) -> Result> { let mut attempt: u32 = 0; loop { attempt += 1; @@ -370,7 +374,7 @@ async fn get_with_retry_using(client: &reqwest::Client, url: &str) -> Result return Ok(bytes), Err(error) if error.is_retryable() && attempt < MAX_ATTEMPTS => { - wait_before_retry(url, attempt, &error, RetryTiming::PRODUCTION).await; + wait_before_retry(url, attempt, &error, timing).await; } Err(error) => return Err(error.into_fbuild_error(url)), } diff --git a/crates/fbuild-packages-fetch/src/downloader_tests.rs b/crates/fbuild-packages-fetch/src/downloader_tests.rs index c36111ed..5357bac3 100644 --- a/crates/fbuild-packages-fetch/src/downloader_tests.rs +++ b/crates/fbuild-packages-fetch/src/downloader_tests.rs @@ -192,7 +192,7 @@ async fn get_with_retry_retries_on_5xx() { let request_count = std::sync::Arc::new(AtomicUsize::new(0)); let port = run_flaky_server(responses.clone(), request_count.clone()).await; let url = format!("http://127.0.0.1:{port}/file"); - let bytes = get_with_retry_using(&test_client(), &url) + let bytes = get_with_retry_timed(&test_client(), &url, FAST_RETRY_TIMING) .await .expect("retry should succeed"); assert_eq!(bytes, b"hello"); @@ -211,7 +211,7 @@ async fn get_with_retry_does_not_retry_on_4xx() { let request_count = std::sync::Arc::new(AtomicUsize::new(0)); let port = run_flaky_server(responses.clone(), request_count.clone()).await; let url = format!("http://127.0.0.1:{port}/missing"); - let err = get_with_retry_using(&test_client(), &url) + let err = get_with_retry_timed(&test_client(), &url, FAST_RETRY_TIMING) .await .expect_err("should error"); assert!( @@ -236,7 +236,7 @@ async fn get_with_retry_gives_up_after_max_attempts() { let request_count = std::sync::Arc::new(AtomicUsize::new(0)); let port = run_flaky_server(responses.clone(), request_count.clone()).await; let url = format!("http://127.0.0.1:{port}/file"); - let err = get_with_retry_using(&test_client(), &url) + let err = get_with_retry_timed(&test_client(), &url, FAST_RETRY_TIMING) .await .expect_err("should give up"); // Last attempt was a 503; that's what gets surfaced. @@ -261,7 +261,7 @@ async fn get_with_retry_retries_truncated_bodies_until_attempt_five() { let port = run_flaky_server(responses, request_count.clone()).await; let url = format!("http://127.0.0.1:{port}/file"); - let bytes = get_with_retry_using(&test_client(), &url) + let bytes = get_with_retry_timed(&test_client(), &url, FAST_RETRY_TIMING) .await .expect("the fifth complete response should succeed"); @@ -283,7 +283,7 @@ async fn get_with_retry_stops_after_five_truncated_bodies() { let port = run_flaky_server(responses, request_count.clone()).await; let url = format!("http://127.0.0.1:{port}/file"); - let _err = get_with_retry_using(&test_client(), &url) + let _err = get_with_retry_timed(&test_client(), &url, FAST_RETRY_TIMING) .await .expect_err("the fifth truncated response should exhaust retries"); @@ -310,9 +310,15 @@ async fn streaming_download_retries_truncated_bodies_until_attempt_five() { let temp = tempfile::TempDir::new().unwrap(); let mut progress = |_progress: &DownloadProgress| {}; - download_file_with_progress_using(&test_client(), &url, temp.path(), &mut progress) - .await - .expect("the fifth complete response should succeed"); + download_file_with_progress_timed( + &test_client(), + &url, + temp.path(), + &mut progress, + FAST_RETRY_TIMING, + ) + .await + .expect("the fifth complete response should succeed"); assert_eq!(std::fs::read(temp.path().join("file")).unwrap(), b"hello"); assert_eq!(request_count.load(Ordering::SeqCst), 5); @@ -334,9 +340,15 @@ async fn streaming_download_stops_after_five_stalled_attempts_without_output() { let temp = tempfile::TempDir::new().unwrap(); let mut progress = |_progress: &DownloadProgress| {}; - let _err = download_file_with_progress_using(&test_client(), &url, temp.path(), &mut progress) - .await - .expect_err("the fifth truncated response should exhaust retries"); + let _err = download_file_with_progress_timed( + &test_client(), + &url, + temp.path(), + &mut progress, + FAST_RETRY_TIMING, + ) + .await + .expect_err("the fifth truncated response should exhaust retries"); // Six, not five, and the extra one is the point of // FastLED/fbuild#1370: the budget is now five attempts that make *no @@ -448,9 +460,15 @@ async fn streaming_download_resumes_from_the_byte_offset_after_a_drop() { let mut seen: Vec = Vec::new(); let mut progress = |p: &DownloadProgress| seen.push(p.downloaded); - download_file_with_progress_using(&test_client(), &url, temp.path(), &mut progress) - .await - .expect("a ranged retry should finish the download"); + download_file_with_progress_timed( + &test_client(), + &url, + temp.path(), + &mut progress, + FAST_RETRY_TIMING, + ) + .await + .expect("a ranged retry should finish the download"); assert_eq!( std::fs::read(temp.path().join("file")).unwrap(), @@ -496,9 +514,15 @@ async fn streaming_download_gives_up_when_the_server_ignores_range() { let temp = tempfile::TempDir::new().unwrap(); let mut progress = |_p: &DownloadProgress| {}; - let error = download_file_with_progress_using(&test_client(), &url, temp.path(), &mut progress) - .await - .expect_err("a server that never sends the tail must fail, not hang"); + let error = download_file_with_progress_timed( + &test_client(), + &url, + temp.path(), + &mut progress, + FAST_RETRY_TIMING, + ) + .await + .expect_err("a server that never sends the tail must fail, not hang"); let message = error.to_string(); assert!( @@ -688,9 +712,15 @@ async fn streaming_download_treats_416_as_complete_without_appending_its_body() let temp = tempfile::TempDir::new().unwrap(); let mut progress = |_p: &DownloadProgress| {}; - download_file_with_progress_using(&test_client(), &url, temp.path(), &mut progress) - .await - .expect("a complete first response should succeed"); + download_file_with_progress_timed( + &test_client(), + &url, + temp.path(), + &mut progress, + FAST_RETRY_TIMING, + ) + .await + .expect("a complete first response should succeed"); let written = std::fs::read(temp.path().join("file")).unwrap(); assert_eq!( diff --git a/crates/fbuild-packages-fetch/src/install_lock.rs b/crates/fbuild-packages-fetch/src/install_lock.rs index 041ae36f..7705604e 100644 --- a/crates/fbuild-packages-fetch/src/install_lock.rs +++ b/crates/fbuild-packages-fetch/src/install_lock.rs @@ -570,7 +570,9 @@ mod tests { let install_path = tmp.path().join("platform").join("2.0"); std::fs::create_dir_all(install_path.parent().unwrap()).unwrap(); let lock_dir = install_lock_dir(&install_path).unwrap(); - std::fs::create_dir(&lock_dir).unwrap(); + // A crashed owner's lock. A bare directory with no owner record + // would instead wait out the real 30 s MISSING_OWNER_GRACE. + plant_lock(&lock_dir, DEAD_PID, None); let guard = acquire_install_lock_at( &lock_dir, diff --git a/crates/fbuild-toolchain/src/lnk/resolver.rs b/crates/fbuild-toolchain/src/lnk/resolver.rs index 12238f63..5f51dcbe 100644 --- a/crates/fbuild-toolchain/src/lnk/resolver.rs +++ b/crates/fbuild-toolchain/src/lnk/resolver.rs @@ -305,13 +305,32 @@ mod tests { assert!(resolved.lease.is_some()); } + /// Serve a single `404` so a refetch fails immediately: 4xx is not + /// retried, whereas an unresolvable host is retried with the production + /// 1+2+4+8 s backoff (15 s of test time for no extra coverage). + fn serve_one_404() -> String { + let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap(); + let port = listener.local_addr().unwrap().port(); + std::thread::spawn(move || { + if let Ok((mut stream, _)) = listener.accept() { + let mut buf = [0u8; 1024]; + let _ = std::io::Read::read(&mut stream, &mut buf); + let _ = stream.write_all( + b"HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\nConnection: close\r\n\r\n", + ); + } + }); + format!("http://127.0.0.1:{port}/corrupt.bin") + } + /// Cache-hit but stored sha doesn't match content → resolve must fall - /// through to refetch (which then fails because we used a fake URL, - /// but the *behavior* we care about is that the bad cache was rejected). + /// through to refetch (which then fails with a 404, but the *behavior* + /// we care about is that the bad cache was rejected). #[test] fn resolve_rejects_corrupt_cache_entry() { let (_tmp, cache) = open_test_cache(); - let url = "https://localhost.invalid/corrupt.bin"; + let url_owned = serve_one_404(); + let url = url_owned.as_str(); let claimed_sha = sha256_of(b"good content"); // what .lnk says let archive_dir = cache.archive_dir(Kind::LnkBlobs, url, &claimed_sha); std::fs::create_dir_all(&archive_dir).unwrap(); From c6e69d1f9290fea5fff65ff9bfc8e8f59dde4ae5 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Mon, 28 Sep 2026 22:44:58 -0700 Subject: [PATCH 06/12] perf(test): merge fbuild-build and fbuild-daemon integration tests into one binary each 26 top-level tests/*.rs files each linked the crate's full dependency graph as a separate binary. They are now modules of tests/it/main.rs (zackees/ci.yml RUST-005). avr_build and eh_frame_strip_esp32 stay standalone: their #[ignore]d download tests mutate process env vars that other ignored tests read, so sharing a process could race. Local: cargo test --no-run -p fbuild-build -p fbuild-daemon after a clean of those crates went 59-79s -> 20-31s. Test counts unchanged. --- crates/fbuild-build/tests/it/README.md | 7 +++++++ .../{ => it}/cache_survives_tar_extract.rs | 0 .../tests/{ => it}/clangd_check_parity.rs | 0 .../{ => it}/compile_many_stage2_perf.rs | 0 .../tests/{ => it}/compile_many_two_stage.rs | 0 .../tests/{ => it}/esp32_build.rs | 0 .../tests/{ => it}/esp32s3_size_parity.rs | 0 .../tests/{ => it}/flag_escaping_lint.rs | 0 .../tests/{ => it}/lite_scons_acceptance.rs | 0 crates/fbuild-build/tests/it/main.rs | 20 +++++++++++++++++++ .../tests/{ => it}/nxplpc_build_flags.rs | 0 .../{ => it}/nxplpc_core_compile_commands.rs | 0 .../tests/{ => it}/stm32_acceptance.rs | 0 .../tests/{ => it}/teensy30_acceptance.rs | 0 .../tests/{ => it}/teensy41_acceptance.rs | 0 .../tests/{ => it}/teensy_build.rs | 0 .../tests/{ => it}/teensylc_acceptance.rs | 0 .../tests/{ => it}/zccache_embedded_smoke.rs | 0 crates/fbuild-daemon/tests/it/README.md | 7 +++++++ .../tests/{ => it}/build_streaming.rs | 0 .../{ => it}/legacy_daemon_transition.rs | 0 crates/fbuild-daemon/tests/it/main.rs | 14 +++++++++++++ .../tests/{ => it}/port_recovery.rs | 0 .../tests/{ => it}/process_containment.rs | 0 .../fbuild-daemon/tests/{ => it}/profiling.rs | 0 .../tests/{ => it}/test_boards_route.rs | 0 .../{ => it}/test_build_progress_route.rs | 0 .../tests/{ => it}/test_emu_endpoint.rs | 0 .../tests/{ => it}/test_libraries_route.rs | 0 .../tests/{ => it}/test_plotter_route.rs | 0 30 files changed, 48 insertions(+) create mode 100644 crates/fbuild-build/tests/it/README.md rename crates/fbuild-build/tests/{ => it}/cache_survives_tar_extract.rs (100%) rename crates/fbuild-build/tests/{ => it}/clangd_check_parity.rs (100%) rename crates/fbuild-build/tests/{ => it}/compile_many_stage2_perf.rs (100%) rename crates/fbuild-build/tests/{ => it}/compile_many_two_stage.rs (100%) rename crates/fbuild-build/tests/{ => it}/esp32_build.rs (100%) rename crates/fbuild-build/tests/{ => it}/esp32s3_size_parity.rs (100%) rename crates/fbuild-build/tests/{ => it}/flag_escaping_lint.rs (100%) rename crates/fbuild-build/tests/{ => it}/lite_scons_acceptance.rs (100%) create mode 100644 crates/fbuild-build/tests/it/main.rs rename crates/fbuild-build/tests/{ => it}/nxplpc_build_flags.rs (100%) rename crates/fbuild-build/tests/{ => it}/nxplpc_core_compile_commands.rs (100%) rename crates/fbuild-build/tests/{ => it}/stm32_acceptance.rs (100%) rename crates/fbuild-build/tests/{ => it}/teensy30_acceptance.rs (100%) rename crates/fbuild-build/tests/{ => it}/teensy41_acceptance.rs (100%) rename crates/fbuild-build/tests/{ => it}/teensy_build.rs (100%) rename crates/fbuild-build/tests/{ => it}/teensylc_acceptance.rs (100%) rename crates/fbuild-build/tests/{ => it}/zccache_embedded_smoke.rs (100%) create mode 100644 crates/fbuild-daemon/tests/it/README.md rename crates/fbuild-daemon/tests/{ => it}/build_streaming.rs (100%) rename crates/fbuild-daemon/tests/{ => it}/legacy_daemon_transition.rs (100%) create mode 100644 crates/fbuild-daemon/tests/it/main.rs rename crates/fbuild-daemon/tests/{ => it}/port_recovery.rs (100%) rename crates/fbuild-daemon/tests/{ => it}/process_containment.rs (100%) rename crates/fbuild-daemon/tests/{ => it}/profiling.rs (100%) rename crates/fbuild-daemon/tests/{ => it}/test_boards_route.rs (100%) rename crates/fbuild-daemon/tests/{ => it}/test_build_progress_route.rs (100%) rename crates/fbuild-daemon/tests/{ => it}/test_emu_endpoint.rs (100%) rename crates/fbuild-daemon/tests/{ => it}/test_libraries_route.rs (100%) rename crates/fbuild-daemon/tests/{ => it}/test_plotter_route.rs (100%) diff --git a/crates/fbuild-build/tests/it/README.md b/crates/fbuild-build/tests/it/README.md new file mode 100644 index 00000000..3c09da99 --- /dev/null +++ b/crates/fbuild-build/tests/it/README.md @@ -0,0 +1,7 @@ +# fbuild-build integration tests + +All integration tests for `fbuild-build` compile into this single `it` binary; each +`*.rs` here is a module listed in `main.rs`. Add new integration tests +as a module here, not as a new top-level `tests/*.rs` file: every top-level +file is a separate binary that re-links the crate's whole dependency graph +(zackees/ci.yml RUST-005). diff --git a/crates/fbuild-build/tests/cache_survives_tar_extract.rs b/crates/fbuild-build/tests/it/cache_survives_tar_extract.rs similarity index 100% rename from crates/fbuild-build/tests/cache_survives_tar_extract.rs rename to crates/fbuild-build/tests/it/cache_survives_tar_extract.rs diff --git a/crates/fbuild-build/tests/clangd_check_parity.rs b/crates/fbuild-build/tests/it/clangd_check_parity.rs similarity index 100% rename from crates/fbuild-build/tests/clangd_check_parity.rs rename to crates/fbuild-build/tests/it/clangd_check_parity.rs diff --git a/crates/fbuild-build/tests/compile_many_stage2_perf.rs b/crates/fbuild-build/tests/it/compile_many_stage2_perf.rs similarity index 100% rename from crates/fbuild-build/tests/compile_many_stage2_perf.rs rename to crates/fbuild-build/tests/it/compile_many_stage2_perf.rs diff --git a/crates/fbuild-build/tests/compile_many_two_stage.rs b/crates/fbuild-build/tests/it/compile_many_two_stage.rs similarity index 100% rename from crates/fbuild-build/tests/compile_many_two_stage.rs rename to crates/fbuild-build/tests/it/compile_many_two_stage.rs diff --git a/crates/fbuild-build/tests/esp32_build.rs b/crates/fbuild-build/tests/it/esp32_build.rs similarity index 100% rename from crates/fbuild-build/tests/esp32_build.rs rename to crates/fbuild-build/tests/it/esp32_build.rs diff --git a/crates/fbuild-build/tests/esp32s3_size_parity.rs b/crates/fbuild-build/tests/it/esp32s3_size_parity.rs similarity index 100% rename from crates/fbuild-build/tests/esp32s3_size_parity.rs rename to crates/fbuild-build/tests/it/esp32s3_size_parity.rs diff --git a/crates/fbuild-build/tests/flag_escaping_lint.rs b/crates/fbuild-build/tests/it/flag_escaping_lint.rs similarity index 100% rename from crates/fbuild-build/tests/flag_escaping_lint.rs rename to crates/fbuild-build/tests/it/flag_escaping_lint.rs diff --git a/crates/fbuild-build/tests/lite_scons_acceptance.rs b/crates/fbuild-build/tests/it/lite_scons_acceptance.rs similarity index 100% rename from crates/fbuild-build/tests/lite_scons_acceptance.rs rename to crates/fbuild-build/tests/it/lite_scons_acceptance.rs diff --git a/crates/fbuild-build/tests/it/main.rs b/crates/fbuild-build/tests/it/main.rs new file mode 100644 index 00000000..1d5cea59 --- /dev/null +++ b/crates/fbuild-build/tests/it/main.rs @@ -0,0 +1,20 @@ +//! One integration-test binary for this crate (zackees/ci.yml RUST-005): +//! each top-level `tests/*.rs` file links the crate's whole dependency +//! graph separately, so these modules share one link instead. + +mod cache_survives_tar_extract; +mod clangd_check_parity; +mod compile_many_stage2_perf; +mod compile_many_two_stage; +mod esp32_build; +mod esp32s3_size_parity; +mod flag_escaping_lint; +mod lite_scons_acceptance; +mod nxplpc_build_flags; +mod nxplpc_core_compile_commands; +mod stm32_acceptance; +mod teensy30_acceptance; +mod teensy41_acceptance; +mod teensy_build; +mod teensylc_acceptance; +mod zccache_embedded_smoke; diff --git a/crates/fbuild-build/tests/nxplpc_build_flags.rs b/crates/fbuild-build/tests/it/nxplpc_build_flags.rs similarity index 100% rename from crates/fbuild-build/tests/nxplpc_build_flags.rs rename to crates/fbuild-build/tests/it/nxplpc_build_flags.rs diff --git a/crates/fbuild-build/tests/nxplpc_core_compile_commands.rs b/crates/fbuild-build/tests/it/nxplpc_core_compile_commands.rs similarity index 100% rename from crates/fbuild-build/tests/nxplpc_core_compile_commands.rs rename to crates/fbuild-build/tests/it/nxplpc_core_compile_commands.rs diff --git a/crates/fbuild-build/tests/stm32_acceptance.rs b/crates/fbuild-build/tests/it/stm32_acceptance.rs similarity index 100% rename from crates/fbuild-build/tests/stm32_acceptance.rs rename to crates/fbuild-build/tests/it/stm32_acceptance.rs diff --git a/crates/fbuild-build/tests/teensy30_acceptance.rs b/crates/fbuild-build/tests/it/teensy30_acceptance.rs similarity index 100% rename from crates/fbuild-build/tests/teensy30_acceptance.rs rename to crates/fbuild-build/tests/it/teensy30_acceptance.rs diff --git a/crates/fbuild-build/tests/teensy41_acceptance.rs b/crates/fbuild-build/tests/it/teensy41_acceptance.rs similarity index 100% rename from crates/fbuild-build/tests/teensy41_acceptance.rs rename to crates/fbuild-build/tests/it/teensy41_acceptance.rs diff --git a/crates/fbuild-build/tests/teensy_build.rs b/crates/fbuild-build/tests/it/teensy_build.rs similarity index 100% rename from crates/fbuild-build/tests/teensy_build.rs rename to crates/fbuild-build/tests/it/teensy_build.rs diff --git a/crates/fbuild-build/tests/teensylc_acceptance.rs b/crates/fbuild-build/tests/it/teensylc_acceptance.rs similarity index 100% rename from crates/fbuild-build/tests/teensylc_acceptance.rs rename to crates/fbuild-build/tests/it/teensylc_acceptance.rs diff --git a/crates/fbuild-build/tests/zccache_embedded_smoke.rs b/crates/fbuild-build/tests/it/zccache_embedded_smoke.rs similarity index 100% rename from crates/fbuild-build/tests/zccache_embedded_smoke.rs rename to crates/fbuild-build/tests/it/zccache_embedded_smoke.rs diff --git a/crates/fbuild-daemon/tests/it/README.md b/crates/fbuild-daemon/tests/it/README.md new file mode 100644 index 00000000..6a14b6e4 --- /dev/null +++ b/crates/fbuild-daemon/tests/it/README.md @@ -0,0 +1,7 @@ +# fbuild-daemon integration tests + +All integration tests for `fbuild-daemon` compile into this single `it` binary; each +`*.rs` here is a module listed in `main.rs`. Add new integration tests +as a module here, not as a new top-level `tests/*.rs` file: every top-level +file is a separate binary that re-links the crate's whole dependency graph +(zackees/ci.yml RUST-005). diff --git a/crates/fbuild-daemon/tests/build_streaming.rs b/crates/fbuild-daemon/tests/it/build_streaming.rs similarity index 100% rename from crates/fbuild-daemon/tests/build_streaming.rs rename to crates/fbuild-daemon/tests/it/build_streaming.rs diff --git a/crates/fbuild-daemon/tests/legacy_daemon_transition.rs b/crates/fbuild-daemon/tests/it/legacy_daemon_transition.rs similarity index 100% rename from crates/fbuild-daemon/tests/legacy_daemon_transition.rs rename to crates/fbuild-daemon/tests/it/legacy_daemon_transition.rs diff --git a/crates/fbuild-daemon/tests/it/main.rs b/crates/fbuild-daemon/tests/it/main.rs new file mode 100644 index 00000000..88767f1e --- /dev/null +++ b/crates/fbuild-daemon/tests/it/main.rs @@ -0,0 +1,14 @@ +//! One integration-test binary for this crate (zackees/ci.yml RUST-005): +//! each top-level `tests/*.rs` file links the crate's whole dependency +//! graph separately, so these modules share one link instead. + +mod build_streaming; +mod legacy_daemon_transition; +mod port_recovery; +mod process_containment; +mod profiling; +mod test_boards_route; +mod test_build_progress_route; +mod test_emu_endpoint; +mod test_libraries_route; +mod test_plotter_route; diff --git a/crates/fbuild-daemon/tests/port_recovery.rs b/crates/fbuild-daemon/tests/it/port_recovery.rs similarity index 100% rename from crates/fbuild-daemon/tests/port_recovery.rs rename to crates/fbuild-daemon/tests/it/port_recovery.rs diff --git a/crates/fbuild-daemon/tests/process_containment.rs b/crates/fbuild-daemon/tests/it/process_containment.rs similarity index 100% rename from crates/fbuild-daemon/tests/process_containment.rs rename to crates/fbuild-daemon/tests/it/process_containment.rs diff --git a/crates/fbuild-daemon/tests/profiling.rs b/crates/fbuild-daemon/tests/it/profiling.rs similarity index 100% rename from crates/fbuild-daemon/tests/profiling.rs rename to crates/fbuild-daemon/tests/it/profiling.rs diff --git a/crates/fbuild-daemon/tests/test_boards_route.rs b/crates/fbuild-daemon/tests/it/test_boards_route.rs similarity index 100% rename from crates/fbuild-daemon/tests/test_boards_route.rs rename to crates/fbuild-daemon/tests/it/test_boards_route.rs diff --git a/crates/fbuild-daemon/tests/test_build_progress_route.rs b/crates/fbuild-daemon/tests/it/test_build_progress_route.rs similarity index 100% rename from crates/fbuild-daemon/tests/test_build_progress_route.rs rename to crates/fbuild-daemon/tests/it/test_build_progress_route.rs diff --git a/crates/fbuild-daemon/tests/test_emu_endpoint.rs b/crates/fbuild-daemon/tests/it/test_emu_endpoint.rs similarity index 100% rename from crates/fbuild-daemon/tests/test_emu_endpoint.rs rename to crates/fbuild-daemon/tests/it/test_emu_endpoint.rs diff --git a/crates/fbuild-daemon/tests/test_libraries_route.rs b/crates/fbuild-daemon/tests/it/test_libraries_route.rs similarity index 100% rename from crates/fbuild-daemon/tests/test_libraries_route.rs rename to crates/fbuild-daemon/tests/it/test_libraries_route.rs diff --git a/crates/fbuild-daemon/tests/test_plotter_route.rs b/crates/fbuild-daemon/tests/it/test_plotter_route.rs similarity index 100% rename from crates/fbuild-daemon/tests/test_plotter_route.rs rename to crates/fbuild-daemon/tests/it/test_plotter_route.rs From 1ad3cc7599d75d4af588eabdf5a1ef92b12e6684 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Mon, 28 Sep 2026 22:53:37 -0700 Subject: [PATCH 07/12] fix(ci): follow the tests/it move everywhere; address review - Dylint ban_std_pathbuf allowlist, docs and run instructions pointed at the old tests/*.rs paths (Dylint policy failed on the stale entries). - acceptance-205.yml and esp32s3-size-parity.yml selected tests with --test ; they now run --test it with a module-qualified filter. All four acceptance filters verified against --list. - Dispatcher: a failed gh workflow run no longer stops later boards; failures are collected and fail the job once at the end. - fbuild_bin checkout sets persist-credentials: false. - resolve_rejects_corrupt_cache_entry now asserts the refetch actually reached the local server, with bounded accept/socket I/O and a join. --- .github/workflows/acceptance-205.yml | 2 +- .github/workflows/ci-full.yml | 1 + .github/workflows/ci-test.yml | 1 + .github/workflows/esp32s3-size-parity.yml | 2 +- .github/workflows/nightly-platforms.yml | 16 ++++- bench/fastled-examples/README.md | 2 +- ci/render_workflows.py | 18 +++++- .../tests/it/clangd_check_parity.rs | 2 +- .../tests/it/compile_many_stage2_perf.rs | 2 +- crates/fbuild-build/tests/it/esp32_build.rs | 2 +- .../tests/it/esp32s3_size_parity.rs | 2 +- .../tests/it/flag_escaping_lint.rs | 2 +- .../tests/it/nxplpc_build_flags.rs | 2 +- .../fbuild-build/tests/it/stm32_acceptance.rs | 2 +- .../tests/it/teensy30_acceptance.rs | 2 +- .../tests/it/teensy41_acceptance.rs | 4 +- crates/fbuild-build/tests/it/teensy_build.rs | 2 +- .../tests/it/teensylc_acceptance.rs | 2 +- .../tests/it/process_containment.rs | 2 +- crates/fbuild-toolchain/src/lnk/resolver.rs | 61 +++++++++++++++---- docs/DEVELOPMENT.md | 4 +- dylints/ban_bare_reqwest/src/lib.rs | 2 +- dylints/ban_std_pathbuf/src/allowlist.txt | 22 +++---- tests/platform/lpc845_build_flags/README.md | 4 +- 24 files changed, 110 insertions(+), 51 deletions(-) diff --git a/.github/workflows/acceptance-205.yml b/.github/workflows/acceptance-205.yml index 0fe0d5ba..b22ed445 100644 --- a/.github/workflows/acceptance-205.yml +++ b/.github/workflows/acceptance-205.yml @@ -73,4 +73,4 @@ jobs: - name: Run ${{ matrix.gate }} acceptance gate run: | - soldr cargo test -p fbuild-build --test ${{ matrix.test_bin }} -- --ignored --exact ${{ matrix.test_fn }} --nocapture --test-threads=1 + soldr cargo test -p fbuild-build --test it -- --ignored --exact ${{ matrix.test_bin }}::${{ matrix.test_fn }} --nocapture --test-threads=1 diff --git a/.github/workflows/ci-full.yml b/.github/workflows/ci-full.yml index 41c72172..5f1465a0 100644 --- a/.github/workflows/ci-full.yml +++ b/.github/workflows/ci-full.yml @@ -139,6 +139,7 @@ jobs: - uses: actions/checkout@v6 with: ref: ${{ needs.verify.outputs.candidate_sha }} + persist-credentials: false - uses: zackees/setup-soldr@dfbe9627f6cb0226716b61625b99a58949162720 with: cache-preset: foundation diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml index 3c12e449..ac3e73a6 100644 --- a/.github/workflows/ci-test.yml +++ b/.github/workflows/ci-test.yml @@ -69,6 +69,7 @@ jobs: - uses: actions/checkout@v6 with: ref: ${{ needs.verify.outputs.candidate_sha }} + persist-credentials: false - uses: zackees/setup-soldr@dfbe9627f6cb0226716b61625b99a58949162720 with: cache-preset: foundation diff --git a/.github/workflows/esp32s3-size-parity.yml b/.github/workflows/esp32s3-size-parity.yml index f0fbd98b..876f22fe 100644 --- a/.github/workflows/esp32s3-size-parity.yml +++ b/.github/workflows/esp32s3-size-parity.yml @@ -51,4 +51,4 @@ jobs: - name: Compare ESP32-S3 Blink firmware size run: | - soldr cargo test -p fbuild-build --test esp32s3_size_parity -- --ignored --nocapture --test-threads=1 + soldr cargo test -p fbuild-build --test it esp32s3_size_parity:: -- --ignored --nocapture --test-threads=1 diff --git a/.github/workflows/nightly-platforms.yml b/.github/workflows/nightly-platforms.yml index f814bcc3..ddec09b1 100644 --- a/.github/workflows/nightly-platforms.yml +++ b/.github/workflows/nightly-platforms.yml @@ -64,6 +64,7 @@ jobs: - uses: actions/checkout@v6 with: ref: ${{ github.sha }} + persist-credentials: false - uses: zackees/setup-soldr@dfbe9627f6cb0226716b61625b99a58949162720 with: cache-preset: foundation @@ -97,8 +98,17 @@ jobs: GH_REPO: ${{ github.repository }} WORKFLOWS: ${{ needs.plan.outputs.workflows }} run: | + failed=() for wf in $(echo "$WORKFLOWS" | jq -r '.[]'); do - gh workflow run "$wf" --ref "$GITHUB_REF_NAME" \ - -f fbuild-run-id="$GITHUB_RUN_ID" -f checkout_ref="$GITHUB_SHA" - echo "dispatched $wf" + if gh workflow run "$wf" --ref "$GITHUB_REF_NAME" \ + -f fbuild-run-id="$GITHUB_RUN_ID" -f checkout_ref="$GITHUB_SHA"; then + echo "dispatched $wf" + else + echo "::error::failed to dispatch $wf" + failed+=("$wf") + fi done + if [ "${#failed[@]}" -gt 0 ]; then + echo "failed to dispatch: ${failed[*]}" >&2 + exit 1 + fi diff --git a/bench/fastled-examples/README.md b/bench/fastled-examples/README.md index 678fe94e..43de278a 100644 --- a/bench/fastled-examples/README.md +++ b/bench/fastled-examples/README.md @@ -22,7 +22,7 @@ fresh `FileKvStore`: The framework library set is a synthetic Teensyduino-class stub built via `MiniFramework`. The bench measures resolver throughput, not the correctness of which libraries get selected — that is the acceptance-test -layer (`crates/fbuild-build/tests/teensylc_acceptance.rs`). +layer (`crates/fbuild-build/tests/it/teensylc_acceptance.rs`). ## Running diff --git a/ci/render_workflows.py b/ci/render_workflows.py index 3b5cbf4e..0b52e2fa 100644 --- a/ci/render_workflows.py +++ b/ci/render_workflows.py @@ -219,6 +219,7 @@ def render_fbuild_bin_job(needs: str, condition: str, ref: str) -> str: " - uses: actions/checkout@v6\n" " with:\n" f" ref: {ref}\n" + " persist-credentials: false\n" " - uses: zackees/setup-soldr@dfbe9627f6cb0226716b61625b99a58949162720\n" " with:\n" " cache-preset: foundation\n" @@ -625,11 +626,22 @@ def render_nightly(boards: list[dict]) -> str: " GH_REPO: ${{ github.repository }}\n" " WORKFLOWS: ${{ needs.plan.outputs.workflows }}\n" " run: |\n" + # One failed dispatch (API blip, rate limit) must not strand every + # later board's badge: keep going, then fail once at the end. + " failed=()\n" " for wf in $(echo \"$WORKFLOWS\" | jq -r '.[]'); do\n" - " gh workflow run \"$wf\" --ref \"$GITHUB_REF_NAME\" \\\n" - " -f fbuild-run-id=\"$GITHUB_RUN_ID\" -f checkout_ref=\"$GITHUB_SHA\"\n" - " echo \"dispatched $wf\"\n" + " if gh workflow run \"$wf\" --ref \"$GITHUB_REF_NAME\" \\\n" + " -f fbuild-run-id=\"$GITHUB_RUN_ID\" -f checkout_ref=\"$GITHUB_SHA\"; then\n" + " echo \"dispatched $wf\"\n" + " else\n" + " echo \"::error::failed to dispatch $wf\"\n" + " failed+=(\"$wf\")\n" + " fi\n" " done\n" + " if [ \"${#failed[@]}\" -gt 0 ]; then\n" + " echo \"failed to dispatch: ${failed[*]}\" >&2\n" + " exit 1\n" + " fi\n" ) return header + render_fbuild_bin_job( "plan", " if: needs.plan.outputs.workflows != '[]'\n", "${{ github.sha }}" diff --git a/crates/fbuild-build/tests/it/clangd_check_parity.rs b/crates/fbuild-build/tests/it/clangd_check_parity.rs index da20719b..44df073b 100644 --- a/crates/fbuild-build/tests/it/clangd_check_parity.rs +++ b/crates/fbuild-build/tests/it/clangd_check_parity.rs @@ -22,7 +22,7 @@ //! on `swap_ino_entries_for_raw` for why the generated entry is removed, //! not duplicated). //! -//! Run locally: `soldr cargo test -p fbuild-build --test clangd_check_parity -- --ignored --nocapture` +//! Run locally: `soldr cargo test -p fbuild-build --test it clangd_check_parity:: -- --ignored --nocapture` //! (see docs/DEVELOPMENT.md → "clangd --check parity harness"). use std::path::{Path, PathBuf}; diff --git a/crates/fbuild-build/tests/it/compile_many_stage2_perf.rs b/crates/fbuild-build/tests/it/compile_many_stage2_perf.rs index ce3d0887..8ab42cf4 100644 --- a/crates/fbuild-build/tests/it/compile_many_stage2_perf.rs +++ b/crates/fbuild-build/tests/it/compile_many_stage2_perf.rs @@ -20,7 +20,7 @@ //! the first run (cached afterward). Run with: //! //! ```bash -//! soldr cargo test -p fbuild-build --test compile_many_stage2_perf \ +//! soldr cargo test -p fbuild-build --test it compile_many_stage2_perf:: \ //! -- --ignored //! ``` diff --git a/crates/fbuild-build/tests/it/esp32_build.rs b/crates/fbuild-build/tests/it/esp32_build.rs index 6bc3174d..6f22044e 100644 --- a/crates/fbuild-build/tests/it/esp32_build.rs +++ b/crates/fbuild-build/tests/it/esp32_build.rs @@ -3,7 +3,7 @@ //! Downloads esp32 toolchain + framework (cached after first run), compiles a //! minimal blink sketch, and validates the output firmware.bin. //! -//! Run with: `soldr cargo test -p fbuild-build --test esp32_build -- --ignored` +//! Run with: `soldr cargo test -p fbuild-build --test it esp32_build:: -- --ignored` use std::fs; use std::path::PathBuf; diff --git a/crates/fbuild-build/tests/it/esp32s3_size_parity.rs b/crates/fbuild-build/tests/it/esp32s3_size_parity.rs index 50b9a021..8f812d53 100644 --- a/crates/fbuild-build/tests/it/esp32s3_size_parity.rs +++ b/crates/fbuild-build/tests/it/esp32s3_size_parity.rs @@ -10,7 +10,7 @@ //! both tools. `.github/workflows/esp32s3-size-parity.yml` runs it once a day: //! //! ```text -//! soldr cargo test -p fbuild-build --test esp32s3_size_parity -- --ignored --nocapture +//! soldr cargo test -p fbuild-build --test it esp32s3_size_parity:: -- --ignored --nocapture //! ``` use std::fs; diff --git a/crates/fbuild-build/tests/it/flag_escaping_lint.rs b/crates/fbuild-build/tests/it/flag_escaping_lint.rs index 833c8e1c..70cf8382 100644 --- a/crates/fbuild-build/tests/it/flag_escaping_lint.rs +++ b/crates/fbuild-build/tests/it/flag_escaping_lint.rs @@ -9,7 +9,7 @@ //! "stray '\\' in program" errors because the backslash is a literal character, //! not a shell escape. `prepare_flags_for_exec` strips `\"` → `"`. //! -//! Run with: `soldr cargo test -p fbuild-build --test flag_escaping_lint` +//! Run with: `soldr cargo test -p fbuild-build --test it flag_escaping_lint::` use std::fs; use std::path::{Path, PathBuf}; diff --git a/crates/fbuild-build/tests/it/nxplpc_build_flags.rs b/crates/fbuild-build/tests/it/nxplpc_build_flags.rs index 6bf9b097..f1b80807 100644 --- a/crates/fbuild-build/tests/it/nxplpc_build_flags.rs +++ b/crates/fbuild-build/tests/it/nxplpc_build_flags.rs @@ -17,7 +17,7 @@ //! fix is wired end-to-end. //! //! Run with: -//! `soldr cargo test -p fbuild-build --test nxplpc_build_flags -- --ignored` +//! `soldr cargo test -p fbuild-build --test it nxplpc_build_flags:: -- --ignored` //! //! Marked `#[ignore]` because it downloads the ARM GCC toolchain plus the //! vendored ArduinoCore-LPC8xx framework and performs a real firmware diff --git a/crates/fbuild-build/tests/it/stm32_acceptance.rs b/crates/fbuild-build/tests/it/stm32_acceptance.rs index 59efc0d4..4a754d14 100644 --- a/crates/fbuild-build/tests/it/stm32_acceptance.rs +++ b/crates/fbuild-build/tests/it/stm32_acceptance.rs @@ -6,7 +6,7 @@ //! by fbuild's library-selection layer. //! //! Run with: -//! `soldr cargo test -p fbuild-build --test stm32_acceptance -- --ignored` +//! `soldr cargo test -p fbuild-build --test it stm32_acceptance:: -- --ignored` //! //! Marked `#[ignore]` because it downloads the ARM GCC toolchain plus the //! STM32duino cores (cached after first run) and performs a full firmware diff --git a/crates/fbuild-build/tests/it/teensy30_acceptance.rs b/crates/fbuild-build/tests/it/teensy30_acceptance.rs index 8b9f5039..e35cee89 100644 --- a/crates/fbuild-build/tests/it/teensy30_acceptance.rs +++ b/crates/fbuild-build/tests/it/teensy30_acceptance.rs @@ -21,7 +21,7 @@ //! `compile_commands.json` or `.fbuild/` is ever left behind in the repo. //! //! Run with: -//! `soldr cargo test -p fbuild-build --test teensy30_acceptance -- --ignored` +//! `soldr cargo test -p fbuild-build --test it teensy30_acceptance:: -- --ignored` //! //! Marked `#[ignore]` because it downloads Teensyduino + arm-gcc on the //! first run (cached after) and performs a full firmware build — too diff --git a/crates/fbuild-build/tests/it/teensy41_acceptance.rs b/crates/fbuild-build/tests/it/teensy41_acceptance.rs index 91b17dee..7b130bc0 100644 --- a/crates/fbuild-build/tests/it/teensy41_acceptance.rs +++ b/crates/fbuild-build/tests/it/teensy41_acceptance.rs @@ -25,8 +25,8 @@ //! and no scratch artifacts land in the repo. //! //! Run with: -//! `soldr cargo test -p fbuild-build --release --test teensy41_acceptance \ -//! -- --ignored teensy41_cold_library_selection_meets_205_ac6 --nocapture` +//! `soldr cargo test -p fbuild-build --release --test it \ +//! -- --ignored teensy41_acceptance::teensy41_cold_library_selection_meets_205_ac6 --nocapture` //! //! Marked `#[ignore]` because it downloads Teensyduino on the first run //! (cached after) — too heavy for default `cargo test`. diff --git a/crates/fbuild-build/tests/it/teensy_build.rs b/crates/fbuild-build/tests/it/teensy_build.rs index 084db350..7777ebf9 100644 --- a/crates/fbuild-build/tests/it/teensy_build.rs +++ b/crates/fbuild-build/tests/it/teensy_build.rs @@ -3,7 +3,7 @@ //! Downloads arm-gcc + Teensy cores (cached after first run), compiles a //! minimal blink sketch, and validates the output firmware.hex. //! -//! Run with: `soldr cargo test -p fbuild-build --test teensy_build -- --ignored` +//! Run with: `soldr cargo test -p fbuild-build --test it teensy_build:: -- --ignored` use std::fs; use std::path::{Path, PathBuf}; diff --git a/crates/fbuild-build/tests/it/teensylc_acceptance.rs b/crates/fbuild-build/tests/it/teensylc_acceptance.rs index 72a6d7a3..0163301a 100644 --- a/crates/fbuild-build/tests/it/teensylc_acceptance.rs +++ b/crates/fbuild-build/tests/it/teensylc_acceptance.rs @@ -14,7 +14,7 @@ //! //! This test downloads Teensyduino + arm-gcc on the first run and is //! therefore CI-only — it is gated behind `#[ignore]` and runs via -//! `soldr cargo test -p fbuild-build --test teensylc_acceptance -- --ignored`. +//! `soldr cargo test -p fbuild-build --test it teensylc_acceptance:: -- --ignored`. use std::path::PathBuf; diff --git a/crates/fbuild-daemon/tests/it/process_containment.rs b/crates/fbuild-daemon/tests/it/process_containment.rs index 1dc6b5b1..386ecc5d 100644 --- a/crates/fbuild-daemon/tests/it/process_containment.rs +++ b/crates/fbuild-daemon/tests/it/process_containment.rs @@ -25,7 +25,7 @@ //! //! Run explicitly with: //! ```bash -//! soldr cargo test -p fbuild-daemon --test process_containment -- --ignored +//! soldr cargo test -p fbuild-daemon --test it process_containment:: -- --ignored //! ``` use std::io::{BufRead, BufReader}; diff --git a/crates/fbuild-toolchain/src/lnk/resolver.rs b/crates/fbuild-toolchain/src/lnk/resolver.rs index 5f51dcbe..34a584d4 100644 --- a/crates/fbuild-toolchain/src/lnk/resolver.rs +++ b/crates/fbuild-toolchain/src/lnk/resolver.rs @@ -308,19 +308,49 @@ mod tests { /// Serve a single `404` so a refetch fails immediately: 4xx is not /// retried, whereas an unresolvable host is retried with the production /// 1+2+4+8 s backoff (15 s of test time for no extra coverage). - fn serve_one_404() -> String { + /// + /// Returns the URL, a receiver that fires once a request has been + /// accepted (proof the refetch reached the network), and the server + /// thread. Accept and socket I/O are bounded so joining cannot hang. + fn serve_one_404() -> ( + String, + std::sync::mpsc::Receiver<()>, + std::thread::JoinHandle<()>, + ) { + use std::time::{Duration, Instant}; let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap(); + listener.set_nonblocking(true).unwrap(); let port = listener.local_addr().unwrap().port(); - std::thread::spawn(move || { - if let Ok((mut stream, _)) = listener.accept() { - let mut buf = [0u8; 1024]; - let _ = std::io::Read::read(&mut stream, &mut buf); - let _ = stream.write_all( - b"HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\nConnection: close\r\n\r\n", - ); - } + let (accepted_tx, accepted_rx) = std::sync::mpsc::channel(); + let server = std::thread::spawn(move || { + let deadline = Instant::now() + Duration::from_secs(10); + let mut stream = loop { + match listener.accept() { + Ok((stream, _)) => break stream, + Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => { + if Instant::now() >= deadline { + return; + } + std::thread::sleep(Duration::from_millis(5)); + } + Err(_) => return, + } + }; + let _ = accepted_tx.send(()); + let _ = stream.set_nonblocking(false); + let _ = stream.set_read_timeout(Some(Duration::from_secs(5))); + let _ = stream.set_write_timeout(Some(Duration::from_secs(5))); + let mut buf = [0u8; 1024]; + let _ = std::io::Read::read(&mut stream, &mut buf); + let _ = stream.write_all( + b"HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\nConnection: close\r\n\r\n", + ); }); - format!("http://127.0.0.1:{port}/corrupt.bin") + ( + format!("http://127.0.0.1:{port}/corrupt.bin"), + accepted_rx, + server, + ) } /// Cache-hit but stored sha doesn't match content → resolve must fall @@ -329,7 +359,7 @@ mod tests { #[test] fn resolve_rejects_corrupt_cache_entry() { let (_tmp, cache) = open_test_cache(); - let url_owned = serve_one_404(); + let (url_owned, accepted, server) = serve_one_404(); let url = url_owned.as_str(); let claimed_sha = sha256_of(b"good content"); // what .lnk says let archive_dir = cache.archive_dir(Kind::LnkBlobs, url, &claimed_sha); @@ -356,9 +386,14 @@ mod tests { extract: super::super::ExtractMode::File, }; - // Should attempt to refetch (and fail because URL is bogus). - // The interesting assertion: it didn't silently return the corrupt blob. + // Should refetch (and fail on the 404). The interesting assertions: + // it didn't silently return the corrupt blob, and it really went back + // to the network rather than failing some other way. let result = resolve(&lnk, &cache); assert!(result.is_err(), "expected refetch failure, got Ok"); + accepted + .recv_timeout(std::time::Duration::from_secs(5)) + .expect("resolve should have refetched from the server"); + server.join().unwrap(); } } diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index ca3f1a89..93b98238 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -95,7 +95,7 @@ since the raw-`.ino` entry carries the same flags the generated `.ino.cpp` entry would have carried. The harness lives at -`crates/fbuild-build/tests/clangd_check_parity.rs` and is `#[ignore]`d +`crates/fbuild-build/tests/it/clangd_check_parity.rs` and is `#[ignore]`d (needs a real AVR toolchain — commonly already cached from other AVR tests — and `clangd` on `PATH`, which fbuild does not manage/download itself; Zed manages its own clangd, so fbuild deliberately doesn't duplicate that). @@ -109,7 +109,7 @@ To run it locally: 2. Run the ignored test by name: ```bash - soldr cargo test -p fbuild-build --test clangd_check_parity -- --ignored --nocapture + soldr cargo test -p fbuild-build --test it clangd_check_parity:: -- --ignored --nocapture ``` If `clangd` isn't found on `PATH`, the test prints a `SKIP:` message and diff --git a/dylints/ban_bare_reqwest/src/lib.rs b/dylints/ban_bare_reqwest/src/lib.rs index f031be2f..9218abcf 100644 --- a/dylints/ban_bare_reqwest/src/lib.rs +++ b/dylints/ban_bare_reqwest/src/lib.rs @@ -194,7 +194,7 @@ mod tests { "crates/fbuild-cli/src/cli/port_scan.rs" )); assert!(!in_production_scope( - "crates/fbuild-daemon/tests/test_emu_endpoint.rs" + "crates/fbuild-daemon/tests/it/test_emu_endpoint.rs" )); } } diff --git a/dylints/ban_std_pathbuf/src/allowlist.txt b/dylints/ban_std_pathbuf/src/allowlist.txt index 150c0ffb..5be64224 100644 --- a/dylints/ban_std_pathbuf/src/allowlist.txt +++ b/dylints/ban_std_pathbuf/src/allowlist.txt @@ -92,16 +92,16 @@ crates/fbuild-build-arm/src/teensy/teensy_linker.rs crates/fbuild-build-engine/src/zccache.rs crates/fbuild-build-engine/src/zccache_embedded.rs crates/fbuild-build/tests/avr_build.rs -crates/fbuild-build/tests/cache_survives_tar_extract.rs -crates/fbuild-build/tests/compile_many_stage2_perf.rs -crates/fbuild-build/tests/compile_many_two_stage.rs -crates/fbuild-build/tests/esp32_build.rs -crates/fbuild-build/tests/flag_escaping_lint.rs -crates/fbuild-build/tests/nxplpc_build_flags.rs -crates/fbuild-build/tests/nxplpc_core_compile_commands.rs -crates/fbuild-build/tests/stm32_acceptance.rs -crates/fbuild-build/tests/teensy_build.rs -crates/fbuild-build/tests/teensylc_acceptance.rs +crates/fbuild-build/tests/it/cache_survives_tar_extract.rs +crates/fbuild-build/tests/it/compile_many_stage2_perf.rs +crates/fbuild-build/tests/it/compile_many_two_stage.rs +crates/fbuild-build/tests/it/esp32_build.rs +crates/fbuild-build/tests/it/flag_escaping_lint.rs +crates/fbuild-build/tests/it/nxplpc_build_flags.rs +crates/fbuild-build/tests/it/nxplpc_core_compile_commands.rs +crates/fbuild-build/tests/it/stm32_acceptance.rs +crates/fbuild-build/tests/it/teensy_build.rs +crates/fbuild-build/tests/it/teensylc_acceptance.rs crates/fbuild-cli/src/cli/bloat_lookup.rs crates/fbuild-cli/src/cli/clang_tools.rs crates/fbuild-cli/src/cli/compile_many.rs @@ -248,4 +248,4 @@ crates/fbuild-cli/src/cli/usb_recovery.rs # installed toolchains", so neither CI nor a normal `bash test` run can # validate such a change — allowlisted rather than migrated blind. # Revisit together with FastLED/fbuild#1076's parity work. -crates/fbuild-build/tests/clangd_check_parity.rs +crates/fbuild-build/tests/it/clangd_check_parity.rs diff --git a/tests/platform/lpc845_build_flags/README.md b/tests/platform/lpc845_build_flags/README.md index ec9b4e75..9711247a 100644 --- a/tests/platform/lpc845_build_flags/README.md +++ b/tests/platform/lpc845_build_flags/README.md @@ -17,12 +17,12 @@ Build succeeds → orchestrator now propagates `build_flags` to libraries. ## Driver -The driver lives at `crates/fbuild-build/tests/nxplpc_build_flags.rs` and is +The driver lives at `crates/fbuild-build/tests/it/nxplpc_build_flags.rs` and is marked `#[ignore]` because it downloads the ARM GCC toolchain plus the vendored ArduinoCore-LPC8xx and performs a real link. Invoke with: ``` -soldr cargo test -p fbuild-build --test nxplpc_build_flags -- --ignored +soldr cargo test -p fbuild-build --test it nxplpc_build_flags:: -- --ignored ``` See also: `tests/platform/lpc845/` (the pre-existing Blink fixture, no From d3d728eb8e003a577d20ecca1af2e6507370805d Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Mon, 28 Sep 2026 23:18:45 -0700 Subject: [PATCH 08/12] perf(ci): drop the redundant cargo check before clippy clippy --workspace --all-targets type-checks the same targets, so the preceding cargo check only repeated work. Measured locally with fresh target dirs and warm zccache: check+clippy 194.5s vs clippy alone 106.4s (-45%). Applies to the Ubuntu and Windows gates. --- .github/workflows/check-ubuntu.yml | 6 ++++-- .github/workflows/check-windows.yml | 5 ++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check-ubuntu.yml b/.github/workflows/check-ubuntu.yml index 2ef2ed0b..b3361d68 100644 --- a/.github/workflows/check-ubuntu.yml +++ b/.github/workflows/check-ubuntu.yml @@ -59,8 +59,10 @@ jobs: # runaway caches. Hard cap stays at the action default (6 GiB). cache-payload-warn-bytes: 2GiB - - name: Check - run: soldr cargo check --workspace --all-targets + # No separate `cargo check`: clippy type-checks the same + # `--workspace --all-targets` set, so a prior check only re-did that work. + # Measured locally (fresh target dir, warm zccache): check+clippy 194s + # vs clippy alone 106s. - name: Clippy run: soldr cargo clippy --workspace --all-targets -- -D warnings # Both guards are stdlib-only. `--no-project` skips building the fbuild diff --git a/.github/workflows/check-windows.yml b/.github/workflows/check-windows.yml index 01e0f225..baa9a9e1 100644 --- a/.github/workflows/check-windows.yml +++ b/.github/workflows/check-windows.yml @@ -58,9 +58,8 @@ jobs: version="$(soldr --version)" echo "$version" [[ "$version" == soldr\ * ]] - - name: Check - shell: bash - run: soldr cargo check --workspace --all-targets + # No separate `cargo check`: clippy type-checks the same + # `--workspace --all-targets` set (see check-ubuntu.yml for the timing). - name: Clippy shell: bash run: soldr cargo clippy --workspace --all-targets -- -D warnings From caf846c56c13b0c9a5fbaca35a1049d01f545b64 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Mon, 28 Sep 2026 23:35:54 -0700 Subject: [PATCH 09/12] perf(ci): drop the rustdoc build lane Every workspace crate is publish = false and none declares [package.metadata.docs.rs], so no rendered docs are published and the Documentation job (median ~5m22s on every PR push and main merge) built HTML nobody consumed. Doctests still run in cargo test --workspace. See zackees/ci.yml#116. --- .github/workflows/README.md | 2 +- .github/workflows/ci-full.yml | 11 ++----- .github/workflows/docs.yml | 57 --------------------------------- ci/render_workflows.py | 6 ++-- ci/test_fractional_workflows.py | 8 ++--- 5 files changed, 9 insertions(+), 75 deletions(-) delete mode 100644 .github/workflows/docs.yml diff --git a/.github/workflows/README.md b/.github/workflows/README.md index f9592f29..96078b1c 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -41,7 +41,7 @@ CI/CD workflows for the fbuild project, covering lint, test, documentation, and - **`check-{ubuntu,windows}.yml`** -- Reusable Clippy + tests per platform (no macOS runner: macOS binaries are cross-built from Linux in the release matrix, see below) -- **`fmt.yml`** -- Rustfmt check | **`docs.yml`** -- Doc build with `-D warnings` +- **`fmt.yml`** -- Rustfmt check - **`msrv.yml`** -- MSRV 1.95.0 verification | **`validate-boards.yml`** -- Board JSON validation - **`platform-boundary-research.yml`** -- Windows/Linux reconciliation of the #1307 research inventory and RED fixture - **`loc-gate.yml`** -- Reject `.rs` files over 1000 LOC | **`lint-subprocess.yml`** -- Forbid direct subprocess spawns diff --git a/.github/workflows/ci-full.yml b/.github/workflows/ci-full.yml index 5f1465a0..1206d77d 100644 --- a/.github/workflows/ci-full.yml +++ b/.github/workflows/ci-full.yml @@ -101,12 +101,6 @@ jobs: uses: ./.github/workflows/fmt.yml with: ref: ${{ needs.verify.outputs.candidate_sha }} - docs: - if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'ci-full') - needs: verify - uses: ./.github/workflows/docs.yml - with: - ref: ${{ needs.verify.outputs.candidate_sha }} msrv: if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'ci-full') needs: verify @@ -713,7 +707,7 @@ jobs: coverage: name: Full coverage if: always() - needs: [verify, boards, linux, windows, macos, dylint, acceptance, bench, qemu, fmt, docs, msrv, validate_boards, crate_gate] + needs: [verify, boards, linux, windows, macos, dylint, acceptance, bench, qemu, fmt, msrv, validate_boards, crate_gate] runs-on: ubuntu-latest outputs: complete: ${{ steps.complete.outputs.complete }} @@ -732,7 +726,6 @@ jobs: BENCH: ${{ needs.bench.result }} QEMU: ${{ needs.qemu.result }} FMT: ${{ needs.fmt.result }} - DOCS: ${{ needs.docs.result }} MSRV: ${{ needs.msrv.result }} VALIDATE_BOARDS: ${{ needs.validate_boards.result }} CRATE_GATE: ${{ needs.crate_gate.result }} @@ -742,7 +735,7 @@ jobs: echo 'Optional tier is not selected on this PR; coverage is incomplete' >&2 exit 1 fi - for result in "$VERIFY" "$BOARDS" "$LINUX" "$WINDOWS" "$MACOS" "$DYLINT" "$ACCEPTANCE" "$BENCH" "$QEMU" "$FMT" "$DOCS" "$MSRV" "$VALIDATE_BOARDS" "$CRATE_GATE"; do + for result in "$VERIFY" "$BOARDS" "$LINUX" "$WINDOWS" "$MACOS" "$DYLINT" "$ACCEPTANCE" "$BENCH" "$QEMU" "$FMT" "$MSRV" "$VALIDATE_BOARDS" "$CRATE_GATE"; do if [ "$result" != success ]; then echo "coverage incomplete: $result" >&2 exit 1 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index c14bd688..00000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Documentation - -on: - workflow_dispatch: {} - workflow_call: - inputs: - ref: - type: string - required: false - default: "" - push: - branches: [main] - pull_request: - branches: [main] - -# Auto-cancel superseded PR runs: pushing again to a feature branch -# supersedes the in-flight run instead of queueing behind it. Non-PR -# events key on run_id so each gets its own group -- a shared group keeps -# only ONE pending run, which would silently drop queued main SHAs. -concurrency: - group: docs.yml-${{ inputs.ref != '' && github.run_id || (github.event_name == 'pull_request' && github.ref || github.run_id) }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - -env: - FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" - -jobs: - docs: - name: Documentation - runs-on: ubuntu-latest - timeout-minutes: 15 - env: - RUSTDOCFLAGS: "-D warnings" - steps: - - uses: actions/checkout@v6 - with: - ref: ${{ inputs.ref }} - - name: Setup soldr - id: setup-soldr - uses: zackees/setup-soldr@v0 - with: - cache: true - build-cache: true - target-cache: true - prebuild-deps: none - # Opt out of the implicit `SOLDR_LINKER=fast` injection so cargo / - # rust-toolchain.toml stays in charge. Silences the routine - # "defaulting SOLDR_LINKER=fast" warning (issue #400 / - # setup-soldr#377). - linker: platform-default - # Realistic zccache payload for the doc build can exceed the - # 512 MiB action default (issue #400). Raise the soft warn - # threshold; hard cap stays at the action default (6 GiB). - cache-payload-warn-bytes: 2GiB - - - name: Build docs - run: soldr cargo doc --workspace --no-deps diff --git a/ci/render_workflows.py b/ci/render_workflows.py index 0b52e2fa..20aa591d 100644 --- a/ci/render_workflows.py +++ b/ci/render_workflows.py @@ -374,7 +374,6 @@ def render_ci(boards: list[dict], tier: str, families: dict) -> str: + f" ref: {verified_ref}\n" for job, workflow in ( ("fmt", "fmt.yml"), - ("docs", "docs.yml"), ("msrv", "msrv.yml"), ("validate_boards", "validate-boards.yml"), ("crate_gate", "crate-gate.yml"), @@ -421,7 +420,7 @@ def render_ci(boards: list[dict], tier: str, families: dict) -> str: " coverage:\n" + (" name: Full coverage\n" if full else " name: ci-test coverage\n") + " if: always()\n" - + (" needs: [verify, boards, linux, windows, macos, dylint, acceptance, bench, qemu, fmt, docs, msrv, validate_boards, crate_gate]\n" if full else " needs: [verify, boards, linux]\n") + + (" needs: [verify, boards, linux, windows, macos, dylint, acceptance, bench, qemu, fmt, msrv, validate_boards, crate_gate]\n" if full else " needs: [verify, boards, linux]\n") + " runs-on: ubuntu-latest\n" + " outputs:\n" + " complete: ${{ steps.complete.outputs.complete }}\n" @@ -440,7 +439,6 @@ def render_ci(boards: list[dict], tier: str, families: dict) -> str: " BENCH: ${{ needs.bench.result }}\n" " QEMU: ${{ needs.qemu.result }}\n" " FMT: ${{ needs.fmt.result }}\n" - " DOCS: ${{ needs.docs.result }}\n" " MSRV: ${{ needs.msrv.result }}\n" " VALIDATE_BOARDS: ${{ needs.validate_boards.result }}\n" " CRATE_GATE: ${{ needs.crate_gate.result }}\n" if full else "") @@ -450,7 +448,7 @@ def render_ci(boards: list[dict], tier: str, families: dict) -> str: + " echo 'Optional tier is not selected on this PR; coverage is incomplete' >&2\n" + " exit 1\n" + " fi\n" - + (" for result in \"$VERIFY\" \"$BOARDS\" \"$LINUX\" \"$WINDOWS\" \"$MACOS\" \"$DYLINT\" \"$ACCEPTANCE\" \"$BENCH\" \"$QEMU\" \"$FMT\" \"$DOCS\" \"$MSRV\" \"$VALIDATE_BOARDS\" \"$CRATE_GATE\"; do\n" if full else " for result in \"$VERIFY\" \"$BOARDS\" \"$LINUX\"; do\n") + + (" for result in \"$VERIFY\" \"$BOARDS\" \"$LINUX\" \"$WINDOWS\" \"$MACOS\" \"$DYLINT\" \"$ACCEPTANCE\" \"$BENCH\" \"$QEMU\" \"$FMT\" \"$MSRV\" \"$VALIDATE_BOARDS\" \"$CRATE_GATE\"; do\n" if full else " for result in \"$VERIFY\" \"$BOARDS\" \"$LINUX\"; do\n") + " if [ \"$result\" != success ]; then\n" + " echo \"coverage incomplete: $result\" >&2\n" + " exit 1\n" diff --git a/ci/test_fractional_workflows.py b/ci/test_fractional_workflows.py index 8513857a..9bd03a77 100644 --- a/ci/test_fractional_workflows.py +++ b/ci/test_fractional_workflows.py @@ -108,7 +108,7 @@ def test_full_matrix_matches_every_supported_board(self): self.assertNotIn("pull_request", self.load(workflow)[True]) self.assertEqual("${{ needs.verify.outputs.candidate_sha }}", full["jobs"]["boards"]["with"]["checkout_ref"]) for job, workflow_name in ( - ("fmt", "fmt.yml"), ("docs", "docs.yml"), ("msrv", "msrv.yml"), + ("fmt", "fmt.yml"), ("msrv", "msrv.yml"), ("validate_boards", "validate-boards.yml"), ("crate_gate", "crate-gate.yml"), ): self.assertEqual(f"./.github/workflows/{workflow_name}", full["jobs"][job]["uses"]) @@ -230,16 +230,16 @@ def test_selected_coverage_requires_every_requested_tier(self): def test_full_coverage_sentinel_and_release_gate(self): full = self.load("ci-full.yml") self.assertEqual( - {"verify", "boards", "linux", "windows", "macos", "dylint", "acceptance", "bench", "qemu", "fmt", "docs", "msrv", "validate_boards", "crate_gate"}, + {"verify", "boards", "linux", "windows", "macos", "dylint", "acceptance", "bench", "qemu", "fmt", "msrv", "validate_boards", "crate_gate"}, set(full["jobs"]["coverage"]["needs"]), ) self.assertEqual("${{ jobs.coverage.outputs.complete }}", full[True]["workflow_call"]["outputs"]["coverage"]["value"]) script = full["jobs"]["coverage"]["steps"][0]["run"] env = {**os.environ, "EVENT_NAME": "workflow_call", "LABEL_PRESENT": "false"} - env.update({key: "success" for key in ("VERIFY", "BOARDS", "LINUX", "WINDOWS", "MACOS", "DYLINT", "ACCEPTANCE", "BENCH", "QEMU", "FMT", "DOCS", "MSRV", "VALIDATE_BOARDS", "CRATE_GATE")}) + env.update({key: "success" for key in ("VERIFY", "BOARDS", "LINUX", "WINDOWS", "MACOS", "DYLINT", "ACCEPTANCE", "BENCH", "QEMU", "FMT", "MSRV", "VALIDATE_BOARDS", "CRATE_GATE")}) with tempfile.NamedTemporaryFile() as output: env["GITHUB_OUTPUT"] = output.name - for missing in ("FMT", "DOCS", "MSRV", "VALIDATE_BOARDS", "CRATE_GATE"): + for missing in ("FMT", "MSRV", "VALIDATE_BOARDS", "CRATE_GATE"): with self.subTest(missing=missing): result = subprocess.run(["bash", "-e", "-c", script], env={**env, missing: "skipped"}, capture_output=True, text=True) self.assertNotEqual(0, result.returncode) From 39f31794273a0052f179578e2fb9813f45d9b1b1 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Mon, 28 Sep 2026 23:50:08 -0700 Subject: [PATCH 10/12] fix(ci): re-extract registry crates whose packaged template.tar was not restored setup-soldr's restored cargo-registry sources lack dylint_internal's template.tar, so any change under dylints/ (lint libraries rebuild on a dylint-cache miss) failed with 'couldn't read template.tar'. Delete the incomplete extraction so cargo re-unpacks it from the .crate. --- .github/workflows/dylint.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/dylint.yml b/.github/workflows/dylint.yml index 291a0083..98c45923 100644 --- a/.github/workflows/dylint.yml +++ b/.github/workflows/dylint.yml @@ -107,6 +107,20 @@ jobs: # (issue #400). Raise the soft warn threshold; hard cap stays # at the action default (6 GiB). cache-payload-warn-bytes: 2GiB + # setup-soldr's cargo-registry cache restores extracted crate sources + # without non-source `.tar` payloads, so `dylint_internal`'s + # `include_bytes!("template.tar")` fails whenever the lint libraries + # rebuild (any change under dylints/). Drop such incomplete extractions + # so cargo re-unpacks them from the `.crate` archive (or re-downloads). + - name: Repair registry sources missing packaged files + run: | + for src in "$HOME"/.cargo/registry/src/*/dylint_internal-*; do + [ -d "$src" ] || continue + if [ ! -f "$src/template.tar" ]; then + echo "::warning::re-extracting $(basename "$src"): template.tar missing from restored registry cache" + rm -rf "$src" + fi + done - name: Prepare prebuilt Dylint tools and driver timeout-minutes: 10 run: | From e1c0f92f5bba14c5158050beabca372bbbef1f36 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Tue, 29 Sep 2026 00:04:20 -0700 Subject: [PATCH 11/12] perf(ci): drop the MSRV job; the pinned toolchain is the MSRV rust-toolchain.toml pins 1.95.0 and Cargo.toml rust-version is 1.95.0 (check_rust_toolchain_pins.py enforces the equality), so msrv.yml's cargo check --workspace on 1.95.0 repeated what every lane already compiles, and the Linux gate's clippy --all-targets covers more. Saved ~5m37s of runner time per PR push. --- .github/workflows/README.md | 2 +- .github/workflows/ci-full.yml | 11 ++----- .github/workflows/msrv.yml | 56 --------------------------------- ci/check_rust_toolchain_pins.py | 8 +---- ci/render_workflows.py | 6 ++-- ci/test_fractional_workflows.py | 8 ++--- 6 files changed, 10 insertions(+), 81 deletions(-) delete mode 100644 .github/workflows/msrv.yml diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 96078b1c..0005a132 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -42,7 +42,7 @@ CI/CD workflows for the fbuild project, covering lint, test, documentation, and - **`check-{ubuntu,windows}.yml`** -- Reusable Clippy + tests per platform (no macOS runner: macOS binaries are cross-built from Linux in the release matrix, see below) - **`fmt.yml`** -- Rustfmt check -- **`msrv.yml`** -- MSRV 1.95.0 verification | **`validate-boards.yml`** -- Board JSON validation +- MSRV 1.95.0 is the pinned toolchain (`rust-toolchain.toml` = `rust-version`, enforced by `ci/check_rust_toolchain_pins.py`), so every lane already compiles on it and there is no separate MSRV job | **`validate-boards.yml`** -- Board JSON validation - **`platform-boundary-research.yml`** -- Windows/Linux reconciliation of the #1307 research inventory and RED fixture - **`loc-gate.yml`** -- Reject `.rs` files over 1000 LOC | **`lint-subprocess.yml`** -- Forbid direct subprocess spawns - **`crate-gate.yml`** -- Reject new workspace crates (monocrate policy, `ci/check_workspace_crates.py`) diff --git a/.github/workflows/ci-full.yml b/.github/workflows/ci-full.yml index 1206d77d..3516db06 100644 --- a/.github/workflows/ci-full.yml +++ b/.github/workflows/ci-full.yml @@ -101,12 +101,6 @@ jobs: uses: ./.github/workflows/fmt.yml with: ref: ${{ needs.verify.outputs.candidate_sha }} - msrv: - if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'ci-full') - needs: verify - uses: ./.github/workflows/msrv.yml - with: - ref: ${{ needs.verify.outputs.candidate_sha }} validate_boards: if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'ci-full') needs: verify @@ -707,7 +701,7 @@ jobs: coverage: name: Full coverage if: always() - needs: [verify, boards, linux, windows, macos, dylint, acceptance, bench, qemu, fmt, msrv, validate_boards, crate_gate] + needs: [verify, boards, linux, windows, macos, dylint, acceptance, bench, qemu, fmt, validate_boards, crate_gate] runs-on: ubuntu-latest outputs: complete: ${{ steps.complete.outputs.complete }} @@ -726,7 +720,6 @@ jobs: BENCH: ${{ needs.bench.result }} QEMU: ${{ needs.qemu.result }} FMT: ${{ needs.fmt.result }} - MSRV: ${{ needs.msrv.result }} VALIDATE_BOARDS: ${{ needs.validate_boards.result }} CRATE_GATE: ${{ needs.crate_gate.result }} run: | @@ -735,7 +728,7 @@ jobs: echo 'Optional tier is not selected on this PR; coverage is incomplete' >&2 exit 1 fi - for result in "$VERIFY" "$BOARDS" "$LINUX" "$WINDOWS" "$MACOS" "$DYLINT" "$ACCEPTANCE" "$BENCH" "$QEMU" "$FMT" "$MSRV" "$VALIDATE_BOARDS" "$CRATE_GATE"; do + for result in "$VERIFY" "$BOARDS" "$LINUX" "$WINDOWS" "$MACOS" "$DYLINT" "$ACCEPTANCE" "$BENCH" "$QEMU" "$FMT" "$VALIDATE_BOARDS" "$CRATE_GATE"; do if [ "$result" != success ]; then echo "coverage incomplete: $result" >&2 exit 1 diff --git a/.github/workflows/msrv.yml b/.github/workflows/msrv.yml deleted file mode 100644 index 12b1dccb..00000000 --- a/.github/workflows/msrv.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Min Rust Version (1.95.0) - -on: - workflow_dispatch: {} - workflow_call: - inputs: - ref: - type: string - required: false - default: "" - push: - branches: [main] - pull_request: - branches: [main] - -# Auto-cancel superseded PR runs: pushing again to a feature branch -# supersedes the in-flight run instead of queueing behind it. Non-PR -# events key on run_id so each gets its own group -- a shared group keeps -# only ONE pending run, which would silently drop queued main SHAs. -concurrency: - group: msrv.yml-${{ inputs.ref != '' && github.run_id || (github.event_name == 'pull_request' && github.ref || github.run_id) }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - -env: - FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" - -jobs: - msrv: - name: Min Rust Version (1.95.0) - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - uses: actions/checkout@v6 - with: - ref: ${{ inputs.ref }} - - name: Setup soldr - id: setup-soldr - uses: zackees/setup-soldr@v0 - with: - cache: true - build-cache: true - target-cache: true - prebuild-deps: none - toolchain: 1.95.0 - # Opt out of the implicit `SOLDR_LINKER=fast` injection so cargo / - # rust-toolchain.toml stays in charge. Silences the routine - # "defaulting SOLDR_LINKER=fast" warning (issue #400 / - # setup-soldr#377). - linker: platform-default - # Realistic zccache payload for the workspace check job is - # ~1.5–2 GiB (issue #400). Raise the soft warn threshold above - # the steady-state size. Hard cap stays at 6 GiB. - cache-payload-warn-bytes: 2GiB - - - name: Check MSRV - run: soldr cargo check --workspace diff --git a/ci/check_rust_toolchain_pins.py b/ci/check_rust_toolchain_pins.py index 305bffef..4c1498d6 100644 --- a/ci/check_rust_toolchain_pins.py +++ b/ci/check_rust_toolchain_pins.py @@ -15,7 +15,6 @@ "rust-toolchain.toml", "CLAUDE.md", "docs/DEVELOPMENT.md", - ".github/workflows/msrv.yml", ".github/workflows/fmt.yml", ".github/workflows/dylint.yml", ".github/workflows/template_native_build.yml", @@ -53,11 +52,6 @@ ".clippy.toml": (r'^msrv\s*=\s*"{pin}"$',), "Cargo.toml": (r'^rust-version\s*=\s*"{pin}"$',), "rust-toolchain.toml": (r'^channel\s*=\s*"{pin}"$',), - ".github/workflows/msrv.yml": ( - r"^name: Min Rust Version \({pin}\)$", - r"^\s+name: Min Rust Version \({pin}\)$", - r"^\s+toolchain: {pin}$", - ), ".github/workflows/dylint.yml": (r"^\s+toolchain: {pin}$",), ".github/workflows/platform-boundary-research.yml": (r"^\s+toolchain: {pin}$",), ".github/workflows/template_native_build.yml": ( @@ -65,7 +59,7 @@ r'TOOLCHAIN_DIR="\$RUSTUP_HOME/toolchains/{pin}-', ), ".github/workflows/fmt.yml": (r"pinned {pin}",), - ".github/workflows/README.md": (r"MSRV {pin} verification",), + ".github/workflows/README.md": (r"MSRV {pin} is the pinned toolchain",), "CLAUDE.md": (r"MSRV: {pin} .* Toolchain: {pin} pinned",), "docs/DEVELOPMENT.md": ( r"MSRV: {pin}", diff --git a/ci/render_workflows.py b/ci/render_workflows.py index 20aa591d..f70e7252 100644 --- a/ci/render_workflows.py +++ b/ci/render_workflows.py @@ -374,7 +374,6 @@ def render_ci(boards: list[dict], tier: str, families: dict) -> str: + f" ref: {verified_ref}\n" for job, workflow in ( ("fmt", "fmt.yml"), - ("msrv", "msrv.yml"), ("validate_boards", "validate-boards.yml"), ("crate_gate", "crate-gate.yml"), ) @@ -420,7 +419,7 @@ def render_ci(boards: list[dict], tier: str, families: dict) -> str: " coverage:\n" + (" name: Full coverage\n" if full else " name: ci-test coverage\n") + " if: always()\n" - + (" needs: [verify, boards, linux, windows, macos, dylint, acceptance, bench, qemu, fmt, msrv, validate_boards, crate_gate]\n" if full else " needs: [verify, boards, linux]\n") + + (" needs: [verify, boards, linux, windows, macos, dylint, acceptance, bench, qemu, fmt, validate_boards, crate_gate]\n" if full else " needs: [verify, boards, linux]\n") + " runs-on: ubuntu-latest\n" + " outputs:\n" + " complete: ${{ steps.complete.outputs.complete }}\n" @@ -439,7 +438,6 @@ def render_ci(boards: list[dict], tier: str, families: dict) -> str: " BENCH: ${{ needs.bench.result }}\n" " QEMU: ${{ needs.qemu.result }}\n" " FMT: ${{ needs.fmt.result }}\n" - " MSRV: ${{ needs.msrv.result }}\n" " VALIDATE_BOARDS: ${{ needs.validate_boards.result }}\n" " CRATE_GATE: ${{ needs.crate_gate.result }}\n" if full else "") + " run: |\n" @@ -448,7 +446,7 @@ def render_ci(boards: list[dict], tier: str, families: dict) -> str: + " echo 'Optional tier is not selected on this PR; coverage is incomplete' >&2\n" + " exit 1\n" + " fi\n" - + (" for result in \"$VERIFY\" \"$BOARDS\" \"$LINUX\" \"$WINDOWS\" \"$MACOS\" \"$DYLINT\" \"$ACCEPTANCE\" \"$BENCH\" \"$QEMU\" \"$FMT\" \"$MSRV\" \"$VALIDATE_BOARDS\" \"$CRATE_GATE\"; do\n" if full else " for result in \"$VERIFY\" \"$BOARDS\" \"$LINUX\"; do\n") + + (" for result in \"$VERIFY\" \"$BOARDS\" \"$LINUX\" \"$WINDOWS\" \"$MACOS\" \"$DYLINT\" \"$ACCEPTANCE\" \"$BENCH\" \"$QEMU\" \"$FMT\" \"$VALIDATE_BOARDS\" \"$CRATE_GATE\"; do\n" if full else " for result in \"$VERIFY\" \"$BOARDS\" \"$LINUX\"; do\n") + " if [ \"$result\" != success ]; then\n" + " echo \"coverage incomplete: $result\" >&2\n" + " exit 1\n" diff --git a/ci/test_fractional_workflows.py b/ci/test_fractional_workflows.py index 9bd03a77..18d26571 100644 --- a/ci/test_fractional_workflows.py +++ b/ci/test_fractional_workflows.py @@ -108,7 +108,7 @@ def test_full_matrix_matches_every_supported_board(self): self.assertNotIn("pull_request", self.load(workflow)[True]) self.assertEqual("${{ needs.verify.outputs.candidate_sha }}", full["jobs"]["boards"]["with"]["checkout_ref"]) for job, workflow_name in ( - ("fmt", "fmt.yml"), ("msrv", "msrv.yml"), + ("fmt", "fmt.yml"), ("validate_boards", "validate-boards.yml"), ("crate_gate", "crate-gate.yml"), ): self.assertEqual(f"./.github/workflows/{workflow_name}", full["jobs"][job]["uses"]) @@ -230,16 +230,16 @@ def test_selected_coverage_requires_every_requested_tier(self): def test_full_coverage_sentinel_and_release_gate(self): full = self.load("ci-full.yml") self.assertEqual( - {"verify", "boards", "linux", "windows", "macos", "dylint", "acceptance", "bench", "qemu", "fmt", "msrv", "validate_boards", "crate_gate"}, + {"verify", "boards", "linux", "windows", "macos", "dylint", "acceptance", "bench", "qemu", "fmt", "validate_boards", "crate_gate"}, set(full["jobs"]["coverage"]["needs"]), ) self.assertEqual("${{ jobs.coverage.outputs.complete }}", full[True]["workflow_call"]["outputs"]["coverage"]["value"]) script = full["jobs"]["coverage"]["steps"][0]["run"] env = {**os.environ, "EVENT_NAME": "workflow_call", "LABEL_PRESENT": "false"} - env.update({key: "success" for key in ("VERIFY", "BOARDS", "LINUX", "WINDOWS", "MACOS", "DYLINT", "ACCEPTANCE", "BENCH", "QEMU", "FMT", "MSRV", "VALIDATE_BOARDS", "CRATE_GATE")}) + env.update({key: "success" for key in ("VERIFY", "BOARDS", "LINUX", "WINDOWS", "MACOS", "DYLINT", "ACCEPTANCE", "BENCH", "QEMU", "FMT", "VALIDATE_BOARDS", "CRATE_GATE")}) with tempfile.NamedTemporaryFile() as output: env["GITHUB_OUTPUT"] = output.name - for missing in ("FMT", "MSRV", "VALIDATE_BOARDS", "CRATE_GATE"): + for missing in ("FMT", "VALIDATE_BOARDS", "CRATE_GATE"): with self.subTest(missing=missing): result = subprocess.run(["bash", "-e", "-c", script], env={**env, missing: "skipped"}, capture_output=True, text=True) self.assertNotEqual(0, result.returncode) From 13526314a30c552f867a6529b6112ccf4784b802 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Tue, 29 Sep 2026 00:16:14 -0700 Subject: [PATCH 12/12] fix(test): drop std::sync::mpsc from the 404 refetch test ban_std_mpsc_in_async_reachable (Dylint) rejects std mpsc. The server thread now returns whether it accepted a request, and the test asserts that from the (already bounded) join. --- crates/fbuild-toolchain/src/lnk/resolver.rs | 35 ++++++++------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/crates/fbuild-toolchain/src/lnk/resolver.rs b/crates/fbuild-toolchain/src/lnk/resolver.rs index 34a584d4..4cb0ed40 100644 --- a/crates/fbuild-toolchain/src/lnk/resolver.rs +++ b/crates/fbuild-toolchain/src/lnk/resolver.rs @@ -309,19 +309,14 @@ mod tests { /// retried, whereas an unresolvable host is retried with the production /// 1+2+4+8 s backoff (15 s of test time for no extra coverage). /// - /// Returns the URL, a receiver that fires once a request has been - /// accepted (proof the refetch reached the network), and the server - /// thread. Accept and socket I/O are bounded so joining cannot hang. - fn serve_one_404() -> ( - String, - std::sync::mpsc::Receiver<()>, - std::thread::JoinHandle<()>, - ) { + /// Returns the URL and the server thread, which yields `true` once a + /// request was accepted (proof the refetch reached the network). Accept + /// and socket I/O are bounded so joining cannot hang. + fn serve_one_404() -> (String, std::thread::JoinHandle) { use std::time::{Duration, Instant}; let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap(); listener.set_nonblocking(true).unwrap(); let port = listener.local_addr().unwrap().port(); - let (accepted_tx, accepted_rx) = std::sync::mpsc::channel(); let server = std::thread::spawn(move || { let deadline = Instant::now() + Duration::from_secs(10); let mut stream = loop { @@ -329,14 +324,13 @@ mod tests { Ok((stream, _)) => break stream, Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => { if Instant::now() >= deadline { - return; + return false; } std::thread::sleep(Duration::from_millis(5)); } - Err(_) => return, + Err(_) => return false, } }; - let _ = accepted_tx.send(()); let _ = stream.set_nonblocking(false); let _ = stream.set_read_timeout(Some(Duration::from_secs(5))); let _ = stream.set_write_timeout(Some(Duration::from_secs(5))); @@ -345,12 +339,9 @@ mod tests { let _ = stream.write_all( b"HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\nConnection: close\r\n\r\n", ); + true }); - ( - format!("http://127.0.0.1:{port}/corrupt.bin"), - accepted_rx, - server, - ) + (format!("http://127.0.0.1:{port}/corrupt.bin"), server) } /// Cache-hit but stored sha doesn't match content → resolve must fall @@ -359,7 +350,7 @@ mod tests { #[test] fn resolve_rejects_corrupt_cache_entry() { let (_tmp, cache) = open_test_cache(); - let (url_owned, accepted, server) = serve_one_404(); + let (url_owned, server) = serve_one_404(); let url = url_owned.as_str(); let claimed_sha = sha256_of(b"good content"); // what .lnk says let archive_dir = cache.archive_dir(Kind::LnkBlobs, url, &claimed_sha); @@ -391,9 +382,9 @@ mod tests { // to the network rather than failing some other way. let result = resolve(&lnk, &cache); assert!(result.is_err(), "expected refetch failure, got Ok"); - accepted - .recv_timeout(std::time::Duration::from_secs(5)) - .expect("resolve should have refetched from the server"); - server.join().unwrap(); + assert!( + server.join().unwrap(), + "resolve should have refetched from the server" + ); } }