Publishing desktop applications (Electron) to multiple distribution channels.
| Platform | Format | Signing | Distribution |
|---|---|---|---|
| macOS | .dmg (Universal) |
Apple ID + Notarization | GitHub Releases, Auto-updater |
| Windows | .exe + .msi |
EV Code Signing | GitHub Releases, Auto-updater |
| Linux | .AppImage, .deb, .snap |
- | GitHub Releases, Snap Store, Flathub |
# Initialize project
taskfile run init
# Development
taskfile run dev # Start dev server
taskfile run test # Run tests
taskfile run lint # Lint code
# Build
taskfile --platform macos run build-macos # macOS (requires macOS)
taskfile --platform windows run build-windows # Windows
taskfile --platform linux run build-linux # Linux
taskfile run build-all # All platforms
# Code Signing (requires certs)
taskfile --platform macos run sign-macos
taskfile --platform windows run sign-windows
# Distribution
taskfile run release-github # GitHub Releases
taskfile run release-snap # Snap Store
taskfile run release-flathub # Flatpak/Flathub
# Full pipeline
taskfile --env prod run publish-all
taskfile run init
This creates .env.local with placeholders for:
APPLE_ID + APPLE_APP_PASSWORD (for macOS notarization)WINDOWS_CERT + WINDOWS_CERT_PASS (for Windows signing)GITHUB_TOKEN (for GitHub Releases)Get from Apple Developer:
Set in .env.prod:
APPLE_ID=your@email.com
APPLE_APP_PASSWORD=xxxx-xxxx-xxxx-xxxx
TEAM_ID=ABCDEF1234
Options:
.pfx file + passwordSet in .env.prod:
WINDOWS_CERT=/path/to/cert.pfx
WINDOWS_CERT_PASS=your-password
Configure in .env:
GH_RELEASES=true # Publish to GitHub Releases
SNAP_STORE=true # Publish to Snap Store
FLATHUB=true # Build Flatpak for Flathub
┌─────────────┐ ┌─────────────┐ ┌─────────────────┐
│ Build │───▶│ Sign │───▶│ Distribute │
│ │ │ │ │ │
│ • macOS │ │ • Apple ID │ │ • GitHub │
│ • Windows │ │ • Windows │ │ • Snap Store │
│ • Linux │ │ cert │ │ • Flathub │
└─────────────┘ └─────────────┘ └─────────────────┘
| Task | Platform | Description |
|---|---|---|
build-macos |
macOS | Build .dmg universal binary |
build-windows |
Windows | Build .exe + .msi |
build-linux |
Linux | Build .AppImage + .deb + .snap |
build-all |
All | Build all platforms (CI) |
| Task | Requirements | Description |
|---|---|---|
sign-macos |
Apple ID + macOS | Sign + notarize with Apple |
sign-windows |
Windows cert | Sign with EV/OV certificate |
| Task | Channel | Description |
|---|---|---|
release-github |
GitHub | Create release with all artifacts |
release-snap |
Snap Store | Upload to Snapcraft |
release-flathub |
Flathub | Build Flatpak + submit PR |
| Task | Description |
|---|---|
publish-all |
Build + sign + distribute to all channels |
name: Publish Desktop
on:
push:
tags: ['v*']
jobs:
publish-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: taskfile --platform macos run build-macos
env:
APPLE_ID: $
APPLE_APP_PASSWORD: $
- run: taskfile --platform macos run sign-macos
publish-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: taskfile --platform windows run build-windows
- run: taskfile --platform windows run sign-windows
publish-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: taskfile --platform linux run build-linux
- run: taskfile run release-snap
env:
SNAPCRAFT_TOKEN: $
release:
needs: [publish-macos, publish-windows, publish-linux]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: taskfile run release-github
Configure electron-updater:
// main.js
const { autoUpdater } = require('electron-updater');
autoUpdater.checkForUpdatesAndNotify();
Set server type in package.json:
{
"build": {
"publish": {
"provider": "github",
"owner": "your-org",
"repo": "your-app"
}
}
}
package.json version in sync with git tags