-
Notifications
You must be signed in to change notification settings - Fork 0
Distribution
Developer documentation for building, signing, and distributing EXStreamTV.
- Overview
- Prerequisites
- Building the App
- Creating a DMG
- Creating a PKG
- Code Signing
- Notarization
- Bundled Dependencies
- Release Checklist
EXStreamTV can be distributed in two formats:
| Format | Use Case | Includes |
|---|---|---|
| DMG | Simple drag-and-drop install | App bundle only |
| PKG | Full installer with options | App + dependencies + AI setup |
Both require code signing and notarization for distribution outside the Mac App Store.
- Apple Developer Account ($99/year for distribution)
- Developer ID Application Certificate
- Developer ID Installer Certificate (for PKG)
- Xcode Command Line Tools
- Open Keychain Access
- Go to Keychain Access > Certificate Assistant > Request Certificate from CA
- Upload to developer.apple.com
- Download and install the certificates
# List available signing identities
security find-identity -v -p codesigning
# Should show something like:
# "Developer ID Application: Your Name (TEAM_ID)"
# "Developer ID Installer: Your Name (TEAM_ID)"cd EXStreamTVApp
# Build for release
swift build -c release
# Or build universal binary (Intel + Apple Silicon)
swift build -c release --arch arm64 --arch x86_64The build output is in .build/release/. For distribution, create a proper app bundle:
# Copy to build directory
mkdir -p ../build
cp -r .build/release/EXStreamTVApp.app ../build/# Check the binary
file build/EXStreamTVApp.app/Contents/MacOS/EXStreamTVApp
# Should show: Mach-O universal binary with 2 architectures
# Check bundle info
plutil -p build/EXStreamTVApp.app/Contents/Info.plistUse the provided script to create a DMG installer.
cd distributions/macos/dmg
# Create DMG with version number
./create_dmg.sh 1.4.0- Creates staging directory
- Copies app bundle
- Creates Applications symlink
- Sets window layout
- Compresses to DMG
- Generates SHA256 checksum
dist/
├── EXStreamTV-Installer-1.4.0.dmg
└── EXStreamTV-Installer-1.4.0.dmg.sha256
# Create temporary DMG
hdiutil create -volname "EXStreamTV" \
-srcfolder build/staging \
-ov -format UDRW \
temp.dmg
# Convert to compressed
hdiutil convert temp.dmg -format UDZO -o EXStreamTV-1.4.0.dmgThe PKG installer provides a full installation experience with AI setup options.
distributions/macos/pkg/
├── Distribution.xml # Installer UI definition
├── scripts/
│ ├── preinstall # Pre-installation checks
│ └── postinstall # Post-installation setup
└── resources/
├── welcome.html # Welcome page
├── license.html # License agreement
├── ai_setup.html # AI provider selection
└── conclusion.html # Completion page
# Build component packages
pkgbuild --root build/EXStreamTVApp.app \
--identifier com.exstreamtv.app \
--version 1.4.0 \
--install-location /Applications/EXStreamTV.app \
app.pkg
# Build distribution package
productbuild --distribution Distribution.xml \
--resources resources \
--package-path . \
EXStreamTV-1.4.0.pkgThe Distribution.xml includes AI provider choices:
<choice id="ai-cloud" title="Cloud AI (Recommended)">
<!-- Configures cloud AI in postinstall -->
</choice>
<choice id="ai-local" title="Local AI">
<!-- Installs Ollama and downloads model -->
</choice>
<choice id="ai-skip" title="Skip">
<!-- User configures later -->
</choice>The postinstall script handles the selected option.
All distributed apps must be signed with your Developer ID.
cd distributions/macos
# Sign with automatic identity detection
./sign_app.sh ../build/EXStreamTVApp.app
# Or specify identity
SIGNING_IDENTITY="Developer ID Application: Your Name (TEAM_ID)" \
./sign_app.sh ../build/EXStreamTVApp.app| Variable | Description |
|---|---|
SIGNING_IDENTITY |
Full name of signing certificate |
- Embedded frameworks (in order)
- Dynamic libraries
- Helper executables
- Main app bundle (with entitlements)
The app requires these entitlements (EXStreamTVApp.entitlements):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "...">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<false/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
</dict>
</plist># Check signature
codesign --verify --deep --strict --verbose=2 EXStreamTVApp.app
# Check entitlements
codesign -d --entitlements - EXStreamTVApp.app
# Gatekeeper check
spctl --assess --type execute --verbose EXStreamTVApp.appApple requires notarization for apps distributed outside the Mac App Store.
cd distributions/macos
# Set credentials
export APPLE_ID="your@email.com"
export TEAM_ID="YOURTEAMID"
export APP_PASSWORD="xxxx-xxxx-xxxx-xxxx" # App-specific password
# Notarize
./notarize.sh ../dist/EXStreamTV-Installer-1.4.0.dmg- Go to appleid.apple.com
- Sign in > Security > App-Specific Passwords
- Generate a new password
- Use this password for
APP_PASSWORD
# Store credentials
xcrun notarytool store-credentials "EXStreamTV" \
--apple-id "your@email.com" \
--team-id "YOURTEAMID" \
--password "xxxx-xxxx-xxxx-xxxx"
# Submit for notarization
xcrun notarytool submit EXStreamTV-1.4.0.dmg \
--keychain-profile "EXStreamTV" \
--wait
# Staple the ticket
xcrun stapler staple EXStreamTV-1.4.0.dmg# Get submission log
xcrun notarytool log <submission-id> \
--keychain-profile "EXStreamTV" \
log.json
# View log
cat log.json | python3 -m json.tool"The signature of the binary is invalid"
- Re-sign with
--options runtimeflag - Ensure all nested bundles are signed
"The executable requests the com.apple.security. entitlement"*
- Check entitlements are correct
- Hardened Runtime must be enabled
The PKG installer can include bundled Python and FFmpeg.
distributions/macos/bundled/
├── python/ # Python 3.11 distribution
│ ├── bin/python3
│ └── lib/
└── ffmpeg/ # FFmpeg binaries
└── bin/
├── ffmpeg
└── ffprobe
# Build Python with universal binary
./configure --enable-universalsdk --with-universal-archs=universal2
make
make install DESTDIR=bundled/pythonOr use the official installer and extract:
# Download from python.org
curl -O https://www.python.org/ftp/python/3.11.7/python-3.11.7-macos11.pkgDownload static builds from evermeet.cx:
curl -O https://evermeet.cx/ffmpeg/ffmpeg-6.1.1.zip
curl -O https://evermeet.cx/ffmpeg/ffprobe-6.1.1.zip
unzip ffmpeg-6.1.1.zip -d bundled/ffmpeg/bin/
unzip ffprobe-6.1.1.zip -d bundled/ffmpeg/bin/# Strip Python test files
find bundled/python -name "test" -type d -exec rm -rf {} +
find bundled/python -name "__pycache__" -exec rm -rf {} +
# Total size: ~150MB (Python ~100MB, FFmpeg ~50MB)- Update version in
Package.swift - Update version in
Info.plist - Update
CHANGELOG.md - Run all tests
- Test on macOS 13, 14, and 15
- Create release build
- Build universal binary (Intel + Apple Silicon)
- Verify app launches on both architectures
- Sign app with Developer ID
- Verify signature:
codesign --verify - Test Gatekeeper:
spctl --assess
- Create DMG:
./create_dmg.sh X.Y.Z - Create PKG (if applicable)
- Verify DMG mounts correctly
- Test PKG installation
- Submit DMG for notarization
- Submit PKG for notarization
- Staple tickets
- Verify:
xcrun stapler validate
- Upload to GitHub Releases
- Update download links in README
- Announce release
- Update documentation
- Monitor for crash reports
- Respond to initial feedback
- Tag release in git:
git tag v2.6.0
# Re-sign everything
codesign --force --deep --options runtime --timestamp \
--sign "Developer ID Application: ..." \
EXStreamTVApp.appEnsure you're using --options runtime when signing:
codesign --options runtime --timestamp --sign "..." app.appThe app needs to be notarized and stapled:
xcrun stapler staple EXStreamTV.dmgCheck the JavaScript in Distribution.xml:
function installCheck() {
if (system.version.ProductVersion < '13.0') {
my.result.message = 'Requires macOS 13.0+';
return false;
}
return true;
}Last Revised: 2026-03-20
Getting Started
Guides
- AI-Setup
- Channel-Creation-Guide
- Local-Media
- Hardware-Transcoding
- macOS-App-Guide
- Navigation-Guide
- Streaming-Stability
- Advanced-Scheduling
Reference
- API-Reference
- System-Design
- Architecture-Diagrams
- Pattern-Refactor-Sources
- ADR-Channel-Manager-Database
- EXStreamTV-UI-Architecture
- Architecture
- Streaming-Internals
- HDHomeRun-Emulation
- Metadata-And-XMLTV
- AI-Agent-And-Containment
- Restart-Safety-Model
- Observability
- Troubleshooting
- Log-Interpretation
- Tunarr-DizqueTV-Integration
- Distribution
- Build-Progress
Operations
Changelog & Migration