chore(release): v0.10.1 #35
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| # Triggered by pushing a tag matching `v*` (e.g. `v0.2.0`). Builds the | |
| # aarch64-apple-darwin bundle (MLX is Apple-Silicon-only — mlx-sys's | |
| # CMakeLists.txt refuses x86_64 outright, so an Intel matrix entry can't | |
| # succeed), signs the `.app.tar.gz` updater bundle with the Ed25519 key | |
| # stored in the `TAURI_SIGNING_PRIVATE_KEY` secret, and uploads the | |
| # artifacts (plus a `latest.json` manifest) to a draft GitHub Release. | |
| # Flip the release from draft to published once the job finishes to | |
| # expose the new version to the in-app updater. | |
| # | |
| # Maintainer setup (one-time): see crates/lumen-app/docs/release.md for | |
| # how to generate the signing keypair + register the secrets on the repo. | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| # Manual dispatch for trial runs without a tag (uploads to a draft | |
| # release named `vTEST-<sha>`). Useful when iterating on this workflow. | |
| workflow_dispatch: | |
| # tauri-action creates a draft GitHub Release + uploads bundle artifacts, | |
| # which requires write access to repo contents. Without this block the | |
| # default token is read-only on repos with restrictive Actions settings, | |
| # and the release-creation step fails with | |
| # "Resource not accessible by integration". | |
| permissions: | |
| contents: write | |
| jobs: | |
| build: | |
| name: build ${{ matrix.target }} | |
| runs-on: macos-14 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # Apple Silicon only. MLX upstream CMakeLists.txt errors out on | |
| # x86_64 ("Building for x86_64 on macOS is not supported") so an | |
| # Intel matrix entry is fundamentally not possible with the | |
| # mlx-native feature. | |
| target: | |
| - aarch64-apple-darwin | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| # Tauri's sidecar bundling references the on-disk `lumen-server` | |
| # binary path; the workflow places it relative to the workspace | |
| # root, so the checkout depth must be full (not shallow). | |
| fetch-depth: 0 | |
| # ── Toolchains ──────────────────────────────────────────────── | |
| - name: Install Rust toolchain (with matrix target) | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Cache cargo registry + git + target/ | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: release-${{ matrix.target }} | |
| # Don't cache the lumen-app target/ — Tauri's bundle step | |
| # writes large `.app` directories that bloat the cache key. | |
| workspaces: | | |
| . -> target | |
| - name: Install Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: npm | |
| cache-dependency-path: crates/lumen-app/frontend/package-lock.json | |
| # ── Sibling candle fork (required because Cargo.toml uses path = "../candle") ── | |
| - name: Clone candle fork next to the workspace | |
| run: | | |
| cd .. | |
| if [ ! -d candle ]; then | |
| git clone --depth 1 https://github.com/huggingface/candle.git | |
| fi | |
| ls candle/Cargo.toml | |
| # ── mlx-sys: force-build first so the metallib lands on disk before | |
| # lumen-server's build.rs runs. Without this, a `Swatinem/rust-cache` | |
| # hit can restore mlx-sys's metadata but skip the `out/` directory, | |
| # leaving lumen-server with no metallib to embed. | |
| - name: Pre-build mlx-sys (writes mlx.metallib) | |
| run: | | |
| # mlx-sys's own default features (accelerate + metal) drive the | |
| # CMake build that produces mlx.metallib. No `mlx-native` feature | |
| # exists at the mlx-sys layer — that knob lives one crate up. | |
| cargo clean -p mlx-sys || true | |
| cargo build -p mlx-sys --release --target ${{ matrix.target }} | |
| # Surface the metallib path so the next step (or a failure log) can | |
| # cross-check what build.rs will discover. | |
| echo "--- mlx.metallib search ---" | |
| find target/${{ matrix.target }}/release/build -name mlx.metallib -print 2>/dev/null || true | |
| find target/release/build -name mlx.metallib -print 2>/dev/null || true | |
| # ── Sidecar: build lumen-server, drop it into the bundle path ── | |
| - name: Build lumen-server (sidecar) | |
| run: | | |
| cargo build -p lumen-server --release \ | |
| --target ${{ matrix.target }} \ | |
| --features mlx-native,qwen3_5_moe | |
| mkdir -p crates/lumen-app/binaries | |
| cp target/${{ matrix.target }}/release/lumen-server \ | |
| crates/lumen-app/binaries/lumen-server-${{ matrix.target }} | |
| # ── Frontend install ────────────────────────────────────────── | |
| - name: Install frontend deps | |
| working-directory: crates/lumen-app/frontend | |
| run: npm ci | |
| # ── Tauri build + sign + upload ─────────────────────────────── | |
| - name: Build, sign + upload (.app, .dmg, latest.json) | |
| uses: tauri-apps/tauri-action@v0 | |
| env: | |
| # Automatically provisioned by Actions — needed for the action to | |
| # create the draft release and upload the bundle + signature. | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| # Apple notary credentials (optional; only set on real releases — | |
| # without these the app is signed by the Tauri key but not notarized, | |
| # so users see a Gatekeeper warning on first launch). | |
| APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} | |
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} | |
| APPLE_ID: ${{ secrets.APPLE_ID }} | |
| APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} | |
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| with: | |
| projectPath: crates/lumen-app | |
| # Tag push → use the pushed tag (e.g. v0.2.0). Manual dispatch → | |
| # vTEST-<sha-7> so dry-runs don't collide with real releases. | |
| tagName: ${{ github.event_name == 'push' && github.ref_name || format('vTEST-{0}', github.sha) }} | |
| releaseName: ${{ github.event_name == 'push' && format('Lumen {0}', github.ref_name) || format('Lumen vTEST-{0} (dry-run)', github.sha) }} | |
| releaseDraft: true | |
| prerelease: false | |
| # `--config` injects the sidecar binding so the default | |
| # tauri.conf.json stays clean for `cargo tauri dev`. | |
| args: >- | |
| --target ${{ matrix.target }} | |
| --config '{"bundle":{"externalBin":["binaries/lumen-server"]}}' |