From e29accc35e7c7b3656c456c5f98c20e591909e6a Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Wed, 2 Sep 2026 16:49:44 -0700 Subject: [PATCH 1/3] ci: drop macOS GitHub runners outside the release path macOS-hosted runners cost the most minutes and are the slowest to schedule, while every shipped macOS artifact is already cross-built from Linux (soldr + cargo-zigbuild + managed Apple SDK) in release-auto.yml. Remove the remaining mac hosts from the push/PR and manual-build lanes: - Delete check-macos.yml (clippy + tests on macos-latest for every push and PR) and its README badge. Only "Dylint" is a required status check on main, so nothing is left waiting on a check that never reports. - platform-boundary-research.yml: drop the macos-latest matrix entry. The scanner walks source rather than expanded modules, so it produces the same union on any host; --host-label is only a print prefix. - build.yml: build aarch64-apple-darwin on ubuntu-latest via the template's mac_cross_linux branch, matching the release matrix, and pass mac_cross_linux through the `with:` block (it was not wired up). release-auto.yml is unchanged -- both apple targets there already run on ubuntu-latest, so no release capability is lost. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01CfdhKY6DmrRJ6mzSTzLU58 --- .github/workflows/README.md | 5 +- .github/workflows/build.yml | 16 +++-- .github/workflows/check-macos.yml | 58 ------------------- .../workflows/platform-boundary-research.yml | 2 - README.md | 1 - docs/platform-boundary-research-inventory.md | 10 ++-- docs/platform-boundary-research.md | 10 +++- 7 files changed, 27 insertions(+), 75 deletions(-) delete mode 100644 .github/workflows/check-macos.yml diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 31709aaab..a214d08d7 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -4,10 +4,11 @@ CI/CD workflows for the fbuild project, covering lint, test, documentation, and ## CI Checks (push/PR) -- **`check-{macos,ubuntu,windows}.yml`** -- Clippy + tests per platform +- **`check-{ubuntu,windows}.yml`** -- 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 -- **`platform-boundary-research.yml`** -- Windows/Linux/macOS reconciliation of the #1307 research inventory and RED fixture +- **`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/build.yml b/.github/workflows/build.yml index 11f9f2376..0e6286e7e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,16 +35,21 @@ jobs: linux_cross: true macos_cross: false - # x86_64-apple-darwin removed: Intel Macs use ARM wheel via Rosetta. - # Cross-compiling ring crate ARM→x86 fails; native macos-13 runners - # are perpetually unavailable. Re-enable when ring supports cross or - # GitHub restores Intel runner capacity. + # x86_64-apple-darwin is not built here: Intel Macs install the + # ARM wheel via Rosetta, and the release matrix + # (release-auto.yml) is what produces the Intel archive when a + # release needs one. + # aarch64-apple-darwin cross-compiles from the Linux runner via + # soldr + cargo-zigbuild + soldr's managed Apple SDK, matching the + # release matrix. No macos-latest runner is used anywhere in this + # workflow. - target: aarch64-apple-darwin - runner: macos-latest + runner: ubuntu-latest binary_ext: "" linux_cross: false macos_cross: false + mac_cross_linux: true - target: x86_64-pc-windows-msvc runner: windows-latest @@ -59,4 +64,5 @@ jobs: binary_ext: ${{ matrix.binary_ext }} linux_cross: ${{ matrix.linux_cross }} macos_cross: ${{ matrix.macos_cross }} + mac_cross_linux: ${{ matrix.mac_cross_linux == true }} ref: ${{ github.event.inputs.ref || 'main' }} diff --git a/.github/workflows/check-macos.yml b/.github/workflows/check-macos.yml deleted file mode 100644 index 2419603fc..000000000 --- a/.github/workflows/check-macos.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Check macOS - -on: - workflow_dispatch: {} - 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: check-macos.yml-${{ github.event_name == 'pull_request' && github.ref || github.run_id }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - -env: - CARGO_TERM_COLOR: always - RUSTFLAGS: "-D warnings" - FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" - -jobs: - check: - name: Check (macos-latest) - runs-on: macos-latest - timeout-minutes: 30 - steps: - - uses: actions/checkout@v6 - - name: Setup soldr - id: setup-soldr - uses: zackees/setup-soldr@v0 - with: - version: 0.8.23 - 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 workspace check job is - # ~1.5–2 GiB (issue #400). Raise the soft warn threshold above - # the steady-state size so the action only flags genuinely - # runaway caches. Hard cap stays at the action default (6 GiB). - cache-payload-warn-bytes: 2GiB - - - name: Check - shell: bash - run: soldr cargo check --workspace --all-targets - - name: Clippy - shell: bash - run: soldr cargo clippy --workspace --all-targets -- -D warnings - - name: Test - shell: bash - run: soldr cargo test --workspace diff --git a/.github/workflows/platform-boundary-research.yml b/.github/workflows/platform-boundary-research.yml index 69fd586db..d3347246b 100644 --- a/.github/workflows/platform-boundary-research.yml +++ b/.github/workflows/platform-boundary-research.yml @@ -27,8 +27,6 @@ jobs: host: linux - os: windows-latest host: windows - - os: macos-latest - host: macos runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v6 diff --git a/README.md b/README.md index 72837cb65..1d035cb4e 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ files already used by PlatformIO sketches, but uses a Rust-native, data-driven build pipeline. [![Check Ubuntu](https://github.com/fastled/fbuild/actions/workflows/check-ubuntu.yml/badge.svg)](https://github.com/fastled/fbuild/actions/workflows/check-ubuntu.yml) -[![Check macOS](https://github.com/fastled/fbuild/actions/workflows/check-macos.yml/badge.svg)](https://github.com/fastled/fbuild/actions/workflows/check-macos.yml) [![Check Windows](https://github.com/fastled/fbuild/actions/workflows/check-windows.yml/badge.svg)](https://github.com/fastled/fbuild/actions/workflows/check-windows.yml) [![Formatting](https://github.com/fastled/fbuild/actions/workflows/fmt.yml/badge.svg)](https://github.com/fastled/fbuild/actions/workflows/fmt.yml) [![Documentation](https://github.com/fastled/fbuild/actions/workflows/docs.yml/badge.svg)](https://github.com/fastled/fbuild/actions/workflows/docs.yml) diff --git a/docs/platform-boundary-research-inventory.md b/docs/platform-boundary-research-inventory.md index c2e2a46fa..963e49061 100644 --- a/docs/platform-boundary-research-inventory.md +++ b/docs/platform-boundary-research-inventory.md @@ -17,10 +17,12 @@ external/vendor sources are outside this research union. Because the scanner walks source rather than expanded modules, the same checkout produces the same union on every host. `.github/workflows/platform-boundary-research.yml` -runs the drift check and fixture tests on Windows, Linux, and macOS and prints a -host-labelled total. Phase 2 must still reconcile the three raw parser/Dylint -inventories before it freezes its authoritative ledger; compiler hooks alone -cannot see wrong-host or orphaned module files. +runs the drift check and fixture tests on Windows and Linux and prints a +host-labelled total (the macOS runner lane was dropped from CI; macOS binaries +are cross-built from Linux, and the host-independent scanner reports the same +union there). Phase 2 must still reconcile the raw parser/Dylint inventories +before it freezes its authoritative ledger; compiler hooks alone cannot see +wrong-host or orphaned module files. Reproduce locally with: diff --git a/docs/platform-boundary-research.md b/docs/platform-boundary-research.md index 75bfa2ba5..073ce3fce 100644 --- a/docs/platform-boundary-research.md +++ b/docs/platform-boundary-research.md @@ -123,7 +123,9 @@ No current fbuild component needs a permanent specialized-artifact zone. | build/test fixtures | Generic or concrete-facade tests | Tests are not an exemption from the source boundary. | Phase 2 must revalidate this decision against its parser-derived three-host -union. If it discovers a genuine artifact ABI constraint, the exception must be +union (the scanner is host-independent; CI now runs it on Linux and Windows +only -- the macOS runner lane was dropped and macOS binaries are cross-built +from Linux). If it discovers a genuine artifact ABI constraint, the exception must be named and narrowly linted; a file/directory wildcard is not acceptable. ## RED evidence @@ -132,8 +134,10 @@ named and narrowly linted; a file/directory wildcard is not acceptable. attribute, active-host native import, `cfg!` expression, and compile-time host fact. It compiles on Windows, Linux, and macOS today because fbuild has no host-platform boundary lint. The phase-1 workflow preserves that positive -compile result on all three hosts. Phase 2 converts the same constructs into -negative Dylint/scanner fixtures whose expected result is a boundary error. +compile result on the Linux and Windows CI hosts (the macOS runner lane was +dropped from CI; macOS binaries are cross-built from Linux). Phase 2 converts +the same constructs into negative Dylint/scanner fixtures whose expected result +is a boundary error. Existing production and test sources provide additional RED evidence: the research inventory includes private/inactive attributes, 77 native paths, and From 71f68339fa118be3911fb76ca311a237e90c7b08 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Wed, 2 Sep 2026 16:51:18 -0700 Subject: [PATCH 2/3] docs: record that CI has no macOS hosts CLAUDE.md is read at the start of every agent session; leaving "CI: Linux, macOS, Windows" invites the next session to re-add a mac check lane. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01CfdhKY6DmrRJ6mzSTzLU58 --- CLAUDE.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index a5f8093d4..a209b930d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -59,7 +59,10 @@ The four rules an agent must internalize before doing anything else (all listed - **Always use a globally-installed `soldr` to execute Rust commands.** Bare cargo/rustc and legacy `uv run cargo` shims are blocked by hook. soldr uses `rustup which` to pick the rustup-managed toolchain from `rust-toolchain.toml`. The standard Cargo path is `soldr cargo ...`, so repo Rust builds get soldr's managed zccache path by default; do not add repo-specific `RUSTC_WRAPPER` wiring for normal builds. Install soldr globally via `uv tool install soldr` (or see https://github.com/zackees/soldr). - **Always use `uv` for Python.** Bare `python`/`pip` are blocked by hook. Use `uv run ...` or `uv pip ...`. - MSRV: 1.95.0 | Edition: 2021 | Toolchain: 1.95.0 pinned in `rust-toolchain.toml` (clippy + rustfmt) -- CI: Linux, macOS, Windows. All warnings denied (`RUSTFLAGS="-D warnings"`) +- CI hosts: Linux, Windows. All warnings denied (`RUSTFLAGS="-D warnings"`). There are + **no macOS runners** — macOS is a build *target*, not a test host: every apple-darwin + binary is cross-built from Linux (soldr + `cargo-zigbuild` + managed Apple SDK) in + `release-auto.yml`. Do not add a `macos-latest` lane back. - Every directory with files must have a README.md (enforced by hook) ## Commands From 5b67f42bcb8fb436d6d400175911babbca03f575 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Thu, 3 Sep 2026 03:35:20 -0700 Subject: [PATCH 3/3] docs(ci): fix Rosetta direction and stale three-host wording CodeRabbit review on #1412: - build.yml repeated an inverted Rosetta claim (Rosetta runs x86_64 on Apple silicon, not the reverse). Drop the rationale and point at the release matrix, which cross-builds the Intel target from Linux. - CLAUDE.md said release-auto.yml was the only workflow producing an Apple binary; build.yml now cross-builds one too. - platform-boundary-research.md still called the protocol "three-host" two paragraphs above the note saying the macOS lane was dropped. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01CfdhKY6DmrRJ6mzSTzLU58 --- .github/workflows/build.yml | 8 ++++---- CLAUDE.md | 5 +++-- docs/platform-boundary-research.md | 4 +++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0e6286e7e..cf98df987 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,10 +35,10 @@ jobs: linux_cross: true macos_cross: false - # x86_64-apple-darwin is not built here: Intel Macs install the - # ARM wheel via Rosetta, and the release matrix - # (release-auto.yml) is what produces the Intel archive when a - # release needs one. + # x86_64-apple-darwin is not built here. This workflow builds + # binaries on demand; the release matrix (release-auto.yml) is + # what produces the Intel archive when a release needs one, and + # it cross-builds that target from Linux too. # aarch64-apple-darwin cross-compiles from the Linux runner via # soldr + cargo-zigbuild + soldr's managed Apple SDK, matching the diff --git a/CLAUDE.md b/CLAUDE.md index a209b930d..d0434d327 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -61,8 +61,9 @@ The four rules an agent must internalize before doing anything else (all listed - MSRV: 1.95.0 | Edition: 2021 | Toolchain: 1.95.0 pinned in `rust-toolchain.toml` (clippy + rustfmt) - CI hosts: Linux, Windows. All warnings denied (`RUSTFLAGS="-D warnings"`). There are **no macOS runners** — macOS is a build *target*, not a test host: every apple-darwin - binary is cross-built from Linux (soldr + `cargo-zigbuild` + managed Apple SDK) in - `release-auto.yml`. Do not add a `macos-latest` lane back. + binary is cross-built from Linux (soldr + `cargo-zigbuild` + managed Apple SDK) by the + Linux-hosted native workflows, `release-auto.yml` and `build.yml`. Do not add a + `macos-latest` lane back. - Every directory with files must have a README.md (enforced by hook) ## Commands diff --git a/docs/platform-boundary-research.md b/docs/platform-boundary-research.md index 073ce3fce..792c863ec 100644 --- a/docs/platform-boundary-research.md +++ b/docs/platform-boundary-research.md @@ -93,7 +93,9 @@ initially reported 490 candidate occurrences. Phase 2 Dylint/scanner reconciliation first corrected the union to 496 after adding missed constructs and removing local-module false positives, then incorporated eight host-cfg occurrences added to `fbuild-paths` on `main` before the baseline merged. The -authoritative union is therefore 504. The checked-in rows and reproducible three-host protocol are described in +authoritative union is therefore 504. The checked-in rows and the reproducible +cross-host protocol (three hosts as run for phase 1; the macOS lane has since +been dropped from CI) are described in `platform-boundary-research-inventory.md`. This is reviewed research input, not the phase-2 exact-occurrence baseline.