Руководство

Как подписать и нотаризовать приложение Electron или Tauri для Mac из Windows или Linux

Приложение на Electron или Tauri можно писать на Windows или Linux. С релизом для macOS всё иначе. Инструменты Apple для подписи и нотаризации работают только на macOS. Без них пользователи Mac видят предупреждение, и приложение не открывается. Здесь показаны шаги сборки, подписи и нотаризации с командами, которые мы запускали.

Почему шагу для Mac нужна macOS

Работу делают три инструмента Apple. codesign подписывает приложение. notarytool отправляет его в службу нотаризации Apple. stapler прикрепляет билет, который Apple присылает в ответ. Все три входят в macOS и Xcode. Версии для Windows или Linux от Apple нет.

Документация фреймворков с этим согласна. Tauri советует запускать tauri build на компьютере Mac. Electron Forge пишет, что для нотаризации нужен Xcode. Мы также проверили сторону Linux на GitHub Actions. Electron Forge на Ubuntu создал .deb и .rpm. Запрос пакета для macOS упал.

Что нужно до дня релиза

  • Платное участие в Apple Developer Program. Apple указывает цену 99 USD в год.
  • Сертификат Developer ID Application. Создать его может только Account Holder команды, в Xcode или на сайте для разработчиков.
  • Пароль приложения для вашего Apple Account или API-ключ App Store Connect.
  • Ваш Team ID, код из 10 символов из аккаунта разработчика.

Служба нотаризации Apple также требует hardened runtime и защищённую метку времени. electron-builder включает hardened runtime одной строкой в конфигурации, она показана ниже.

Как выглядит сборка без подписи

Мы собрали официальный шаблон create-tauri-app без сертификата. Вот проверки, которые мы запустили на результате:

npm create tauri-app@latest tauri-app -- --template vanilla --manager npm --yes
cd tauri-app && npm install
rustup target add aarch64-apple-darwin x86_64-apple-darwin
npm run tauri build -- --target universal-apple-darwin

