From a84b2cfd8bee5051631fcd0cd85688f5c5faab5d Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 16 Aug 2026 12:38:48 -0400 Subject: [PATCH 1/3] feat(ci): add linux_aarch64 release build (CRY-48) - Add linux_aarch64: [os: :linux, cpu: :aarch64] to Burrito targets in app/mix.exs, keeping it in sync with the CI matrix comment. - Add a matching ubuntu-24.04-arm matrix leg to burrito-build in .github/workflows/main.yaml. The native ARM64 runner is required (not cross-compilation) because rustler_precompiled downloads the mdex_native NIF for the build host's architecture - the same constraint that drove CRY-40's per-OS-runner split. - Add a smoke-test step (linux_aarch64 only) that runs `lc version` on the native runner after the build succeeds, proving the binary executes, the OTP app boots in interactive mode, and all NIFs load (exqlite via Zig cross-compilation, mdex_native via rustler_precompiled's aarch64-unknown-linux-musl precompiled artifact). - Update install.sh detect_target to recognise aarch64 Linux and select the linux_aarch64 tarball instead of erroring out. The packaging, checksum, and release-asset steps in burrito-package already handle arbitrary targets generically (for artifact in lc_*) and require no changes. The Homebrew formula covers only macos_aarch64 and linux_x86_64 (Homebrew's supported platforms) and also needs no changes. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/main.yaml | 15 +++++++++++++++ app/mix.exs | 2 ++ install.sh | 3 ++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 8c7ecfa..4fbf686 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -73,6 +73,8 @@ jobs: runner: macos-latest - target: linux_x86_64 runner: ubuntu-latest + - target: linux_aarch64 + runner: ubuntu-24.04-arm - target: windows_x86_64 runner: windows-latest defaults: @@ -130,6 +132,19 @@ jobs: exit 1 fi fi + - + # Smoke-test the linux_aarch64 binary on the native ARM64 runner: + # proves the binary executes (right architecture), the OTP app boots, + # and all NIFs (exqlite via elixir_make/Zig, mdex_native via + # rustler_precompiled) load correctly. `lc version` runs in + # interactive mode (no LINEAR_CLI_DAEMON=true), starts an empty + # supervisor, prints the version, and exits 0 - no API key or network + # needed. Only runs for linux_aarch64 because that's the only target + # whose runner architecture matches the binary (macos/Windows smoke + # tests are out of scope for CRY-48). + if: matrix.target == 'linux_aarch64' + name: Smoke-test the linux_aarch64 binary boots and NIFs load + run: burrito_out/lc_linux_aarch64 version - # Handed off to burrito-package below, which needs every target's # binary gathered back into one place before it can build the diff --git a/app/mix.exs b/app/mix.exs index 791adae..9093d33 100644 --- a/app/mix.exs +++ b/app/mix.exs @@ -22,6 +22,7 @@ defmodule LinearCli.MixProject do # Burrito's own docs/source, and exqlite's NIF cross-compilation verified # empirically (built+ran the linux_x86_64 target under podman/QEMU) - see # documents/phase-8-plan.adoc. macOS Intel intentionally not targeted. + # Kept in sync with .github/workflows/main.yaml's burrito-build matrix. defp releases do [ lc: [ @@ -30,6 +31,7 @@ defmodule LinearCli.MixProject do targets: [ macos_aarch64: [os: :darwin, cpu: :aarch64], linux_x86_64: [os: :linux, cpu: :x86_64], + linux_aarch64: [os: :linux, cpu: :aarch64], windows_x86_64: [os: :windows, cpu: :x86_64] ] ] diff --git a/install.sh b/install.sh index cec9d5d..026070f 100755 --- a/install.sh +++ b/install.sh @@ -32,8 +32,9 @@ detect_target() { Linux) case "$(uname -m)" in x86_64) printf '%s\n' linux_x86_64 ;; + aarch64) printf '%s\n' linux_aarch64 ;; *) - printf 'error: unsupported Linux architecture: %s (only x86_64 is built)\n' "$(uname -m)" >&2 + printf 'error: unsupported Linux architecture: %s (only x86_64 and aarch64 are built)\n' "$(uname -m)" >&2 exit 1 ;; esac From c22bc8277761a81aa6a6047c1c3c2949d7c4d106 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 16 Aug 2026 12:39:13 -0400 Subject: [PATCH 2/3] fix(ci): prefix smoke-test binary path with ./ Bash does not execute files in the working directory without an explicit path; burrito_out/lc_linux_aarch64 only works from a shell that has . on $PATH (non-standard). Use ./burrito_out/... so the step is unambiguous regardless of runner shell configuration. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/main.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 4fbf686..ebe2498 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -113,8 +113,8 @@ jobs: # independently, so a target failing partway through wouldn't # necessarily fail the whole `mix release` invocation. Not everyone # installing this uses Homebrew (no tap exists yet anyway - see - # #14/CRY-37), so linux_x86_64/macos_aarch64 are the primary - # install path for a lot of users; silently shipping a release + # #14/CRY-37), so linux_x86_64/linux_aarch64/macos_aarch64 are the + # primary install path for a lot of users; silently shipping a release # missing one of them is worse than failing loudly here. # windows_x86_64 stays best-effort, as it always has. name: Verify this target actually built @@ -144,7 +144,7 @@ jobs: # tests are out of scope for CRY-48). if: matrix.target == 'linux_aarch64' name: Smoke-test the linux_aarch64 binary boots and NIFs load - run: burrito_out/lc_linux_aarch64 version + run: ./burrito_out/lc_linux_aarch64 version - # Handed off to burrito-package below, which needs every target's # binary gathered back into one place before it can build the From 7211ecf2638ad7b26a0857e32726fd81128a7880 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 16 Aug 2026 12:48:18 -0400 Subject: [PATCH 3/3] fix(ci): add timeout-minutes: 1 to linux_aarch64 smoke test Prevents the step from hanging for up to 6 hours if `lc version` deadlocks instead of crashing (e.g. a NIF load issue that stalls rather than raises). `lc version` should exit in under a second; a 1-minute timeout fails fast without false-positive risk. --- .github/workflows/main.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index ebe2498..81065ed 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -144,6 +144,7 @@ jobs: # tests are out of scope for CRY-48). if: matrix.target == 'linux_aarch64' name: Smoke-test the linux_aarch64 binary boots and NIFs load + timeout-minutes: 1 run: ./burrito_out/lc_linux_aarch64 version - # Handed off to burrito-package below, which needs every target's