From ab6dd769249a1f1f7b1fba642d70344a6018967e Mon Sep 17 00:00:00 2001 From: mrdulasolutions Date: Tue, 12 May 2026 19:23:05 -0400 Subject: [PATCH] ci(release): pre-import Apple cert into keychain before sidecar build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apple's notarytool rejected v0.1.8 with two errors against Contents/Resources/runtime-modules/better-sqlite3/build/Release/ better_sqlite3.node: - "The binary is not signed with a valid Developer ID certificate." - "The signature does not include a secure timestamp." Root cause: copy-runtime-modules.mjs codesigns the .node file as part of `npm run runtime-modules`, but at that point in the workflow the runner's keychain doesn't yet have the Apple Developer ID cert — tauri-action only imports it later, inside its own ephemeral keychain. PR #7's best-effort patch made the script log a warning and continue when codesign failed, which kept the build from aborting but left the .node unsigned. tauri-bundler's own codesign pass walks Contents/MacOS/ only, not Resources/, so the .node was still unsigned when notarytool inspected the .app. Fix: a new step right before "Build sidecar" mirrors tauri-action's keychain import dance, but against the runner's default login.keychain-db. By the time runtime-modules runs codesign, the identity is available with the secure-timestamp flag enabled, and notarytool accepts the resulting .app. Skipped (with explanatory log) when APPLE_CERTIFICATE secrets are absent — keeps the unsigned-build path functional. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/release.yml | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ac7291f..e734915 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -65,6 +65,56 @@ jobs: - name: Install sidecar npm dependencies run: npm --prefix sidecar ci + - name: Pre-import Apple Developer ID cert into login keychain + env: + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + run: | + # Why this exists: + # + # The next step (`Build sidecar`) runs `npm run runtime-modules`, + # which codesigns better-sqlite3's native .node binary using the + # identity from tauri.conf.json. That binary lives inside + # Contents/Resources/, which tauri-bundler's own codesign pass + # later does NOT walk — we have to sign it ourselves before the + # bundle, or Apple's notarytool rejects the whole .app with + # "The binary is not signed with a valid Developer ID certificate" + # + "The signature does not include a secure timestamp." + # + # tauri-action *does* import the cert into a fresh keychain — but + # only later, when it actually runs `tauri build`. By that point + # the .node has been baked into the .app already. So we mirror + # tauri-action's keychain dance here, ahead of time, into + # login.keychain-db (the runner's default keychain that codesign + # consults). + # + # When tauri-action runs later it creates its own temporary + # keychain and imports the cert again; both keychains end up + # holding the same identity, codesign finds it in either. + if [ -z "$APPLE_CERTIFICATE" ] || [ -z "$APPLE_CERTIFICATE_PASSWORD" ]; then + echo "Apple signing secrets missing — skipping cert pre-import." + echo "Runtime .node files will be left unsigned (matches the" + echo "unsigned-build path; notarization will not pass)." + exit 0 + fi + P12=/tmp/aos-devid.p12 + echo "$APPLE_CERTIFICATE" | base64 -d > "$P12" + # The login keychain on macos-latest runners is empty and has no + # password. unlock with the empty password (no-op if already + # unlocked, but tolerant if it's locked). + security unlock-keychain -p "" ~/Library/Keychains/login.keychain-db 2>/dev/null || true + security import "$P12" -P "$APPLE_CERTIFICATE_PASSWORD" \ + -k ~/Library/Keychains/login.keychain-db \ + -T /usr/bin/codesign -T /usr/bin/productbuild -T /usr/bin/pkgbuild + # Grant codesign non-interactive access to the imported key — + # without this, codesign blocks waiting for a GUI password prompt + # that will never come on a headless runner. + security set-key-partition-list -S apple-tool:,apple:,codesign: \ + -s -k "" ~/Library/Keychains/login.keychain-db + rm -f "$P12" + # Sanity: confirm the identity is now visible. + security find-identity -v -p codesigning ~/Library/Keychains/login.keychain-db + - name: Build sidecar (bundle + package binary) run: | # Full sidecar pipeline — matches package.json's `build:sidecar`