feat(FN-5609): add macOS desktop signing configuration and entitlements

Adds macOS code signing and notarization infrastructure (FN-5609), introducing hardened runtime entitlements, electron-builder config for signed builds, and signing-enabled release workflows, with tests validating the configuration and docs covering the signing flow.

Fusion-Task-Id: FN-5609

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5609
This commit is contained in:
gsxdsm
2026-05-27 05:21:56 -07:00
parent 925a466043
commit 7d2cf330db
8 changed files with 199 additions and 13 deletions

View File

@@ -164,8 +164,6 @@ jobs:
packages/desktop/dist-electron/latest.yml
# ── Build macOS desktop artifacts ────────────────────────────────────
# macOS Developer ID signing/notarization is intentionally deferred;
# this job emits unsigned .dmg/.zip release artifacts.
build-desktop-macos:
name: Build Desktop macOS DMG/ZIP
runs-on: macos-latest
@@ -183,15 +181,34 @@ jobs:
- name: Build desktop package
run: pnpm --filter @fusion/desktop build
- name: Package macOS desktop artifacts
- name: Package signed macOS desktop DMG/ZIP
if: ${{ env.APPLE_CERTIFICATE_BASE64 != '' }}
run: pnpm --filter @fusion/desktop dist:mac -- --publish never
env:
APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
CSC_IDENTITY_AUTO_DISCOVERY: "true"
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Package unsigned macOS desktop DMG/ZIP
if: ${{ env.APPLE_CERTIFICATE_BASE64 == '' }}
run: pnpm --filter @fusion/desktop dist:mac -- --publish never -c.mac.notarize=false
env:
APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
CSC_IDENTITY_AUTO_DISCOVERY: "false"
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Verify desktop macOS artifacts
- name: Verify signed and notarized macOS artifacts
if: ${{ env.APPLE_CERTIFICATE_BASE64 != '' }}
env:
APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
shell: bash
run: |
set -euo pipefail
shopt -s nullglob
dmgs=(packages/desktop/dist-electron/Fusion-*-mac-*.dmg)
zips=(packages/desktop/dist-electron/Fusion-*-mac-*.zip)
@@ -203,6 +220,27 @@ jobs:
echo "No Fusion macOS ZIP artifacts produced" >&2
exit 1
fi
for dmg in "${dmgs[@]}"; do
echo "Verifying signed DMG: $dmg"
codesign --verify --deep --strict --verbose=2 "$dmg"
spctl --assess --type open --context context:primary-signature -v "$dmg"
xcrun stapler validate "$dmg"
done
for zip in "${zips[@]}"; do
echo "Verifying ZIP app bundle: $zip"
tmpdir="$(mktemp -d)"
unzip -q "$zip" -d "$tmpdir"
app="$(find "$tmpdir" -type d -name '*.app' -print -quit)"
if [ -z "$app" ]; then
echo "No .app bundle found in $zip" >&2
rm -rf "$tmpdir"
exit 1
fi
codesign --verify --deep --strict --verbose=2 "$app"
spctl --assess --type exec -v "$app"
xcrun stapler validate "$app"
rm -rf "$tmpdir"
done
- name: Generate desktop macOS checksums
shell: bash

View File

@@ -167,8 +167,6 @@ jobs:
packages/desktop/dist-electron/latest.yml
# ── Build macOS desktop artifacts ────────────────────────────────────
# macOS Developer ID signing/notarization is intentionally deferred;
# this job emits unsigned .dmg/.zip release artifacts.
build-desktop-macos:
name: Build Desktop macOS DMG/ZIP
runs-on: macos-latest
@@ -186,15 +184,34 @@ jobs:
- name: Build desktop package
run: pnpm --filter @fusion/desktop build
- name: Package macOS desktop artifacts
- name: Package signed macOS desktop DMG/ZIP
if: ${{ env.APPLE_CERTIFICATE_BASE64 != '' }}
run: pnpm --filter @fusion/desktop dist:mac -- --publish never
env:
APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
CSC_IDENTITY_AUTO_DISCOVERY: "true"
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Package unsigned macOS desktop DMG/ZIP
if: ${{ env.APPLE_CERTIFICATE_BASE64 == '' }}
run: pnpm --filter @fusion/desktop dist:mac -- --publish never -c.mac.notarize=false
env:
APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
CSC_IDENTITY_AUTO_DISCOVERY: "false"
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Verify desktop macOS artifacts
- name: Verify signed and notarized macOS artifacts
if: ${{ env.APPLE_CERTIFICATE_BASE64 != '' }}
env:
APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
shell: bash
run: |
set -euo pipefail
shopt -s nullglob
dmgs=(packages/desktop/dist-electron/Fusion-*-mac-*.dmg)
zips=(packages/desktop/dist-electron/Fusion-*-mac-*.zip)
@@ -206,6 +223,27 @@ jobs:
echo "No Fusion macOS ZIP artifacts produced" >&2
exit 1
fi
for dmg in "${dmgs[@]}"; do
echo "Verifying signed DMG: $dmg"
codesign --verify --deep --strict --verbose=2 "$dmg"
spctl --assess --type open --context context:primary-signature -v "$dmg"
xcrun stapler validate "$dmg"
done
for zip in "${zips[@]}"; do
echo "Verifying ZIP app bundle: $zip"
tmpdir="$(mktemp -d)"
unzip -q "$zip" -d "$tmpdir"
app="$(find "$tmpdir" -type d -name '*.app' -print -quit)"
if [ -z "$app" ]; then
echo "No .app bundle found in $zip" >&2
rm -rf "$tmpdir"
exit 1
fi
codesign --verify --deep --strict --verbose=2 "$app"
spctl --assess --type exec -v "$app"
xcrun stapler validate "$app"
rm -rf "$tmpdir"
done
- name: Generate desktop macOS checksums
shell: bash