Files
dohooo__helmor/scripts/verify-bundled-cli.sh
Walaff Fernandes e8dbade1bf fix(sidecar): cross-compile sidecar to release target triple (Intel ships arm64 sidecar) (#844)
fix(sidecar): cross-compile sidecar to release target triple

The x86_64 macOS build shipped an arm64 `helmor-sidecar`. Both macOS
matrix targets build on an arm64 runner (macos-26); cargo cross-compiles
the Rust/CLI via `--target`, but `bun build --compile` in build.ts had no
target and emitted a host-arch (arm64) binary. prepare-sidecar.mjs then
copied it to the `-x86_64-apple-darwin` suffix and Tauri bundled it, so
Intel users hit "Failed to start sidecar binary" / "bad CPU type in
executable". Same class as #293, on the one binary the arch guard skipped.

- build.ts: map the target triple (TAURI_TARGET_TRIPLE / CARGO_BUILD_TARGET)
  to a Bun compile target; omit in dev so host builds are unchanged; throw
  on an unmapped-but-set triple instead of silently shipping host arch.
- verify-bundled-cli.sh: add Contents/MacOS/helmor-sidecar to the arch
  check so a wrong-arch sidecar fails CI.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 09:15:45 +08:00

92 lines
2.7 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
if [[ $# -ne 1 ]]; then
echo "Usage: $0 <Helmor.app path>"
exit 1
fi
APP_BUNDLE="$1"
CLI_PATH="${APP_BUNDLE}/Contents/MacOS/helmor-cli"
if [[ ! -d "${APP_BUNDLE}" ]]; then
echo "App bundle not found: ${APP_BUNDLE}"
exit 1
fi
if [[ ! -x "${CLI_PATH}" ]]; then
echo "Bundled CLI missing or not executable: ${CLI_PATH}"
exit 1
fi
echo "Verifying bundled CLI at ${CLI_PATH}..."
OUTPUT="$("${CLI_PATH}" cli-status --json)"
if [[ -z "${OUTPUT}" ]]; then
echo "Bundled CLI returned empty output"
exit 1
fi
if [[ "${OUTPUT}" != *'"buildMode"'* ]] || [[ "${OUTPUT}" != *'"currentBinary"'* ]]; then
echo "Bundled CLI did not return the expected cli-status JSON:"
echo "${OUTPUT}"
exit 1
fi
echo "Bundled CLI smoke check passed."
# ----- Bundled binary architecture check -----------------------------------
# helmor-cli is built per-arch via cargo --target, so its lipo arch is the
# source of truth for what this bundle is targeting. Every other bundled
# executable must match — otherwise an x64 .dmg ends up shipping an arm64
# binary and Intel users see "bad CPU type in executable" (#293).
#
# This includes helmor-sidecar: it's a Bun `--compile` artifact built in
# sidecar/scripts/build.ts, which historically ignored the target triple and
# emitted a host-arch binary. The CLI/vendor checks below did NOT cover it, so
# an arm64 sidecar shipped in the x86_64 release. Keep it first in the list.
EXPECTED_ARCH="$(lipo -archs "${CLI_PATH}")"
case "${EXPECTED_ARCH}" in
arm64|x86_64) ;;
*)
echo "Unexpected helmor-cli arch '${EXPECTED_ARCH}' (want arm64 or x86_64)"
exit 1
;;
esac
# claude-code + codex are now single self-contained native binaries (ripgrep
# / audio-capture are statically embedded), so there's nothing to verify
# under their sub-paths anymore.
VENDOR_ROOT="${APP_BUNDLE}/Contents/Resources/vendor"
VENDOR_BINARIES=(
"${APP_BUNDLE}/Contents/MacOS/helmor-sidecar"
"${VENDOR_ROOT}/gh/gh"
"${VENDOR_ROOT}/glab/glab"
"${VENDOR_ROOT}/codex/codex"
"${VENDOR_ROOT}/claude-code/claude"
)
echo "Verifying vendor binary archs (expect ${EXPECTED_ARCH})..."
mismatches=0
for bin in "${VENDOR_BINARIES[@]}"; do
if [[ ! -e "${bin}" ]]; then
echo " MISSING ${bin}"
mismatches=$((mismatches + 1))
continue
fi
actual="$(lipo -archs "${bin}" 2>/dev/null || echo "?")"
if [[ "${actual}" != "${EXPECTED_ARCH}" ]]; then
echo " MISMATCH ${bin}: got '${actual}', want '${EXPECTED_ARCH}'"
mismatches=$((mismatches + 1))
else
echo " ok ${bin}"
fi
done
if [[ "${mismatches}" -ne 0 ]]; then
echo "Vendor binary arch check failed (${mismatches} issue(s))"
exit 1
fi
echo "Vendor binary arch check passed."