Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/app-binaries.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: app-binaries
# Regression gate: build every binary the macOS Studio app ships, each with its
# required-features. `cargo build --workspace` skips required-features bins, so
# this is the only CI that compiles chat_metal / eval_perplexity / train_grad_full
# / generate_lora / embed with the features the app actually builds them with.
# See scripts/build-app-bins.sh for the rationale and the two regressions that
# motivated it.

on:
pull_request:
branches: [main]
paths:
- 'crates/**'
- 'scripts/build-app-bins.sh'
- '.github/workflows/app-binaries.yml'
push:
branches: [main]
paths:
- 'crates/**'
workflow_dispatch:

permissions:
contents: read

env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: '0'

jobs:
build-app-bins:
name: build app-shipped binaries
runs-on: macos-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.94.1
- uses: Swatinem/rust-cache@v2
with:
shared-key: app-binaries
- name: Build all app-shipped binaries (required-features included)
run: ./scripts/build-app-bins.sh
56 changes: 56 additions & 0 deletions scripts/build-app-bins.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env bash
#
# Build every binary the macOS Studio app ships (apps/macos/scripts/package-app.sh),
# each with its required-features.
#
# This is the regression gate that `cargo build --workspace` cannot provide:
# --workspace (even with --all-targets) silently SKIPS any [[bin]] that declares
# `required-features` unless those features are explicitly enabled. So a
# required-features binary can stop compiling and never trip fmt / clippy / test
# / build CI — the break only surfaces when the app is packaged.
#
# Two real regressions slipped through exactly this gap and were caught only at
# packaging time:
# - train_grad_full E0063 (missing GDN gradient fields under train-backward)
# - generate_lora E0599 (generate_streaming method not in scope)
#
# Keep this binary list in sync with apps/macos/scripts/package-app.sh.

set -uo pipefail

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT"

FAIL=0
build_bin() {
echo ""
echo "==> cargo build --release $*"
if ! cargo build --release "$@"; then
echo "!! FAILED: cargo build --release $*"
FAIL=1
fi
}

# lattice-inference — default features (already covered by --workspace, built
# here too so the gate reflects the full app binary set).
for BIN in quantize_q4 quantize_quarot lattice qwen35_generate; do
build_bin -p lattice-inference --bin "$BIN"
done

# required-features binaries — the ones `cargo build --workspace` silently skips.
build_bin -p lattice-tune --bin train_grad_full --features train-backward
build_bin -p lattice-tune --bin generate_lora --features safetensors,inference-hook
build_bin -p lattice-inference --bin eval_perplexity --features f16,metal-gpu
build_bin -p lattice-inference --bin chat_metal --features f16,metal-gpu

# lattice-embed — `native` is a default feature, so no explicit --features.
build_bin -p lattice-embed --bin embed

if [ "$FAIL" -ne 0 ]; then
echo ""
echo "ERROR: one or more app-shipped binaries failed to build."
echo "The macOS Studio app would fail to package. Fix before merging."
exit 1
fi
echo ""
echo "OK: all app-shipped binaries built."
Loading