This document explains how to distribute your ManyMany.dev app and push updates to users.
- Sign up for Apple Developer Program ($99/year)
- Create signing certificates:
- Developer ID Application certificate
- Developer ID Installer certificate (for .pkg files)
Run this command interactively in your terminal:
npx tauri signer generateThis will generate:
- Private key (keep secret) - for signing updates
- Public key - for embedding in your app
Add these secrets to your GitHub repository (Settings > Secrets and variables > Actions):
APPLE_CERTIFICATE: Base64 encoded .p12 certificateAPPLE_CERTIFICATE_PASSWORD: Certificate passwordAPPLE_ID: Your Apple ID emailAPPLE_PASSWORD: App-specific passwordAPPLE_TEAM_ID: Your Apple Developer Team ID
TAURI_SIGNING_PRIVATE_KEY: The private key from step 2TAURI_SIGNING_PRIVATE_KEY_PASSWORD: Password you set for the private key
Update your src-tauri/tauri.conf.json with the updater configuration:
{
"updater": {
"active": true,
"endpoints": [
"https://github.com/JayZeeDesign/ManyMany.dev/releases/latest/download/latest.json"
],
"dialog": true,
"pubkey": "YOUR_PUBLIC_KEY_HERE"
},
"bundle": {
"macOS": {
"signingIdentity": "Developer ID Application: Your Name (TEAM_ID)",
"hardenedRuntime": true,
"entitlements": "src-tauri/entitlements.plist"
}
}
}Replace YOUR_PUBLIC_KEY_HERE with the public key from step 2.
Create src-tauri/entitlements.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
</dict>
</plist>npm install @tauri-apps/plugin-updaterAdd this to your React app (e.g., in App.tsx):
import { check } from '@tauri-apps/plugin-updater';
import { relaunch } from '@tauri-apps/plugin-process';
async function checkForUpdates() {
try {
const update = await check();
if (update?.available) {
console.log(\`Update available: \${update.version}\`);
// Download and install update
let downloaded = 0;
let contentLength = 0;
await update.downloadAndInstall((event) => {
switch (event.event) {
case 'Started':
contentLength = event.data.contentLength ?? 0;
console.log('Download started');
break;
case 'Progress':
downloaded += event.data.chunkLength;
console.log(\`Downloaded \${downloaded} of \${contentLength}\`);
break;
case 'Finished':
console.log('Download finished');
break;
}
});
// Restart the app to apply update
await relaunch();
}
} catch (error) {
console.error('Update check failed:', error);
}
}
// Check for updates on app start
useEffect(() => {
checkForUpdates();
}, []);-
Update version in
src-tauri/tauri.conf.jsonandpackage.json -
Commit changes and push to main branch
-
Create and push a tag:
git tag v1.0.1 git push origin v1.0.1
-
GitHub Actions will automatically:
- Build for all platforms (macOS, Windows, Linux)
- Code sign the macOS app
- Create GitHub release with assets
- Generate
latest.jsonfor the updater
You can also create releases manually through GitHub's web interface:
- Go to
Releasestab in your repository - Click "Create a new release"
- Choose tag version (e.g.,
v1.0.1) - Add release notes
- GitHub Actions will build and attach assets
Users can download from your GitHub releases page:
https://github.com/JayZeeDesign/ManyMany.dev/releases
For App Store distribution, you'll need additional setup:
- App Store provisioning profiles
- App Store entitlements
- Sandbox compliance
Host download links on your website pointing to GitHub releases.
Once users have the app installed:
- App checks for updates on startup
- If update available, user gets notification dialog
- User can choose to download and install
- App restarts with new version
- Code signing fails: Check certificates and Team ID
- Update check fails: Verify public key in config
- GitHub Actions fail: Check repository secrets
- Notarization fails: Ensure proper entitlements
- Check GitHub Actions logs for build errors
- Use
tauri build --debugfor local testing - Verify certificates with
security find-identity -v
- Keep your private signing key secure
- Use repository secrets for sensitive data
- Regularly rotate certificates and keys
- Consider using a dedicated signing service for production
- Set up proper code signing certificates
- Configure repository secrets
- Test the release process with a beta version
- Add update UI to your app
- Set up analytics to track update adoption