docs(ci): record macOS implementation in ADR-ci-003 (D1 complete)
ci / gate (push) Successful in 3m23s
ci / gate (push) Successful in 3m23s
macOS is no longer deferred — built natively on a Tart (Apple-Silicon) runner (real hardware → licensed SDK, no grey area). Amendment documents release-macos.yaml (dispatch-only, needs main), the libiconv de-nix + ad-hoc re-sign, the runner-label `:host` backend nuance, generation-based cache pruning, and D2-on-macOS (system libs only). All six D1 targets now produce artifacts. Updates the deferred list + index entry.
This commit is contained in:
@@ -20,6 +20,49 @@ This ADR records the **cross-platform build strategy**; it sits on top of
|
||||
**ADR-ci-002** (the nix flake, which now carries the cross toolchain) and
|
||||
**ADR-ci-001** (the pipeline, whose release job this fills in).
|
||||
|
||||
## Amendment — 2026-06-14: macOS implemented (closes D1)
|
||||
|
||||
macOS is no longer deferred. The two `*-apple-darwin` targets now build on a
|
||||
**Tart (Apple-Silicon) macOS runner** registered to Gitea — building on **real
|
||||
Apple hardware** makes the SDK fully licensed, so the whole osxcross / SDK
|
||||
grey-area + public-image-redistribution problem (§5 below) simply **does not
|
||||
arise**. With all six D1 targets producing artifacts, **D1 is complete.**
|
||||
|
||||
Details, all verified on the runner via a throwaway smoke-test before wiring the
|
||||
release leg:
|
||||
|
||||
- **`release-macos.yaml`** — `workflow_dispatch` with a `tag` input,
|
||||
`runs-on: macos`. The runner registered as `macos:host`, but `:host` is
|
||||
act_runner's execution-backend schema (run on host, no container), **not** part
|
||||
of the label, so the label is `macos`. Steps: `cargo test` (macOS gets the only
|
||||
automated test coverage outside the Linux gate — user choice) → build both
|
||||
darwin targets natively through the flake (`apple-sdk` added to the devShell so
|
||||
the toolchain links AppKit) → **upload to the same release** via the idempotent
|
||||
create-or-get.
|
||||
- **De-nix + re-sign.** The darwin stdenv bakes a `/nix/store` `libiconv` load
|
||||
path into the binary (the *only* non-system dependency; everything else is
|
||||
AppKit/Foundation/CoreGraphics/IOKit + `libSystem`/`libobjc`). The release step
|
||||
rewrites it to `/usr/lib/libiconv.2.dylib` with `install_name_tool` and
|
||||
**re-signs ad-hoc** (`codesign -f -s -`) — `install_name_tool` invalidates the
|
||||
signature and Apple Silicon refuses an unsigned binary. A guard fails the build
|
||||
if any `/nix/store` path remains. Result: portable, signed binaries (the native
|
||||
one was confirmed to launch).
|
||||
- **Dispatch-only, intermittent runner.** The Mac isn't always on, so macOS is a
|
||||
separate dispatched workflow (not a job in `release.yaml`) — a release always
|
||||
carries the four Linux/Windows assets regardless of the Mac, and the two macOS
|
||||
assets are added by dispatching `release-macos` for that tag. **Caveat:** Gitea
|
||||
exposes `workflow_dispatch` only for workflows on the **default branch**, so
|
||||
`release-macos` becomes triggerable once the CI work is merged to `main`.
|
||||
- **Cache hygiene (host-execution runner).** The runner wipes the workspace each
|
||||
run, so cargo `target/` never accumulates; the persistent cache is the nix
|
||||
store, bounded by **generation** — record the current devShell in a persistent
|
||||
profile, keep the 2 newest generations (`nix-env --delete-generations +2`),
|
||||
reclaim the rest. (The first sweep reclaimed a ~3.8 GB one-time backlog of
|
||||
build scaffolding — source + build-only deps, not re-installed toolchains.)
|
||||
- **D2 on macOS.** macOS binaries cannot be fully static (`libSystem` is always
|
||||
dynamic); "no runtime deps" there means *system libraries only*, which the
|
||||
de-nix step guarantees.
|
||||
|
||||
## Context
|
||||
|
||||
`requirements.md` **D1** asks for binaries on **Linux, macOS, Windows × x86_64
|
||||
@@ -135,7 +178,8 @@ user decides when we get there.
|
||||
|
||||
## Deferred / out of scope
|
||||
|
||||
- **macOS** (x86_64 + aarch64) — the SDK/runner decision above.
|
||||
- ~~**macOS** (x86_64 + aarch64)~~ — **done** via the Tart runner (see the
|
||||
2026-06-14 amendment); §5 below is the as-deferred rationale, kept for history.
|
||||
- **D3 packaging** — Homebrew / Scoop / winget / `cargo-binstall` manifests
|
||||
(and binstall-friendly archive naming).
|
||||
- **CI speed** — caching per-target builds / Zig's libc cache.
|
||||
|
||||
Reference in New Issue
Block a user