diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 22ef23a49..0005a132a 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -22,19 +22,27 @@ 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) - **`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` -- **`msrv.yml`** -- MSRV 1.95.0 verification | **`validate-boards.yml`** -- Board JSON validation +- **`fmt.yml`** -- Rustfmt check +- 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/acceptance-205.yml b/.github/workflows/acceptance-205.yml index 0fe0d5ba4..b22ed445b 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/build-apollo3_red.yml b/.github/workflows/build-apollo3_red.yml index 26146948f..db7d5f276 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-apollo3_thing_explorable.yml b/.github/workflows/build-apollo3_thing_explorable.yml index 9c99f9502..208ba5c22 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-atmega8.yml b/.github/workflows/build-atmega8.yml index 09794c498..3d74d32db 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-atmega8a.yml b/.github/workflows/build-atmega8a.yml index cce5ff674..48fcf6dbe 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-attiny1604.yml b/.github/workflows/build-attiny1604.yml index 70c28fabc..72082fbcc 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-attiny1616.yml b/.github/workflows/build-attiny1616.yml index 72c05001a..5bd3b4f03 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-attiny4313.yml b/.github/workflows/build-attiny4313.yml index e1523d908..63f491e2c 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-attiny85.yml b/.github/workflows/build-attiny85.yml index 8f11bebf8..09c441196 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-attiny88.yml b/.github/workflows/build-attiny88.yml index 41c7d69fd..f393f62c2 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-blackpill.yml b/.github/workflows/build-blackpill.yml index 3483befeb..f678f914d 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-bluepill.yml b/.github/workflows/build-bluepill.yml index 45794dbc3..8b60d845c 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32l103.yml b/.github/workflows/build-ch32l103.yml index 65a606ddb..d7c818c6a 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32v003.yml b/.github/workflows/build-ch32v003.yml index 1a68c574d..5777af839 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32v006.yml b/.github/workflows/build-ch32v006.yml index 5efb0d60d..c51c29897 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32v103.yml b/.github/workflows/build-ch32v103.yml index eb9ef51c8..7fd88b1e8 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32v203.yml b/.github/workflows/build-ch32v203.yml index 29b3c6f71..949307787 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32v208.yml b/.github/workflows/build-ch32v208.yml index eae5d1c63..f5ec5608f 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32v303.yml b/.github/workflows/build-ch32v303.yml index fb0e13d18..dd31b648a 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32v307.yml b/.github/workflows/build-ch32v307.yml index dc17f35a2..64059e1e8 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-ch32x035.yml b/.github/workflows/build-ch32x035.yml index 0ab6852b0..dccbf91d7 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-clearcore.yml b/.github/workflows/build-clearcore.yml index ebd71d32e..1d8e3035d 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-due.yml b/.github/workflows/build-due.yml index 537609da4..c7071a8d6 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32c2.yml b/.github/workflows/build-esp32c2.yml index 3d320f69b..d233ab150 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32c3.yml b/.github/workflows/build-esp32c3.yml index da8f6fd32..f01672b8c 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32c5.yml b/.github/workflows/build-esp32c5.yml index 7119efbc7..e0cb23f24 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32c6.yml b/.github/workflows/build-esp32c6.yml index 0141db299..1a05a6221 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32dev.yml b/.github/workflows/build-esp32dev.yml index 8428b4374..53774ad9b 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32h2.yml b/.github/workflows/build-esp32h2.yml index 8cc34a152..4c45b754d 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32p4.yml b/.github/workflows/build-esp32p4.yml index 48bca262e..ad4b5a6c7 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32s2.yml b/.github/workflows/build-esp32s2.yml index 45f32d47e..eac215fa5 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-esp32s3.yml b/.github/workflows/build-esp32s3.yml index a91fbe894..be457f88e 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-esp8266.yml b/.github/workflows/build-esp8266.yml index 1c3d36615..295bc9524 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-giga-r1.yml b/.github/workflows/build-giga-r1.yml index 0add7bd96..fc771e900 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-leonardo.yml b/.github/workflows/build-leonardo.yml index b818564fa..1a9dd0c04 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-lpc804.yml b/.github/workflows/build-lpc804.yml index 2f234ef6b..aaa4142c3 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-lpc845.yml b/.github/workflows/build-lpc845.yml index 7e1b350c1..95137f568 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-lpc845brk.yml b/.github/workflows/build-lpc845brk.yml index f63b6900a..403d50203 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-lpcxpresso804.yml b/.github/workflows/build-lpcxpresso804.yml index 59b37032e..39b05f776 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-lpcxpresso845max.yml b/.github/workflows/build-lpcxpresso845max.yml index 8986905d5..4cb0c25c7 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-matrix_portal_m4.yml b/.github/workflows/build-matrix_portal_m4.yml index 1567a3b21..946a82a22 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-mgm240.yml b/.github/workflows/build-mgm240.yml index 57d4eb74e..ab4aa11dd 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,11 @@ 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 }} + toolchain-cache: true diff --git a/.github/workflows/build-nano-every.yml b/.github/workflows/build-nano-every.yml index 967de7ebd..ad8fc822d 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-nano_every.yml b/.github/workflows/build-nano_every.yml index bc19075f2..58d0045c4 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-nice_nano_nrf52840.yml b/.github/workflows/build-nice_nano_nrf52840.yml index 9eaba5940..f49b7c108 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-nrf52840-sense.yml b/.github/workflows/build-nrf52840-sense.yml index b3a9815d7..9bbae9303 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-nrf52840_dk.yml b/.github/workflows/build-nrf52840_dk.yml index 14ce12978..5806a7a52 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-nrfmicro_nrf52840.yml b/.github/workflows/build-nrfmicro_nrf52840.yml index 59e2e0b8c..323e4d112 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-nucleo-f429zi.yml b/.github/workflows/build-nucleo-f429zi.yml index 549d5cae4..7c76d7195 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-nucleo-f439zi.yml b/.github/workflows/build-nucleo-f439zi.yml index e58e2e3ed..f8b3bbc35 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-nucleo_f429zi.yml b/.github/workflows/build-nucleo_f429zi.yml index 8cfeecd6f..5aa3a8230 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-nucleo_f439zi.yml b/.github/workflows/build-nucleo_f439zi.yml index f53e3659a..d20744d47 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-qtpy_m0.yml b/.github/workflows/build-qtpy_m0.yml index 15b11e49f..c72b190f1 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-rp2040.yml b/.github/workflows/build-rp2040.yml index 3e114153f..0d9586e80 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-rp2350.yml b/.github/workflows/build-rp2350.yml index 8c4a9fc60..b82a33a49 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-rpipico.yml b/.github/workflows/build-rpipico.yml index 303fffbd3..81a364fc8 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-rpipico2.yml b/.github/workflows/build-rpipico2.yml index 6c5eb1e95..041aa8c30 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-sam3x8e_due.yml b/.github/workflows/build-sam3x8e_due.yml index 32a164444..7bcb7c6ef 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-samd21.yml b/.github/workflows/build-samd21.yml index b6815eac2..60957d51f 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-samd21_zero.yml b/.github/workflows/build-samd21_zero.yml index b053cba10..090428b26 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-samd51j.yml b/.github/workflows/build-samd51j.yml index f30921292..9c710074c 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-samd51p.yml b/.github/workflows/build-samd51p.yml index e2626954f..88dd70540 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-stm32f103c8.yml b/.github/workflows/build-stm32f103c8.yml index 42a9ed2ca..0bbe3c029 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-stm32f103cb.yml b/.github/workflows/build-stm32f103cb.yml index d05fc6f54..8008ae3b1 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-stm32f103tb.yml b/.github/workflows/build-stm32f103tb.yml index 2ccd4e57d..dd0b9a5dc 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-stm32f411ce.yml b/.github/workflows/build-stm32f411ce.yml index c2bf07a7b..042f1132c 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-stm32h747xi.yml b/.github/workflows/build-stm32h747xi.yml index ac7176cd0..0fedfe49b 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-supermini_nrf52840.yml b/.github/workflows/build-supermini_nrf52840.yml index c6b53ad96..6f7ca9ad0 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-teensy30.yml b/.github/workflows/build-teensy30.yml index eb7e70021..b6dc1280c 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-teensy31.yml b/.github/workflows/build-teensy31.yml index 2d15bab17..d22917854 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-teensy32.yml b/.github/workflows/build-teensy32.yml index c8f152a4f..54b3815fc 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-teensy35.yml b/.github/workflows/build-teensy35.yml index 851d13e5a..4855a86ce 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-teensy36.yml b/.github/workflows/build-teensy36.yml index 0fc1956fa..4607fd2d0 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-teensy40.yml b/.github/workflows/build-teensy40.yml index 87af1f68c..f1861271b 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-teensy41.yml b/.github/workflows/build-teensy41.yml index 0364ff9c8..231cd4c1b 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-teensylc.yml b/.github/workflows/build-teensylc.yml index 907cb30c1..8e8033ea2 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-thingplusmatter.yml b/.github/workflows/build-thingplusmatter.yml index df3eaec68..9fc3dd818 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-tinystm.yml b/.github/workflows/build-tinystm.yml index 123952dbb..eeb6c7ff7 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-uno-r4-wifi.yml b/.github/workflows/build-uno-r4-wifi.yml index ff5decc6a..e57d52fa5 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-uno.yml b/.github/workflows/build-uno.yml index e742f092f..9d1656ce1 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,7 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/build-uno_r4_wifi.yml b/.github/workflows/build-uno_r4_wifi.yml index 262791c05..bfab9b0c6 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,11 @@ 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 }} + toolchain-cache: false diff --git a/.github/workflows/check-ubuntu.yml b/.github/workflows/check-ubuntu.yml index 2ef2ed0b6..b3361d68f 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 01e0f2259..baa9a9e13 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 diff --git a/.github/workflows/ci-full.yml b/.github/workflows/ci-full.yml index 9b9ffde4c..3516db06f 100644 --- a/.github/workflows/ci-full.yml +++ b/.github/workflows/ci-full.yml @@ -101,18 +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 - 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 @@ -125,9 +113,45 @@ 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 }} + persist-credentials: false + - 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 + 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 + - 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 @@ -139,456 +163,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 }} @@ -596,10 +696,12 @@ jobs: env-name: ${{ matrix.env_name }} 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() - 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, validate_boards, crate_gate] runs-on: ubuntu-latest outputs: complete: ${{ steps.complete.outputs.complete }} @@ -618,8 +720,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 }} run: | @@ -628,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" "$DOCS" "$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/ci-test.yml b/.github/workflows/ci-test.yml index d12f49284..ac3e73a6c 100644 --- a/.github/workflows/ci-test.yml +++ b/.github/workflows/ci-test.yml @@ -55,9 +55,45 @@ 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 }} + persist-credentials: false + - 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 + 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 + - 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 @@ -69,6 +105,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 }} @@ -76,6 +113,8 @@ jobs: env-name: ${{ matrix.env_name }} 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/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index c14bd6880..000000000 --- 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/.github/workflows/dylint.yml b/.github/workflows/dylint.yml index 291a0083e..98c459234 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: | diff --git a/.github/workflows/esp32s3-size-parity.yml b/.github/workflows/esp32s3-size-parity.yml index f0fbd98b5..876f22fe4 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/msrv.yml b/.github/workflows/msrv.yml deleted file mode 100644 index 12b1dccb7..000000000 --- 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/.github/workflows/nightly-platforms.yml b/.github/workflows/nightly-platforms.yml index 4364651cb..ddec09b12 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,431 +17,98 @@ 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" - build: - name: ${{ matrix.workflow_name }} - needs: guard - 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_bin: + name: Build fbuild (shared by board jobs) + if: needs.plan.outputs.workflows != '[]' + needs: plan + 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 }} + persist-credentials: false + - 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 + 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 + - 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 + 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: | + failed=() + for wf in $(echo "$WORKFLOWS" | jq -r '.[]'); do + 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/.github/workflows/template_build.yml b/.github/workflows/template_build.yml index 75d3fe3c4..8a65cf554 100644 --- a/.github/workflows/template_build.yml +++ b/.github/workflows/template_build.yml @@ -23,6 +23,35 @@ 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. + 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 + 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 @@ -47,6 +76,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: @@ -79,6 +109,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 @@ -89,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 @@ -108,6 +144,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 +163,24 @@ 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 + run-id: ${{ inputs.fbuild-run-id || github.run_id }} + github-token: ${{ github.token }} + + - 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 @@ -174,7 +228,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() && inputs.toolchain-cache && github.ref == 'refs/heads/main' timeout-minutes: 10 uses: actions/cache/save@v5 with: @@ -182,7 +237,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/bench/fastled-examples/README.md b/bench/fastled-examples/README.md index 678fe94e2..43de278aa 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/README.md b/ci/README.md index f3172ca17..411b9b7b2 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/board_families.json b/ci/board_families.json index 7f3554b02..3725e536d 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/check_rust_toolchain_pins.py b/ci/check_rust_toolchain_pins.py index 305bffef1..4c1498d67 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 686ed3012..f70e7252d 100644 --- a/ci/render_workflows.py +++ b/ci/render_workflows.py @@ -135,13 +135,51 @@ 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 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" + " 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" + f" toolchain-cache: {json.dumps(toolchain_cache(board, families))}\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] = {} @@ -154,7 +192,59 @@ def execution_boards(boards: list[dict]) -> list[dict]: return list(unique.values()) -def render_ci(boards: list[dict], tier: str) -> str: +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" + " persist-credentials: false\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" + " 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" + " - 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, 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)]) @@ -165,6 +255,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: @@ -283,8 +374,6 @@ def render_ci(boards: list[dict], tier: str) -> 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"), ) @@ -307,9 +396,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,12 +412,14 @@ 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" + + " toolchain-cache: ${{ matrix.toolchain_cache }}\n") + ("" if minimal else " 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, 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" @@ -346,8 +438,6 @@ def render_ci(boards: list[dict], tier: str) -> 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 "") + " run: |\n" @@ -356,7 +446,7 @@ def render_ci(boards: list[dict], tier: str) -> 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\" \"$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" @@ -442,61 +532,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 = ( - " build:\n" - " name: ${{ matrix.workflow_name }}\n" - " needs: guard\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" - ) + 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" @@ -504,6 +565,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" @@ -512,42 +575,73 @@ 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" + # 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" + " 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 }}" + ) + dispatch def write_if_changed(path: Path, new_text: str, check: bool, drift: list[Path], updated: list[Path]) -> None: @@ -601,12 +695,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, 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/select_boards.py b/ci/select_boards.py new file mode 100644 index 000000000..014f0de38 --- /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 573e4197f..18d26571a 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"), ("validate_boards", "validate-boards.yml"), ("crate_gate", "crate-gate.yml"), ): self.assertEqual(f"./.github/workflows/{workflow_name}", full["jobs"][job]["uses"]) @@ -127,12 +127,37 @@ 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"]) + 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") @@ -172,7 +197,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): @@ -200,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", "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", "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", "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) diff --git a/ci/test_select_boards.py b/ci/test_select_boards.py new file mode 100644 index 000000000..136196235 --- /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() diff --git a/crates/fbuild-build/tests/it/README.md b/crates/fbuild-build/tests/it/README.md new file mode 100644 index 000000000..3c09da99f --- /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 99% rename from crates/fbuild-build/tests/clangd_check_parity.rs rename to crates/fbuild-build/tests/it/clangd_check_parity.rs index da20719bc..44df073b7 100644 --- a/crates/fbuild-build/tests/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/compile_many_stage2_perf.rs b/crates/fbuild-build/tests/it/compile_many_stage2_perf.rs similarity index 99% rename from crates/fbuild-build/tests/compile_many_stage2_perf.rs rename to crates/fbuild-build/tests/it/compile_many_stage2_perf.rs index ce3d0887f..8ab42cf4a 100644 --- a/crates/fbuild-build/tests/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/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 99% rename from crates/fbuild-build/tests/esp32_build.rs rename to crates/fbuild-build/tests/it/esp32_build.rs index 6bc3174d2..6f22044e9 100644 --- a/crates/fbuild-build/tests/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/esp32s3_size_parity.rs b/crates/fbuild-build/tests/it/esp32s3_size_parity.rs similarity index 98% rename from crates/fbuild-build/tests/esp32s3_size_parity.rs rename to crates/fbuild-build/tests/it/esp32s3_size_parity.rs index 50b9a0210..8f812d53c 100644 --- a/crates/fbuild-build/tests/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/flag_escaping_lint.rs b/crates/fbuild-build/tests/it/flag_escaping_lint.rs similarity index 99% rename from crates/fbuild-build/tests/flag_escaping_lint.rs rename to crates/fbuild-build/tests/it/flag_escaping_lint.rs index 833c8e1c9..70cf8382b 100644 --- a/crates/fbuild-build/tests/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/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 000000000..1d5cea594 --- /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 98% rename from crates/fbuild-build/tests/nxplpc_build_flags.rs rename to crates/fbuild-build/tests/it/nxplpc_build_flags.rs index 6bf9b0978..f1b808078 100644 --- a/crates/fbuild-build/tests/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/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 98% rename from crates/fbuild-build/tests/stm32_acceptance.rs rename to crates/fbuild-build/tests/it/stm32_acceptance.rs index 59efc0d43..4a754d145 100644 --- a/crates/fbuild-build/tests/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/teensy30_acceptance.rs b/crates/fbuild-build/tests/it/teensy30_acceptance.rs similarity index 98% rename from crates/fbuild-build/tests/teensy30_acceptance.rs rename to crates/fbuild-build/tests/it/teensy30_acceptance.rs index 8b9f50390..e35cee891 100644 --- a/crates/fbuild-build/tests/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/teensy41_acceptance.rs b/crates/fbuild-build/tests/it/teensy41_acceptance.rs similarity index 97% rename from crates/fbuild-build/tests/teensy41_acceptance.rs rename to crates/fbuild-build/tests/it/teensy41_acceptance.rs index 91b17deee..7b130bc04 100644 --- a/crates/fbuild-build/tests/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/teensy_build.rs b/crates/fbuild-build/tests/it/teensy_build.rs similarity index 99% rename from crates/fbuild-build/tests/teensy_build.rs rename to crates/fbuild-build/tests/it/teensy_build.rs index 084db350c..7777ebf9d 100644 --- a/crates/fbuild-build/tests/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/teensylc_acceptance.rs b/crates/fbuild-build/tests/it/teensylc_acceptance.rs similarity index 98% rename from crates/fbuild-build/tests/teensylc_acceptance.rs rename to crates/fbuild-build/tests/it/teensylc_acceptance.rs index 72a6d7a38..0163301aa 100644 --- a/crates/fbuild-build/tests/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-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 000000000..6a14b6e42 --- /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 000000000..88767f1ec --- /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 98% rename from crates/fbuild-daemon/tests/process_containment.rs rename to crates/fbuild-daemon/tests/it/process_containment.rs index 1dc6b5b1e..386ecc5d7 100644 --- a/crates/fbuild-daemon/tests/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-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 diff --git a/crates/fbuild-packages-fetch/src/downloader.rs b/crates/fbuild-packages-fetch/src/downloader.rs index c35bc589e..2cd918525 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 c36111ed7..5357bac3d 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 041ae36f3..7705604e8 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 12238f631..4cb0ed40b 100644 --- a/crates/fbuild-toolchain/src/lnk/resolver.rs +++ b/crates/fbuild-toolchain/src/lnk/resolver.rs @@ -305,13 +305,53 @@ 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). + /// + /// 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 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 false; + } + std::thread::sleep(Duration::from_millis(5)); + } + Err(_) => return false, + } + }; + 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", + ); + true + }); + (format!("http://127.0.0.1:{port}/corrupt.bin"), server) + } + /// 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, 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); std::fs::create_dir_all(&archive_dir).unwrap(); @@ -337,9 +377,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"); + assert!( + server.join().unwrap(), + "resolve should have refetched from the server" + ); } } diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index ca3f1a89b..93b982383 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 f031be2fb..9218abcfb 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 150c0ffb2..5be64224f 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 ec9b4e750..9711247a7 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