APP=src-tauri/target/universal-apple-darwin/release/bundle/macos/tauri-app.app
lipo -archs "$APP"/Contents/MacOS/*
codesign --verify --deep --strict --verbose=2 "$APP"
spctl -a -vv "$APP"

Вывод на раннере GitHub macos-26:

x86_64 arm64
tauri-app.app: code object is not signed at all
tauri-app.app: rejected
source=no usable signature

Сборка заняла 4 минуты. Она создала универсальный .app на 8.23 MiB и .dmg на 3.57 MiB. .dmg от Electron Forge был не лучше. codesign показал Signature=adhoc и TeamIdentifier=not set, а spctl его отклонил. Gatekeeper блокирует такие сборки на Mac ваших пользователей.

Electron Forge: подпись и нотаризация в make

Forge подписывает и нотаризует во время npm run make, если это указано в конфигурации. Это пример из руководства Forge по подписи для macOS:

// forge.config.js
module.exports = {
  packagerConfig: {
    osxSign: {},
    osxNotarize: {
      appleId: process.env.APPLE_ID,
      appleIdPassword: process.env.APPLE_PASSWORD,
      teamId: process.env.APPLE_TEAM_ID
    }
  }
};

Потом соберите каждую архитектуру. Сначала мы добавили в стандартный шаблон сборщик DMG. Каждая из двух сборок заняла меньше 25 секунд:

npm install --save-dev @electron-forge/maker-dmg
npm run make -- --arch=arm64
npm run make -- --arch=x64

Мы также попробовали --arch=universal на стандартном шаблоне. Сборка упала с ошибкой "the number of mach-o files is not the same between the arm64 and x64 builds". В документации electron-builder тоже сказано, что сборки под каждую архитектуру отдельно надёжнее всего.

electron-builder: notarize: true

electron-builder берёт сертификат и логин Apple из переменных окружения. На его странице про нотаризацию показана такая конфигурация:

# electron-builder.yml
mac:
  notarize: true
  sign:
    hardenedRuntime: true

# environment
CSC_LINK=/path/to/developer-id.p12
CSC_KEY_PASSWORD=...
APPLE_ID=you@example.com
APPLE_APP_SPECIFIC_PASSWORD=xxxx-xxxx-xxxx-xxxx
APPLE_TEAM_ID=ABCDE12345

Tauri: задайте переменные и соберите

Tauri подписывает и нотаризует внутри tauri build, если заданы эти переменные. Имена взяты из руководства Tauri по подписи для macOS:

export APPLE_SIGNING_IDENTITY="Developer ID Application: Your Name (ABCDE12345)"
export APPLE_ID=you@example.com
export APPLE_PASSWORD=xxxx-xxxx-xxxx-xxxx
export APPLE_TEAM_ID=ABCDE12345
npm run tauri build -- --target universal-apple-darwin

Нотаризация любого приложения вручную

Для других тулкитов или чтобы повторить один шаг, запускайте инструменты Apple сами. Эти команды взяты из документации Apple по нотаризации. Один раз сохраните логин, потом заархивируйте, отправьте и дождитесь ответа:

xcrun notarytool store-credentials "notarytool-password" \
  --apple-id "you@example.com" --team-id ABCDE12345 \
  --password xxxx-xxxx-xxxx-xxxx

ditto -c -k --keepParent "MyApp.app" "MyApp.zip"
xcrun notarytool submit MyApp.zip --keychain-profile "notarytool-password" --wait
xcrun stapler staple "MyApp.app"

По словам Apple, нотаризация обычно занимает меньше часа. К ZIP нельзя прикрепить билет, поэтому прикрепите его к .app и заархивируйте снова. Можно также отправить и обработать сам .dmg. Если статус Invalid, прочитайте лог:

xcrun notarytool log <submission-id> --keychain-profile "notarytool-password" developer_log.json

Как это сделать на арендованном Mac

Суточный доступ MacRun это выделенный Mac mini на M6 за $15. Xcode 27.1 установлен, так что codesign, notarytool и stapler готовы. Node и Rust заранее не установлены. У вас есть права администратора и Homebrew, так что их можно поставить самому.

  • Подключитесь через Tailscale по SSH или откройте рабочий стол в любом VNC-клиенте.
  • Войдите в Xcode со своим Apple Account и создайте там сертификат Developer ID.
  • Экспортируйте сертификат с ключом в файл .p12 и сохраните его, позже он пригодится для CI.
  • Клонируйте репозиторий, соберите, нотаризуйте и скачайте .dmg с прикреплённым билетом.

Когда доступ заканчивается, Mac очищается. Сначала отправьте код в репозиторий и скопируйте .p12 к себе. Про Xcode через удалённый экран читайте наше руководство Xcode из Windows.

Кому не стоит арендовать для этого Mac

  • Командам, у которых уже есть CI. Раннер macOS в GitHub умеет подписывать и нотаризовать с секретами. Наша задача для Electron оплачена как 2 минуты, около 12 центов. Задача для Tauri как 5, около 31 цента. Ожидание нотаризации добавляет минуты. Смотрите наше руководство по GitHub Actions.
  • Конвейерам только на Linux. rcodesign это инструмент с открытым кодом, который подписывает и нотаризует из Linux или Windows. Ему нужен API-ключ App Store Connect. Это не инструмент Apple, и его последний выпуск 0.29.0 вышел в ноябре 2024 года.
  • Еженедельным релизам. Помесячный раннер стоит $104за первый месяц, дальше $139 в месяц. Купить б/у Mac за год может выйти дешевле.

Частые вопросы

Можно ли нотаризовать приложение для Mac на Windows?

+

Инструментами Apple нельзя. codesign, notarytool и stapler работают только на macOS. Инструмент с открытым кодом rcodesign умеет подписывать и нотаризовать из Windows или Linux, но Apple его не делает и не поддерживает.

Нужен ли платный аккаунт Apple Developer для нотаризации?

+

Да. Нужен сертификат Developer ID Application, он входит в Apple Developer Program за 99 USD в год. В документации Tauri сказано, что бесплатный аккаунт не может нотаризовать.

Может ли Electron Forge собрать .dmg для Mac на Linux?

+

В нашем тесте нет. Electron Forge на Ubuntu создал только .deb и .rpm, а принудительный пакет для macOS упал. На раннере macOS 26 тот же шаблон создал .dmg и .zip для arm64 и x64.

Как сделать универсальную сборку для Mac?

+

В Tauri добавьте обе цели Rust и выполните tauri build --target universal-apple-darwin. Так мы получили один .app с x86_64 и arm64. В Electron Forge стандартный шаблон не смог объединить сборки, поэтому собирайте arm64 и x64 отдельно.

Сколько длится нотаризация Apple?

+

По словам Apple, обычно меньше часа. Флаг --wait держит notarytool запущенным, пока Apple не ответит, так что опрашивать статус вручную не нужно.

Сколько стоит Mac на один релиз?

+

Суточный доступ MacRun стоит $15 за выделенный Mac mini на M6 с установленным Xcode. Неделя стоит $59. Вы платите один раз, и ничего не продлевается.

Похожие руководства