mirror of
https://github.com/praktimarc/kst4contest.git
synced 2026-09-11 19:55:40 +02:00
Macos signing (#80)
* Sign and notarize macOS builds jpackage cannot produce a distributable macOS bundle on its own. It ad-hoc signs the embedded runtime and then re-runs codesign on the same files without --force, which codesign rejects; and "--type dmg --app-image" re-signs the app it is handed, replacing a Developer ID signature with an ad-hoc one. So the build now creates an unsigned app-image, signs it from the inside out, and wraps it with hdiutil. Apple's notary service also unpacks JARs and checks the native libraries inside them, which sqlite-jdbc ships for both architectures. Those are signed before the bundle is sealed, since rewriting a JAR afterwards would invalidate the seal. A preflight check verifies Apple's two criteria locally, so a missed binary costs seconds rather than a round trip to the notary service. Two long-standing defects surfaced while testing and are fixed here: the bundle identifier defaulted to the main class's package name (kst4contest.view instead of de.x08.KST4Contest), and every release reported version 1.0 in Finder because --app-version was never passed. Neither affects existing users: the app keeps its settings in ~/.praktiKST, independent of the bundle ID. Both workflows call the same script the local Mac uses, so the two cannot drift apart. Signing needs a keychain that can answer a UI prompt, which a runner cannot, so ci-import-cert.sh creates a throwaway keychain whose password is generated per job and discarded with it. Notarization goes through an App Store Connect API key and needs no keychain at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Sign bundle contents serially Signing the app image's Mach-O files with "xargs -P 8" passed locally but failed on a runner: codesign reported "replacing existing signature" and then "No such file or directory" for that same path. The two libjli.dylib copies are separate inodes, so this is not hard links being signed twice -- concurrent codesign runs over one bundle are simply not reliable. Serially costs about a minute, since each call waits on Apple's timestamp server. Also stop the matrix from cancelling the other architecture on a failure; that throws away half the diagnostic information from a failed run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Document macOS signing from 1.42 The installation guides described the right-click workaround as the normal first launch. That stays, but as the path for 1.41.1 and older; from 1.42 a double-click works. Both guides also show how to verify a download with spctl, so the claim is checkable rather than something to take on faith. The per-channel download notes distinguish where the channels actually stand: Nightly is built from main and is signed as of now, while Stable still points at 1.41.1, so those notes name the version instead of claiming it outright. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Executable
+64
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Import the Developer ID certificate into a throwaway keychain on a CI runner.
|
||||
#
|
||||
# A runner cannot answer the keychain's authorization dialog, so the login
|
||||
# keychain is unusable there. This creates a dedicated keychain instead, whose
|
||||
# password is generated here and needed nowhere else -- it is discarded with the
|
||||
# keychain at the end of the job.
|
||||
#
|
||||
# Reads from the environment:
|
||||
# MACOS_CERT_P12 base64 of the exported .p12
|
||||
# MACOS_CERT_PASSWORD the password that .p12 was exported with
|
||||
#
|
||||
# Exports to $GITHUB_ENV:
|
||||
# SIGNING_IDENTITY for packaging/macos/build-signed-dmg.sh
|
||||
# SIGNING_KEYCHAIN so the cleanup step knows what to delete
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
: "${MACOS_CERT_P12:?MACOS_CERT_P12 is not set}"
|
||||
: "${MACOS_CERT_PASSWORD:?MACOS_CERT_PASSWORD is not set}"
|
||||
: "${RUNNER_TEMP:?RUNNER_TEMP is not set}"
|
||||
: "${GITHUB_ENV:?GITHUB_ENV is not set}"
|
||||
|
||||
KEYCHAIN="$RUNNER_TEMP/kst4contest-signing.keychain-db"
|
||||
KEYCHAIN_PASSWORD="$(uuidgen)"
|
||||
CERT="$RUNNER_TEMP/cert.p12"
|
||||
|
||||
printf '%s' "$MACOS_CERT_P12" | base64 --decode > "$CERT"
|
||||
|
||||
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN"
|
||||
# Keychains re-lock after five minutes by default, which would strand a build
|
||||
# halfway through signing.
|
||||
security set-keychain-settings -lut 21600 "$KEYCHAIN"
|
||||
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN"
|
||||
|
||||
security import "$CERT" -k "$KEYCHAIN" -P "$MACOS_CERT_PASSWORD" \
|
||||
-T /usr/bin/codesign -T /usr/bin/security
|
||||
rm -f "$CERT"
|
||||
|
||||
# Lets codesign reach the private key without the UI prompt a runner has no way
|
||||
# of answering.
|
||||
security set-key-partition-list -S apple-tool:,apple:,codesign: \
|
||||
-s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN" >/dev/null
|
||||
|
||||
# codesign searches the keychain list, so the new keychain has to be on it --
|
||||
# added to whatever the runner already had, not in place of it.
|
||||
EXISTING_KEYCHAINS="$(security list-keychains -d user | sed -e 's/^[[:space:]]*"//' -e 's/"$//')"
|
||||
# shellcheck disable=SC2086
|
||||
security list-keychains -d user -s "$KEYCHAIN" $EXISTING_KEYCHAINS
|
||||
|
||||
IDENTITY="$(security find-identity -v -p codesigning "$KEYCHAIN" \
|
||||
| sed -n 's/.*"Developer ID Application: \(.*\)".*/\1/p' | head -n 1)"
|
||||
|
||||
if [ -z "$IDENTITY" ]; then
|
||||
echo "No 'Developer ID Application' identity found in the imported certificate." >&2
|
||||
echo "What the keychain does contain:" >&2
|
||||
security find-identity -v -p codesigning "$KEYCHAIN" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Imported identity: Developer ID Application: $IDENTITY"
|
||||
echo "SIGNING_IDENTITY=$IDENTITY" >> "$GITHUB_ENV"
|
||||
echo "SIGNING_KEYCHAIN=$KEYCHAIN" >> "$GITHUB_ENV"
|
||||
Reference in New Issue
Block a user