fix(ci): ensure sidecar architecture matches target in macOS releases (#637)

* fix(ci): pass target architecture to beforeBuildCommand

Set TAURI_ENV_TARGET_TRIPLE environment variable before running
build commands to ensure sidecar binary matches target architecture.

Problem:
- CI builds both arm64 and x86_64 targets in parallel on arm64 runner
- beforeBuildCommand executes before Tauri sets TAURI_ENV_TARGET_TRIPLE
- build-sidecar.mjs fallbacks to process.arch (arm64 on CI runner)
- Both parallel tasks build arm64 sidecars, second task overwrites first
- Result: x86_64 releases contain arm64 sidecar → startup failure on Intel Macs

Solution:
- Explicitly set TAURI_ENV_TARGET_TRIPLE in CI workflow
- Add architecture verification step to detect mismatches early

Evidence:
- Official DMG OpenChamber_1.8.5_darwin-x86_64.dmg contains arm64 sidecar
- Local build with explicit env var produces correct x86_64 sidecar
- /Applications/OpenChamber.app/Contents/MacOS/openchamber-server: arm64
- packages/desktop/src-tauri/sidecars/...: x86_64 (with env var)

Fixes startup failure on Intel Macs where official x86_64 DMG
contains arm64 sidecar binary, causing indefinite loading screen.

* fix(ci): normalize architecture names in verification step

Fix architecture mismatch where macOS 'file' command reports ARM binaries
as 'arm64' but verification expects 'aarch64', causing false negatives
in ARM builds.

Changes:
- Update grep pattern to include 'arm64' in extraction
- Add normalize_arch() function to map arm64 -> aarch64
- Improve debug output to show raw and normalized architectures
- Update error messages to show both raw and normalized values

This fixes the issue reported by @btriapitsyn where ARM builds would
fail verification even with correct artifacts, because:
- macOS file command reports: 'Mach-O 64-bit executable arm64'
- Old grep pattern only matched: 'x86_64|aarch64'
- Result: empty string != 'aarch64' → false failure

The normalization ensures consistency between:
- macOS file output (arm64/x86_64)
- Rust/Cargo naming (aarch64/x86_64)
- Tauri target triples (aarch64-apple-darwin/x86_64-apple-darwin)

Fixes architecture verification for both ARM and Intel builds.
This commit is contained in:
kalac2232
2026-03-12 17:56:45 +02:00
committed by GitHub
parent d1650343b1
commit 77467311f1
+61 -1
View File
@@ -166,8 +166,12 @@ jobs:
- name: Build Desktop app
# Note: We use inline commands instead of desktop:build to pass architecture-specific --target flag
# This enables cross-compilation for both arm64 and x86_64 from the same runner
run: bun run --cwd packages/desktop build && bun run --cwd packages/desktop tauri build --target ${{ matrix.target }}
run: |
export TAURI_ENV_TARGET_TRIPLE=${{ matrix.target }}
bun run --cwd packages/desktop build
bun run --cwd packages/desktop tauri build --target ${{ matrix.target }}
env:
TAURI_ENV_TARGET_TRIPLE: ${{ matrix.target }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
@@ -175,6 +179,62 @@ jobs:
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
- name: Verify binary architectures
run: |
set -euo pipefail
BUNDLE_DIR="packages/desktop/src-tauri/target/${{ matrix.target }}/release/bundle/macos"
if [ ! -d "$BUNDLE_DIR" ]; then
echo "❌ Error: bundle directory not found: $BUNDLE_DIR"
exit 1
fi
APP_PATH=$(find "$BUNDLE_DIR" -maxdepth 2 -name "*.app" -print -quit)
if [ -z "$APP_PATH" ]; then
echo "❌ Error: .app bundle not found under $BUNDLE_DIR"
exit 1
fi
echo "🔍 Verifying binary architectures in $APP_PATH"
# Extract raw architecture names (macOS file command reports ARM as "arm64")
MAIN_ARCH_RAW=$(file "$APP_PATH/Contents/MacOS/openchamber-desktop" | grep -oE 'arm64|x86_64|aarch64' | head -1)
SIDEARCH_ARCH_RAW=$(file "$APP_PATH/Contents/MacOS/openchamber-server" | grep -oE 'arm64|x86_64|aarch64' | head -1)
# Normalize architecture names (arm64 -> aarch64 for consistency with Rust/Tauri)
normalize_arch() {
case "$1" in
arm64) echo "aarch64" ;;
aarch64|x86_64) echo "$1" ;;
*) echo "unknown" ;;
esac
}
MAIN_ARCH=$(normalize_arch "$MAIN_ARCH_RAW")
SIDEARCH_ARCH=$(normalize_arch "$SIDEARCH_ARCH_RAW")
EXPECTED_ARCH=$(echo "${{ matrix.target }}" | grep -oE 'aarch64|x86_64' | head -1)
echo " Main: $MAIN_ARCH_RAW → $MAIN_ARCH"
echo " Sidecar: $SIDEARCH_ARCH_RAW → $SIDEARCH_ARCH"
echo " Expected: $EXPECTED_ARCH"
if [ "$MAIN_ARCH" != "$EXPECTED_ARCH" ]; then
echo "❌ ERROR: Main binary architecture mismatch!"
echo " Expected: $EXPECTED_ARCH"
echo " Got: $MAIN_ARCH (raw: $MAIN_ARCH_RAW)"
exit 1
fi
if [ "$SIDEARCH_ARCH" != "$EXPECTED_ARCH" ]; then
echo "❌ ERROR: Sidecar binary architecture mismatch!"
echo " Expected: $EXPECTED_ARCH"
echo " Got: $SIDEARCH_ARCH (raw: $SIDEARCH_ARCH_RAW)"
exit 1
fi
echo "✅ Architecture verification passed: both binaries match $EXPECTED_ARCH"
- name: Verify macOS entitlements
run: |
set -euo pipefail