From fed719ca42343e3481dce77a69ba6165e06e9c03 Mon Sep 17 00:00:00 2001 From: YJack0000 Date: Mon, 29 Jun 2026 20:39:33 +0800 Subject: [PATCH 1/6] [fix] grant codesign keychain access to unblock CI signing hang --- .github/workflows/release.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cbc9b6f..d68370c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -114,10 +114,15 @@ jobs: security default-keychain -s "$KEYCHAIN_PATH" security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" - # Import certificate + # Import certificate. Grant /usr/bin/codesign (and productsign) explicit + # access to the imported private key via -T, then add `codesign:` to the + # key partition list so codesign can use the key non-interactively. Without + # the codesign partition, codesign blocks on a GUI keychain-auth prompt that + # can never appear on CI, hanging the build at "replacing existing signature". echo "$APPLE_CERTIFICATE" | base64 --decode > "$CERT_PATH" - security import "$CERT_PATH" -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH" - security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + security import "$CERT_PATH" -P "$APPLE_CERTIFICATE_PASSWORD" -t cert -f pkcs12 -k "$KEYCHAIN_PATH" -T /usr/bin/codesign -T /usr/bin/productsign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + security find-identity -v -p codesigning "$KEYCHAIN_PATH" - name: Prepare Apple API Key if: ${{ env.APPLE_API_KEY != '' && env.APPLE_API_ISSUER != '' && env.APPLE_API_KEY_CONTENT != '' }} From 3bb01dfa82bac3d6c524c8185cc5b84f93518877 Mon Sep 17 00:00:00 2001 From: YJack0000 Date: Mon, 29 Jun 2026 22:28:26 +0800 Subject: [PATCH 2/6] [fix] disable keychain auto-lock so codesign does not hang mid-build --- .github/workflows/release.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d68370c..0419a1e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -109,10 +109,15 @@ jobs: KEYCHAIN_PATH="${{ runner.temp }}/build.keychain" KEYCHAIN_PASSWORD=$(openssl rand -base64 24) - # Create keychain + # Create keychain. Disable the auto-lock timeout (-lut 21600 = 6h, and no + # -l so it does not lock on sleep): a freshly created keychain otherwise + # re-locks after the default ~5min idle. The Rust build before codesign runs + # takes far longer than that, so without this the keychain re-locks mid-build + # and codesign then hangs on a keychain-auth prompt at signing time. security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" security default-keychain -s "$KEYCHAIN_PATH" security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" # Import certificate. Grant /usr/bin/codesign (and productsign) explicit # access to the imported private key via -T, then add `codesign:` to the From 238da7f0a41ec4562093adcbb27dd9bb5828c3e3 Mon Sep 17 00:00:00 2001 From: YJack0000 Date: Mon, 29 Jun 2026 22:39:38 +0800 Subject: [PATCH 3/6] [fix] import Apple intermediate certs so codesign chain resolves in CI --- .github/workflows/release.yml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0419a1e..9f1e9d7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -126,8 +126,26 @@ jobs: # can never appear on CI, hanging the build at "replacing existing signature". echo "$APPLE_CERTIFICATE" | base64 --decode > "$CERT_PATH" security import "$CERT_PATH" -P "$APPLE_CERTIFICATE_PASSWORD" -t cert -f pkcs12 -k "$KEYCHAIN_PATH" -T /usr/bin/codesign -T /usr/bin/productsign + + # The exported .p12 contains only the leaf "Developer ID Application" cert, + # not Apple's intermediate/root. Without the full chain, codesign fails with + # `errSecInternalComponent` ("unable to build chain to self-signed root") and + # the Tauri build exits 1 at signing time. Import Apple's Developer ID G2 + # intermediate + Apple Root so the chain resolves. (Verified locally: leaf + # alone → 0 valid identities + sign failure; leaf + these two → 1 valid + sign OK.) + curl -fsSL -o "${{ runner.temp }}/DeveloperIDG2CA.cer" https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer + curl -fsSL -o "${{ runner.temp }}/AppleRoot.cer" https://www.apple.com/appleca/AppleIncRootCertificate.cer + security import "${{ runner.temp }}/DeveloperIDG2CA.cer" -k "$KEYCHAIN_PATH" + security import "${{ runner.temp }}/AppleRoot.cer" -k "$KEYCHAIN_PATH" + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" - security find-identity -v -p codesigning "$KEYCHAIN_PATH" + + # Assert a usable signing identity exists. `find-identity` exits 0 even with + # "0 valid identities found", so grep for an actual match — otherwise fail + # loudly here instead of ambiguously mid-build at codesign time. + security find-identity -v -p codesigning "$KEYCHAIN_PATH" | tee /tmp/identities.txt + grep -q '1 valid identities found\|[1-9][0-9]* valid identities found' /tmp/identities.txt \ + || { echo "::error::No valid code-signing identity in keychain (cert chain incomplete?)"; exit 1; } - name: Prepare Apple API Key if: ${{ env.APPLE_API_KEY != '' && env.APPLE_API_ISSUER != '' && env.APPLE_API_KEY_CONTENT != '' }} From f428f346afaa5fa9d5179d103aaabdf2a439b990 Mon Sep 17 00:00:00 2001 From: YJack0000 Date: Mon, 29 Jun 2026 22:46:10 +0800 Subject: [PATCH 4/6] [fix] add build keychain to search list so codesign finds the identity --- .github/workflows/release.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9f1e9d7..67544f6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -114,6 +114,11 @@ jobs: # re-locks after the default ~5min idle. The Rust build before codesign runs # takes far longer than that, so without this the keychain re-locks mid-build # and codesign then hangs on a keychain-auth prompt at signing time. + # Remember the existing search-list keychains (login/System) BEFORE we touch + # anything — they carry the trusted Apple Root anchor needed to validate the + # signing identity. + ORIGINAL_KEYCHAINS=$(security list-keychains -d user | sed 's/[\" ]//g') + security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" security default-keychain -s "$KEYCHAIN_PATH" security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" @@ -140,6 +145,14 @@ jobs: security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + # THE key fix for "no identity found" mid-build: `default-keychain -s` does + # NOT add the keychain to the search list, but codesign resolves identities + # via the SEARCH LIST. Add the build keychain to the search list while keeping + # the original keychains (login/System) so the Apple Root trust anchor still + # resolves. (Verified locally: build keychain as sole default → codesign "no + # identity found"; build keychain + login in search list → codesign OK.) + security list-keychains -d user -s "$KEYCHAIN_PATH" $ORIGINAL_KEYCHAINS + # Assert a usable signing identity exists. `find-identity` exits 0 even with # "0 valid identities found", so grep for an actual match — otherwise fail # loudly here instead of ambiguously mid-build at codesign time. From 8e9237b06c9811060c4425a5d6a6bfd701627791 Mon Sep 17 00:00:00 2001 From: YJack0000 Date: Mon, 29 Jun 2026 22:56:16 +0800 Subject: [PATCH 5/6] [fix] tolerate pre-existing Apple intermediates under bash -e in CI --- .github/workflows/release.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 67544f6..6eab7d7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -133,15 +133,15 @@ jobs: security import "$CERT_PATH" -P "$APPLE_CERTIFICATE_PASSWORD" -t cert -f pkcs12 -k "$KEYCHAIN_PATH" -T /usr/bin/codesign -T /usr/bin/productsign # The exported .p12 contains only the leaf "Developer ID Application" cert, - # not Apple's intermediate/root. Without the full chain, codesign fails with - # `errSecInternalComponent` ("unable to build chain to self-signed root") and - # the Tauri build exits 1 at signing time. Import Apple's Developer ID G2 - # intermediate + Apple Root so the chain resolves. (Verified locally: leaf - # alone → 0 valid identities + sign failure; leaf + these two → 1 valid + sign OK.) - curl -fsSL -o "${{ runner.temp }}/DeveloperIDG2CA.cer" https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer - curl -fsSL -o "${{ runner.temp }}/AppleRoot.cer" https://www.apple.com/appleca/AppleIncRootCertificate.cer - security import "${{ runner.temp }}/DeveloperIDG2CA.cer" -k "$KEYCHAIN_PATH" - security import "${{ runner.temp }}/AppleRoot.cer" -k "$KEYCHAIN_PATH" + # not Apple's intermediate/root. Best-effort import Apple's Developer ID G2 + # intermediate + Apple Root so the chain resolves on runners that lack them. + # GitHub runners usually already have these, in which case `security import` + # reports "already exists" (non-zero) — tolerate that (and any curl hiccup) so + # the step does not abort under `bash -e`. + curl -fsSL -o "${{ runner.temp }}/DeveloperIDG2CA.cer" https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer || true + curl -fsSL -o "${{ runner.temp }}/AppleRoot.cer" https://www.apple.com/appleca/AppleIncRootCertificate.cer || true + security import "${{ runner.temp }}/DeveloperIDG2CA.cer" -k "$KEYCHAIN_PATH" 2>/dev/null || true + security import "${{ runner.temp }}/AppleRoot.cer" -k "$KEYCHAIN_PATH" 2>/dev/null || true security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" From 2bd6167cc431ea3c648a893bcd90a34b0ddb0cf0 Mon Sep 17 00:00:00 2001 From: YJack0000 Date: Mon, 29 Jun 2026 23:15:26 +0800 Subject: [PATCH 6/6] [fix] sign bundled onnxruntime dylib so notarization passes --- .github/workflows/release.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6eab7d7..923d162 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -168,6 +168,21 @@ jobs: chmod 600 "${{ runner.temp }}/private_keys/AuthKey_${{ env.APPLE_API_KEY }}.p8" echo "APPLE_API_KEY_PATH=${{ runner.temp }}/private_keys/AuthKey_${{ env.APPLE_API_KEY }}.p8" >> $GITHUB_ENV + - name: Sign bundled ONNX Runtime dylib + if: ${{ env.APPLE_SIGNING_IDENTITY != '' }} + run: | + # libonnxruntime.dylib ships as a bundle resource (loaded at runtime via + # ORT_DYLIB_PATH). Tauri signs the main binary + .app shell but NOT this + # nested dylib, so notarization rejects the archive with "The binary is not + # signed" for Contents/Resources/onnxruntime/libonnxruntime.dylib. Sign it + # with Developer ID + hardened runtime + secure timestamp BEFORE the build — + # the signature survives being copied into the .app and the .app re-sign + # (verified locally: bundled dylib keeps the full Developer ID chain + timestamp). + codesign --force --options runtime --timestamp \ + --sign "$APPLE_SIGNING_IDENTITY" \ + src-tauri/onnxruntime/libonnxruntime.dylib + codesign --verify --strict --verbose=2 src-tauri/onnxruntime/libonnxruntime.dylib + - name: Build and upload Tauri bundles uses: tauri-apps/tauri-action@84b9d35b5fc46c1e45415bdb6144030364f7ebc5 # v0.6.2 env: