| | |
| | | # Example: "3rd Party Mac Developer Installer: Example Team (TEAMID)" |
| | | # |
| | | # PRIVATEVOICE_APPSTORE_PROVISIONING_PROFILE |
| | | # Path to the Mac App Store provisioning profile for com.privatevoice.input. |
| | | # Path to the Mac App Store provisioning profile for com.shanghai3168.privatevoicedictation. |
| | | # |
| | | # Optional environment: |
| | | # PRIVATEVOICE_SIGNING_KEYCHAIN |
| | |
| | | PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" |
| | | |
| | | INFO_PLIST="$PROJECT_DIR/build/darwin/Info.plist" |
| | | ENTITLEMENTS="$PROJECT_DIR/build/darwin/entitlements-appstore.plist" |
| | | BASE_ENTITLEMENTS="$PROJECT_DIR/build/darwin/entitlements-appstore.plist" |
| | | GOMODCACHE="$(go env GOMODCACHE)" |
| | | SHERPA_MACOS_MODULE_VERSION="$(cd "$PROJECT_DIR" && go list -m -f '{{.Version}}' github.com/k2-fsa/sherpa-onnx-go-macos)" |
| | | |
| | | VERSION="$(defaults read "$INFO_PLIST" CFBundleShortVersionString 2>/dev/null || echo "2.1.0")" |
| | | BUILD_ID="$(defaults read "$INFO_PLIST" CFBundleVersion 2>/dev/null || date +%Y%m%d.%H%M)" |
| | | BUNDLE_ID="$(defaults read "$INFO_PLIST" CFBundleIdentifier 2>/dev/null || echo "")" |
| | | |
| | | step() { |
| | | echo "" |
| | |
| | | codesign --force \ |
| | | --options runtime \ |
| | | --timestamp \ |
| | | --entitlements "$ENTITLEMENTS" \ |
| | | --entitlements "$SIGNING_ENTITLEMENTS" \ |
| | | --sign "$APPSTORE_APP_IDENTITY" \ |
| | | "$item" |
| | | } |
| | | |
| | | plist_set_string() { |
| | | local plist="$1" |
| | | local key="$2" |
| | | local value="$3" |
| | | /usr/libexec/PlistBuddy -c "Delete :$key" "$plist" >/dev/null 2>&1 || true |
| | | /usr/libexec/PlistBuddy -c "Add :$key string $value" "$plist" |
| | | } |
| | | |
| | | strip_extended_attributes() { |
| | | local item="$1" |
| | | if command -v xattr >/dev/null; then |
| | | xattr -cr "$item" 2>/dev/null || true |
| | | fi |
| | | } |
| | | |
| | | assert_no_quarantine_attributes() { |
| | | local item="$1" |
| | | if command -v xattr >/dev/null; then |
| | | local found |
| | | found="$(xattr -lr "$item" 2>/dev/null | grep -F "com.apple.quarantine" | head -n 20 || true)" |
| | | [[ -z "$found" ]] || fail "com.apple.quarantine attributes remain under $item: |
| | | $found" |
| | | fi |
| | | } |
| | | |
| | | TARGET_ARCH="${1:-$(uname -m)}" |
| | |
| | | [[ -n "$APPSTORE_PROVISIONING_PROFILE" ]] || fail "PRIVATEVOICE_APPSTORE_PROVISIONING_PROFILE is required" |
| | | [[ -f "$APPSTORE_PROVISIONING_PROFILE" ]] || fail "Provisioning profile not found: $APPSTORE_PROVISIONING_PROFILE" |
| | | [[ -f "$INFO_PLIST" ]] || fail "Info.plist not found at $INFO_PLIST" |
| | | [[ -f "$ENTITLEMENTS" ]] || fail "App Store entitlements not found at $ENTITLEMENTS" |
| | | [[ -n "$BUNDLE_ID" ]] || fail "CFBundleIdentifier is missing from $INFO_PLIST" |
| | | [[ -f "$BASE_ENTITLEMENTS" ]] || fail "App Store entitlements not found at $BASE_ENTITLEMENTS" |
| | | [[ -f "$PROJECT_DIR/build/darwin/icon.icns" ]] || fail "icon.icns not found" |
| | | [[ -d "$SHERPA_LIB_DIR" ]] || fail "sherpa-onnx dylibs not found at $SHERPA_LIB_DIR" |
| | | ONNXRUNTIME_DYLIB="$(find "$SHERPA_LIB_DIR" -maxdepth 1 -type f -name 'libonnxruntime.*.dylib' | sort | tail -n 1)" |
| | |
| | | fail "App Store installer signing identity not found: $APPSTORE_INSTALLER_IDENTITY" |
| | | command -v productbuild >/dev/null || fail "productbuild not found" |
| | | command -v pkgutil >/dev/null || fail "pkgutil not found" |
| | | |
| | | PROFILE_PLIST="$(mktemp)" |
| | | SIGNING_ENTITLEMENTS="$(mktemp)" |
| | | trap 'rm -f "$PROFILE_PLIST" "$SIGNING_ENTITLEMENTS"' EXIT |
| | | security cms -D -i "$APPSTORE_PROVISIONING_PROFILE" >"$PROFILE_PLIST" || |
| | | fail "Unable to decode provisioning profile: $APPSTORE_PROVISIONING_PROFILE" |
| | | PROFILE_APP_IDENTIFIER="$(/usr/libexec/PlistBuddy -c "Print :Entitlements:com.apple.application-identifier" "$PROFILE_PLIST" 2>/dev/null || true)" |
| | | PROFILE_TEAM_IDENTIFIER="$(/usr/libexec/PlistBuddy -c "Print :Entitlements:com.apple.developer.team-identifier" "$PROFILE_PLIST" 2>/dev/null || true)" |
| | | PROFILE_KEYCHAIN_GROUP="$(/usr/libexec/PlistBuddy -c "Print :Entitlements:keychain-access-groups:0" "$PROFILE_PLIST" 2>/dev/null || true)" |
| | | PROFILE_BUNDLE_ID="${PROFILE_APP_IDENTIFIER#*.}" |
| | | [[ "$PROFILE_BUNDLE_ID" == "$BUNDLE_ID" ]] || |
| | | fail "Provisioning profile bundle ID mismatch: profile has $PROFILE_BUNDLE_ID, app has $BUNDLE_ID" |
| | | [[ -n "$PROFILE_TEAM_IDENTIFIER" ]] || fail "Provisioning profile missing com.apple.developer.team-identifier entitlement" |
| | | |
| | | cp "$BASE_ENTITLEMENTS" "$SIGNING_ENTITLEMENTS" |
| | | plist_set_string "$SIGNING_ENTITLEMENTS" "com.apple.application-identifier" "$PROFILE_APP_IDENTIFIER" |
| | | plist_set_string "$SIGNING_ENTITLEMENTS" "com.apple.developer.team-identifier" "$PROFILE_TEAM_IDENTIFIER" |
| | | if [[ -n "$PROFILE_KEYCHAIN_GROUP" ]]; then |
| | | /usr/libexec/PlistBuddy -c "Delete :keychain-access-groups" "$SIGNING_ENTITLEMENTS" >/dev/null 2>&1 || true |
| | | /usr/libexec/PlistBuddy -c "Add :keychain-access-groups array" "$SIGNING_ENTITLEMENTS" |
| | | /usr/libexec/PlistBuddy -c "Add :keychain-access-groups:0 string $PROFILE_KEYCHAIN_GROUP" "$SIGNING_ENTITLEMENTS" |
| | | fi |
| | | |
| | | step "Cleaning old Mac App Store build" |
| | | rm -rf "$BUILD_DIR" |
| | |
| | | cp "$SHERPA_LIB_DIR/libsherpa-onnx-c-api.dylib" "$APP_BUNDLE/Contents/Frameworks/" |
| | | cp "$ONNXRUNTIME_DYLIB" "$APP_BUNDLE/Contents/Frameworks/" |
| | | |
| | | step "Removing extended attributes from app bundle" |
| | | strip_extended_attributes "$APP_BUNDLE" |
| | | assert_no_quarantine_attributes "$APP_BUNDLE" |
| | | |
| | | step "Fixing rpaths" |
| | | install_name_tool -add_rpath @executable_path/../Frameworks \ |
| | | "$APP_BUNDLE/Contents/MacOS/$APP_NAME" 2>/dev/null || true |
| | |
| | | sign_sandboxed "$APP_BUNDLE/Contents/MacOS/$APP_NAME" |
| | | sign_sandboxed "$APP_BUNDLE" |
| | | |
| | | step "Removing extended attributes after signing" |
| | | strip_extended_attributes "$APP_BUNDLE" |
| | | assert_no_quarantine_attributes "$APP_BUNDLE" |
| | | |
| | | step "Verifying app signature and entitlements" |
| | | codesign -vvv --deep --strict "$APP_BUNDLE" |
| | | codesign -d --entitlements :- "$APP_BUNDLE" |
| | | SIGNED_ENTITLEMENTS="$(mktemp)" |
| | | codesign -d --entitlements :- "$APP_BUNDLE" >"$SIGNED_ENTITLEMENTS" 2>/dev/null |
| | | SIGNED_APP_IDENTIFIER="$(/usr/libexec/PlistBuddy -c "Print :com.apple.application-identifier" "$SIGNED_ENTITLEMENTS" 2>/dev/null || true)" |
| | | rm -f "$SIGNED_ENTITLEMENTS" |
| | | [[ "$SIGNED_APP_IDENTIFIER" == "$PROFILE_APP_IDENTIFIER" ]] || |
| | | fail "Signed app application-identifier mismatch: signed has $SIGNED_APP_IDENTIFIER, profile has $PROFILE_APP_IDENTIFIER" |
| | | |
| | | step "Creating signed installer package" |
| | | productbuild \ |