chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
# Mac App Store Setup
|
||||
|
||||
Presenton’s Electron app is configured for Mac App Store (MAS) distribution with App Sandbox. MAS builds must be produced on macOS because Apple’s 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 → **Settings** → **Accounts** → 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 Portal](https://developer.apple.com/account) → **Certificates, Identifiers & Profiles** → **Identifiers** → **App 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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
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).
|
||||
|
||||
### Full build (recommended)
|
||||
|
||||
Rebuilds Next.js, FastAPI, export runtime, and packages the app:
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
npm run build:all:mac:signed
|
||||
```
|
||||
|
||||
See [Direct distribution](./direct-distribution.md) 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:
|
||||
|
||||
```text
|
||||
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](https://appstoreconnect.apple.com).
|
||||
|
||||
## 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](#4-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
|
||||
|
||||
- [macOS dev README](./README.md) — quick reference for all macOS build targets
|
||||
- [Electron dependency strategy](../../electron-dependency-strategy.md) — what gets bundled in the app
|
||||
Reference in New Issue
Block a user