From 244deeb727018523cb77a51cf8f22f2a86ea194b Mon Sep 17 00:00:00 2001 From: Test Date: Fri, 6 Mar 2026 08:43:54 +0100 Subject: [PATCH] fix: sign qmd binaries with Developer ID + hardened runtime for notarization Apple notarization rejected qmd/qmd and qmd/vec0.dylib due to: - Not signed with valid Developer ID certificate - Hardened runtime not enabled Changes: - bundle-qmd.sh: use APPLE_SIGNING_IDENTITY + --options runtime --timestamp in CI (falls back to ad-hoc signing in dev when no identity is set) - useThemeManager.test.ts: add ensure_vault_themes to mock (added by theme editor feature, missing from stale theme ID test mock) --- scripts/bundle-qmd.sh | 19 +++++++++++++++---- src/hooks/useThemeManager.test.ts | 1 + 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/scripts/bundle-qmd.sh b/scripts/bundle-qmd.sh index 8fc18cf4..8bbbe5f9 100755 --- a/scripts/bundle-qmd.sh +++ b/scripts/bundle-qmd.sh @@ -129,11 +129,22 @@ export class LlamaChatSession { export const LlamaLogLevel = { Error: 0, Warn: 1, Info: 2, Debug: 3 }; STUB -# ---------- ad-hoc code signing (macOS) ---------- +# ---------- code signing (macOS) ---------- +# In CI (APPLE_SIGNING_IDENTITY set): sign with Developer ID + hardened runtime (required for notarization) +# In dev (no identity): ad-hoc sign to remove quarantine if [[ "$(uname)" == "Darwin" ]] && command -v codesign &>/dev/null; then - echo "Ad-hoc signing bundled binaries..." - codesign --force --sign - "$OUT/qmd" 2>/dev/null && echo " ✓ qmd signed" || echo " ⚠ qmd signing failed (non-fatal)" - find "$OUT/node_modules" -name "*.dylib" -exec sh -c 'codesign --force --sign - "$1" 2>/dev/null && echo " ✓ $(basename "$1") signed"' _ {} \; + SIGN_ID="${APPLE_SIGNING_IDENTITY:--}" + if [[ "$SIGN_ID" != "-" ]]; then + echo "Signing bundled binaries with Developer ID: $SIGN_ID" + SIGN_OPTS=(--force --sign "$SIGN_ID" --options runtime --timestamp) + else + echo "Ad-hoc signing bundled binaries (dev mode)..." + SIGN_OPTS=(--force --sign -) + fi + codesign "${SIGN_OPTS[@]}" "$OUT/qmd" 2>/dev/null && echo " ✓ qmd signed" || echo " ⚠ qmd signing failed (non-fatal)" + while IFS= read -r -d '' dylib; do + codesign "${SIGN_OPTS[@]}" "$dylib" 2>/dev/null && echo " ✓ $(basename "$dylib") signed" || echo " ⚠ $(basename "$dylib") signing failed (non-fatal)" + done < <(find "$OUT/node_modules" -name "*.dylib" -print0) fi # ---------- summary ---------- diff --git a/src/hooks/useThemeManager.test.ts b/src/hooks/useThemeManager.test.ts index 4dbaae84..5ad52bea 100644 --- a/src/hooks/useThemeManager.test.ts +++ b/src/hooks/useThemeManager.test.ts @@ -371,6 +371,7 @@ describe('useThemeManager', () => { mockInvokeFn.mockImplementation(async (cmd: string) => { if (cmd === 'get_vault_settings') return { theme: 'untitled-2' } if (cmd === 'set_active_theme') return null + if (cmd === 'ensure_vault_themes') return null return null })