You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Import the Developer ID cert into a temporary keychain in build-macos.yml,
switch the package step from --no-sign to --notarize, and add credential-based
notarization to package-macos.sh (NOTARY_APPLE_ID/PASSWORD/TEAM_ID env vars)
for the CI case where no local keychain profile exists.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CLAUDE.md
+35-1Lines changed: 35 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -490,11 +490,45 @@ Prerequisites: draft release must exist for the tag, `gh` CLI authenticated.
490
490
5.**Test** — fresh install + upgrade test
491
491
6.**Create GitHub releases** — deps release first (if changed, tag `deps-vX.Y.Z`), then app release (tag `vX.Y.Z`)
492
492
493
+
### macOS Code Signing & Notarization
494
+
495
+
The macOS app is signed with a **Developer ID Application** certificate and notarized by Apple so it launches without Gatekeeper warnings. Signing happens **in CI** (`build-macos.yml`) — the runner imports the cert into a temporary keychain, then `package-macos.sh --notarize` signs every Mach-O inner-out (dylibs → frameworks → `.so` → worker → app), signs the DMG, submits to the notary service, and staples the ticket. `ci-build-and-release.sh` just downloads the finished signed/notarized DMG and uploads it — no local signing step.
496
+
497
+
`package-macos.sh` also works locally: with a Developer ID cert in your keychain it signs, and `--notarize` uses a stored `notarytool` keychain profile (default name `VapourBox`). In CI there is no keychain profile, so it falls back to `NOTARY_APPLE_ID` / `NOTARY_PASSWORD` / `NOTARY_TEAM_ID` env vars. Use `--no-sign` for ad-hoc local test builds.
|`MACOS_CERTIFICATE`| Base64 of the exported Developer ID Application `.p12`|
504
+
|`MACOS_CERTIFICATE_PASSWORD`| Password set when exporting the `.p12`|
505
+
|`MACOS_KEYCHAIN_PASSWORD`| Any random string (temp keychain password) |
506
+
|`MACOS_NOTARY_APPLE_ID`| Apple ID email for notarization |
507
+
|`MACOS_NOTARY_PASSWORD`| App-specific password from appleid.apple.com |
508
+
|`MACOS_NOTARY_TEAM_ID`|`PMXZ63S6YG`|
509
+
510
+
**One-time setup** (export the cert and load secrets via `gh`):
511
+
512
+
```bash
513
+
# 1. Export the Developer ID Application cert + private key from Keychain Access
514
+
# (right-click the identity → Export → .p12, set a password) to ~/devid.p12
515
+
# 2. Base64-encode and store all secrets:
516
+
gh secret set MACOS_CERTIFICATE <<(base64 -i ~/devid.p12)
517
+
gh secret set MACOS_CERTIFICATE_PASSWORD # paste the .p12 export password
518
+
gh secret set MACOS_KEYCHAIN_PASSWORD # paste any random string
519
+
gh secret set MACOS_NOTARY_APPLE_ID # paste your Apple ID email
520
+
gh secret set MACOS_NOTARY_PASSWORD # paste app-specific password
521
+
gh secret set MACOS_NOTARY_TEAM_ID # paste PMXZ63S6YG
522
+
rm ~/devid.p12
523
+
```
524
+
525
+
Create the app-specific password at appleid.apple.com → Sign-In and Security → App-Specific Passwords. The Developer ID cert expires **2027-02-01**; re-export and update `MACOS_CERTIFICATE` before then.
526
+
493
527
### Cross-Platform Notes
494
528
495
529
- Flutter Windows can't build on macOS — use GitHub Actions
496
530
- Windows deps can be zipped on macOS if `deps/windows-x64/` exists
497
-
-CI builds are ad-hoc signed; sign locally for distribution
531
+
-The macOS CI build (`build-macos.yml`) signs with the Developer ID cert and notarizes — see "macOS Code Signing & Notarization" below. Windows CI builds remain unsigned.
0 commit comments