Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,75 @@ jobs:
echo "notarization: DISABLED (no API key or Apple ID secrets)"
fi

# The computerd bundle is a nested .app *resource* inside the Tauri app
# (Resources/jcode-computerd.app). Tauri signs the outer app and its
# externalBin sidecars with Developer ID, but does NOT re-sign resource
# bundles — so the ad-hoc signature applied by build_computerd_bundle.sh
# would survive into the notarization upload and Apple rejects it ("not
# signed with a valid Developer ID certificate" / "no secure timestamp" /
# "hardened runtime not enabled"). Re-sign the nested bundle here, before
# `tauri build`, so the outer signature references a properly signed inner
# bundle. Skipped when signing is disabled (no APPLE_CERTIFICATE): Tauri
# then neither signs nor notarizes, and the ad-hoc bundle is fine for an
# unsigned local build.
- name: Sign computerd bundle (Developer ID)
if: runner.os == 'macOS'
shell: bash
run: |
set -euo pipefail
if [ -z "${APPLE_CERTIFICATE:-}" ]; then
echo "code-signing disabled — leaving ad-hoc signature (no notarization)"
exit 0
fi
BUNDLE="desktop/src-tauri/bundles/jcode-computerd.app"

# Import the Developer ID certificate into a throwaway keychain so
# codesign can use it. Tauri builds its own keychain later for the
# outer app; the two coexist.
KEYCHAIN="$RUNNER_TEMP/computerd-signing.keychain-db"
KEYCHAIN_PW="$(openssl rand -hex 16)"
security create-keychain -p "$KEYCHAIN_PW" "$KEYCHAIN"
security set-keychain-settings -lut 21600 "$KEYCHAIN"
security unlock-keychain -p "$KEYCHAIN_PW" "$KEYCHAIN"
CERT="$RUNNER_TEMP/computerd-cert.p12"
echo -n "$APPLE_CERTIFICATE" | base64 --decode > "$CERT"
security import "$CERT" -P "$APPLE_CERTIFICATE_PASSWORD" \
-A -t cert -f pkcs12 -k "$KEYCHAIN"
security set-key-partition-list -S apple-tool:,apple: \
-k "$KEYCHAIN_PW" "$KEYCHAIN" >/dev/null
# Prepend our keychain so codesign resolves the identity. The
# unquoted substitution is intentional: it expands to the list of
# existing keychain paths, each a separate argument.
# shellcheck disable=SC2046
security list-keychains -d user -s "$KEYCHAIN" \
$(security list-keychains -d user | tr -d '"')

# Resolve the signing identity (fall back to the first valid
# codesigning identity in the keychain when not explicitly set).
IDENTITY="${APPLE_SIGNING_IDENTITY:-}"
if [ -z "$IDENTITY" ]; then
IDENTITY="$(security find-identity -v -p codesigning "$KEYCHAIN" | awk -F'"' 'NR==1{print $2}')"
fi
[ -n "$IDENTITY" ] || { echo "no Developer ID signing identity found" >&2; exit 1; }

# Sign from the inside out: workers first, then the daemon, then the
# bundle wrapper. Hardened runtime (--options runtime) + a secure
# timestamp are both mandatory for notarization. A shared identifier
# keeps the three binaries under one TCC identity (see the bundle
# script header). The daemon uses only AX + ScreenCaptureKit, which
# work under hardened runtime without extra entitlements.
for bin in jcode-computerd-capture jcode-computerd-onboarding jcode-computerd; do
[ -x "$BUNDLE/Contents/MacOS/$bin" ] || continue
codesign --force --options runtime --timestamp \
--sign "$IDENTITY" --identifier com.cnjack.jcode.computerd \
"$BUNDLE/Contents/MacOS/$bin"
done
codesign --force --options runtime --timestamp \
--sign "$IDENTITY" "$BUNDLE"

echo "Signed nested bundle with: $IDENTITY"
codesign --verify --deep --strict --verbose=2 "$BUNDLE"

- name: Build desktop bundle
shell: bash
working-directory: desktop
Expand Down
Loading