Files
presenton--presenton/docs/macos/dev/mac-app-store-setup.md
T
2026-07-13 13:08:41 +08:00

7.5 KiB
Raw Blame History

Mac App Store Setup

Presentons Electron app is configured for Mac App Store (MAS) distribution with App Sandbox. MAS builds must be produced on macOS because Apples signing tools are required.

This guide covers Apple Developer setup, local provisioning files, and the npm scripts in electron/package.json on main.

Overview

Target Purpose npm script
dmg Direct download outside the App Store npm run build:all:mac:signed
mas-dev Sandbox testing on registered Macs npm run build:all:mas-dev
mas App Store submission npm run build:all:mas

Build configuration lives in electron/build.js. Key identifiers:

  • Bundle ID: com.presenton.presenton
  • Team ID: S6W5C54KL6 (set in extendInfo.ElectronTeamID)

MAS files in the repo

These are checked in under electron/build/:

File Role
entitlements.mas.plist Main app entitlements (sandbox, network, JIT, user-selected files)
entitlements.mas.inherit.plist Inherited entitlements for helper processes and bundled binaries
MacAppStore.provisionprofile.replace_me Placeholder — replace with your real App Store profile (see below)

build.js validates provisioning profiles with security cms -D before building. Invalid or placeholder files will fail the build with a clear error.

What you need from Apple

1. Apple Development certificate

Xcode → SettingsAccounts → your team → Manage Certificates+Apple Development.

Used for mas-dev builds and local sandbox testing.

2. Apple Distribution certificate

Same path as above, but choose Apple Distribution.

Used for mas (App Store submission) builds.

3. App ID (Bundle ID)

Apple Developer PortalCertificates, Identifiers & ProfilesIdentifiersApp IDs.

Create a macOS App ID that matches com.presenton.presenton (or update APP_ID in electron/build.js if you use a different ID).

4. Provisioning profiles

Create two macOS profiles and download each .provisionprofile file into electron/build/:

AppleDevelopment (MAS development)

  • Portal → Profiles+
  • Type: macOS App Development
  • App ID: your Presenton app ID
  • Certificate: Apple Development
  • Save as electron/build/AppleDevelopment.provisionprofile

build.js also accepts AppleDev.provisionprofile or AppDev.provisionprofile as fallbacks.

MacAppStore (MAS distribution)

  • Portal → Profiles+
  • Type: Mac App Store
  • App ID: your Presenton app ID
  • Certificate: Apple Distribution
  • Save as electron/build/MacAppStore.provisionprofile

Verify profiles decode correctly:

cd electron
security cms -D -i build/AppleDevelopment.provisionprofile
security cms -D -i build/MacAppStore.provisionprofile

Provisioning profiles expire (typically yearly). Regenerate and replace the local files when they do.

Environment variables

Variable Used for Description
PRESENTON_MAC_TARGET Set by npm scripts mas-dev or mas (do not set manually when using the scripts below)
PRESENTON_MAS_DEV_IDENTITY mas-dev Signing identity, e.g. Apple Development: Your Name (TEAMID)
PRESENTON_MAS_DISTRIBUTION_IDENTITY mas Distribution identity, e.g. Apple Distribution: Your Org (TEAMID)
PRESENTON_MAS_IDENTITY mas Alias for distribution identity
CSC_NAME Either target Fallback if the target-specific identity vars are unset
PRESENTON_APP_STORE_VERSION mas App Store version (x.y.z). Required when package.json version contains a suffix like -beta
PRESENTON_APP_STORE_BUILD mas App Store build number. Defaults to the short version if unset

Example for a beta package version:

export PRESENTON_APP_STORE_VERSION=1.0.0
export PRESENTON_APP_STORE_BUILD=42

Build commands

Run from electron/ after npm run setup:env (first time only).

Rebuilds Next.js, FastAPI, export runtime, and packages the app:

# MAS development — runs on Macs in your dev provisioning profile
PRESENTON_MAS_DEV_IDENTITY="Apple Development: Your Name (TEAMID)" \
  npm run build:all:mas-dev

# MAS distribution — for App Store Connect upload
PRESENTON_MAS_DISTRIBUTION_IDENTITY="Apple Distribution: Your Org (TEAMID)" \
  PRESENTON_APP_STORE_VERSION=1.0.0 \
  npm run build:all:mas

Package only (resources already built)

If you already ran build:all and only need to re-run the Electron packager:

PRESENTON_MAS_DEV_IDENTITY="Apple Development: Your Name (TEAMID)" \
  npm run dist:mac:mas-dev

PRESENTON_MAS_DISTRIBUTION_IDENTITY="Apple Distribution: Your Org (TEAMID)" \
  PRESENTON_APP_STORE_VERSION=1.0.0 \
  npm run dist:mac:mas

Direct DMG (not App Store)

For a signed and notarized macOS disk image that does not go through App Store approval:

npm run build:all:mac:signed

See Direct distribution for the Developer ID certificate, notarization, and verification flow.

Artifacts land in electron/dist/.

Output locations

Exact paths depend on architecture (arm64 vs x64). Typical layouts:

electron/dist/
  mas-dev-arm64/          # unsigned or dev-signed .app (mas-dev)
  mas-arm64/              # distribution-signed .app (mas)
  Presenton-<version>.pkg # MAS installer for upload
  Presenton-<version>.dmg # signed and notarized direct distribution DMG

Upload the .pkg from the mas build to App Store Connect.

Icons

The default macOS icon is electron/resources/ui/assets/images/presenton_short_filled.png.

For App Store packaging you can provide a proper .icns at electron/build/icon.icns and update the mac.icon field in electron/build.js if you want a custom store icon.

Source PNGs for generating an icon set are in electron/build/icon.iconset/.

Testing notes

  • MAS-signed apps require the MAS Electron build (mas or mas-dev targets). A normal DMG build is not sandbox-compatible in the same way.
  • mas-dev builds run only on Macs registered in your development provisioning profile.
  • mas (distribution) builds usually do not launch locally; they are meant for App Store Connect processing and release.
  • mas-dev signing uses --timestamp=none in build.js so local signing works without a network timestamp server.

Troubleshooting

“Missing MAS development/distribution provisioning profile”

Place the correct .provisionprofile in electron/build/ (see Provisioning profiles).

“macOS could not decode” a profile

Re-download the profile from the Developer Portal. Do not commit real profiles to git.

“Cannot derive an App Store version from package version”

Set PRESENTON_APP_STORE_VERSION to three integers, e.g. 1.0.0.

“MAS builds must be run on macOS”

Run the build on a Mac with Xcode command-line tools installed (xcode-select --install).

FastAPI or export binary not executable inside the .app

build.js runs an afterPack hook that sets executable permissions on bundled binaries. If signing fails afterward, check that entitlements allow the sandboxed app to execute helpers in Contents/Resources/app/resources/.

See also