Skip to content

Add Mac App Store distribution scaffolding#29

Open
msollami wants to merge 1 commit into
mainfrom
feature/mac-app-store
Open

Add Mac App Store distribution scaffolding#29
msollami wants to merge 1 commit into
mainfrom
feature/mac-app-store

Conversation

@msollami

Copy link
Copy Markdown
Collaborator

Summary

Makes the Tauri notebook (frontend/) shippable to the Mac App Store (MAS). The core blocker was that the compiled C engine, spawned as a Tauri sidecar, linked Homebrew dylibs under /opt/homebrew — paths that don't exist on user machines and are disallowed under the App Sandbox that MAS mandates. This PR makes the sidecar self-contained and adds the MAS build config, entitlements, and a full runbook. Packaging only — no C-engine changes. arm64-only for now (universal is documented as future work).

Changes

  • frontend/build-sidecar-appstore.sh — builds the engine, copies the sidecar, recursively bundles the four Homebrew dylibs (gmp, mpfr, pcre2, raylib; only transitive dep is mpfr→gmp) into src-tauri/binaries/libs/, rewrites all install names via install_name_tool (dylib IDs and sidecar loads → @rpath/…; inter-dylib refs → @loader_path/…), adds @executable_path/../Frameworks and @executable_path/libs rpaths, and ad-hoc re-signs. Self-verifies no /opt/homebrew paths remain.
  • frontend/src-tauri/Entitlements.plist — App Sandbox (mandatory), application-identifier/team-identifier placeholders, and files.user-selected.read-write (the notebook opens/saves .lb files via the dialog plugin). No network entitlement — sidecar comms are local stdio only.
  • frontend/src-tauri/tauri.appstore.conf.json — overlay config so normal .dmg builds are unaffected: sets bundle.macOS.entitlements, bundle.macOS.frameworks (bundled dylibs → Contents/Frameworks), and bundle.macOS.files for embedded.provisionprofile. Base identifier com.mathilda.notebook is already a real reverse-DNS id (no fix needed).
  • docs/appstore.md — end-to-end runbook (enrollment, App ID, certs, provisioning profile, signed .app/.pkg, upload) plus common pitfalls.
  • Changelog note in docs/spec/changelog/2026-07-20.md.

Testing

Done & verified in this PR

  • Ran build-sidecar-appstore.sh; otool -L on the final sidecar and every bundled dylib shows no /opt/homebrew paths (before/after below).
  • Proved self-contained execution: copied sidecar + dylibs into a temp bundle layout (Contents/MacOS + Contents/Frameworks) on /tmp and ran it with Homebrew scrubbed from PATH and DYLD_* cleared (env -i). Series[Exp[x],{x,0,3}] and Factor[x^4-1] both returned correct pretty output over the stdio pipe protocol.
  • Base config identifier confirmed real reverse-DNS; binaries/ is already gitignored so no build artifacts are committed.

Before:

/opt/homebrew/opt/gmp/lib/libgmp.10.dylib
/opt/homebrew/opt/mpfr/lib/libmpfr.6.dylib
/opt/homebrew/opt/raylib/lib/libraylib.550.dylib
/opt/homebrew/opt/pcre2/lib/libpcre2-8.0.dylib

After (sidecar):

/usr/lib/libedit.3.dylib
@rpath/libgmp.10.dylib
/usr/lib/libSystem.B.dylib
@rpath/libmpfr.6.dylib
/System/Library/Frameworks/Accelerate.framework/.../Accelerate
@rpath/libraylib.550.dylib
@rpath/libpcre2-8.0.dylib

(libmpfr.6.dylib@loader_path/libgmp.10.dylib; system//usr/lib refs intentionally left alone.)

Requires your Apple Developer account (manual — cannot be done in-repo)

  • Apple Developer Program enrollment; register App ID (com.mathilda.notebook) + App Store Connect app record.
  • Create Apple Distribution + Mac Installer Distribution certificates.
  • Create + download the Mac App Store provisioning profilefrontend/src-tauri/embedded.provisionprofile.
  • Fill $IDENTIFIER/$TEAM_ID in Entitlements.plist.
  • Signed build (APPLE_SIGNING_IDENTITY=... npm run tauri build -- --bundles app --config src-tauri/tauri.appstore.conf.json), productbuild into a signed .pkg, and altool --upload-app.

Full steps in docs/appstore.md.

Ticket

beads-planning-fes / App Store follow-up

Make the Tauri notebook shippable to the Mac App Store by making the C
engine sidecar self-contained and adding the MAS build configuration.

- build-sidecar-appstore.sh: bundles the Homebrew dylibs (gmp, mpfr,
  pcre2, raylib and transitive deps) next to the sidecar, rewrites all
  install names to @rpath/@loader_path, adds rpaths, and ad-hoc
  re-signs. Verified free of /opt/homebrew references and runs
  self-contained with Homebrew unreachable.
- Entitlements.plist: App Sandbox, application/team identifiers, and
  user-selected file read-write (notebook open/save). No network use.
- tauri.appstore.conf.json: overlay config wiring entitlements, bundled
  frameworks, and the provisioning profile without affecting .dmg builds.
- docs/appstore.md: end-to-end runbook and pitfalls.
- Changelog note for the week of 2026-07-20.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant