Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/release-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,23 @@ jobs:
name: desktop-mac-${{ matrix.arch }}-dmg
path: apps/desktop/release/*.dmg
retention-days: 30
if-no-files-found: error

- name: Upload ZIP artifact
uses: actions/upload-artifact@v4
with:
name: desktop-mac-${{ matrix.arch }}-zip
path: apps/desktop/release/*.zip
retention-days: 30
if-no-files-found: error

- name: Upload auto-update manifest
uses: actions/upload-artifact@v4
with:
name: desktop-mac-update-manifest
path: apps/desktop/release/latest-mac.yml
retention-days: 30
if-no-files-found: error

Comment thread
coderabbitai[bot] marked this conversation as resolved.
# Create GitHub Release after builds complete
release:
Expand Down
156 changes: 39 additions & 117 deletions apps/desktop/RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,154 +1,76 @@
# Desktop App Release Process

This document describes how to create a release for the Superset Desktop application.
## Quick Start

## Prerequisites

- Ensure all changes are committed and pushed to the repository
- Ensure the build works locally: `bun run package`
- Update version in `package.json` if needed

## Release Methods

### Method 1: Tag-Based Release (Recommended)

Create and push a git tag with the format `desktop-v*.*.*`:
From the monorepo root:

```bash
# Create a tag (e.g., desktop-v1.0.0)
git tag desktop-v1.0.0

# Push the tag to trigger the release workflow
git push origin desktop-v1.0.0
./apps/desktop/create-release.sh <version>
# Example: ./apps/desktop/create-release.sh desktop-v0.0.1
```

This will automatically:
1. Build the app for macOS (arm64), Windows (x64), and Linux (x64)
2. Create artifacts for each platform
3. Create a draft GitHub release with all binaries attached

### Method 2: Manual Workflow Dispatch

You can also trigger a release manually from GitHub Actions:
The script will:
1. Update `package.json` version
2. Create and push a `desktop-v<version>` tag
3. Monitor the GitHub Actions build
4. Create a **draft release** for review

1. Go to Actions → Release Desktop App
2. Click "Run workflow"
3. Enter the version number (e.g., `1.0.0`)
4. Click "Run workflow"
To auto-publish instead of creating a draft:

This method is useful for testing the workflow or creating builds without creating a tag.

## Workflow Overview

The release workflow (`.github/workflows/release-desktop.yml`) performs the following:

### Build Platform

Builds are created for:
- **macOS**: arm64 (Apple Silicon) - produces `.dmg` and `.zip`
```bash
./apps/desktop/create-release.sh desktop-v0.0.1 --publish
```

### Build Steps
To publish a draft:

1. Checkout code
2. Setup Bun
3. Install dependencies
4. Clean dev folder (`bun run clean:dev`)
5. Compile app with electron-vite (`bun run compile:app`)
6. Package with electron-builder (`bun run package`)
7. Upload artifacts
```bash
gh release edit desktop-v0.0.1 --draft=false
```

### Release Creation
### Requirements

After the build completes (tag-based releases only):
1. Downloads all artifacts
2. Creates a draft GitHub release
3. Attaches all binaries to the release
4. Generates release notes from commits
- GitHub CLI (`gh`) installed and authenticated
- Clean git working directory

## Code Signing (Optional)
## Manual Release

To enable macOS code signing, add the following secrets to your GitHub repository:
If you prefer not to use the script:

```yaml
CSC_LINK: ${{ secrets.MAC_CERTIFICATE }}
CSC_KEY_PASSWORD: ${{ secrets.MAC_CERTIFICATE_PASSWORD }}
APPLEID: ${{ secrets.APPLE_ID }}
APPLEIDPASS: ${{ secrets.APPLE_ID_PASSWORD }}
```bash
git tag desktop-v1.0.0
git push origin desktop-v1.0.0
```

Then uncomment the environment variables in the workflow under "Build Electron app".

## Publishing the Release
This creates a draft release. Publish it manually at GitHub Releases.

1. After the workflow completes, go to GitHub Releases
2. Find the draft release
3. Review the release notes and binaries
4. Edit the release description if needed
5. Click "Publish release" to make it public
## Auto-update

## Build Outputs
The app checks for updates at launch and every x hours using:

### macOS (arm64)
- `Superset-<version>-arm64.dmg` - DMG installer
- `Superset-<version>-arm64-mac.zip` - Zipped app bundle

## Troubleshooting
- **Manifest**: `https://github.com/superset-sh/superset/releases/latest/download/latest-mac.yml`
- **Installer**: `https://github.com/superset-sh/superset/releases/latest/download/Superset-arm64.dmg`

### Build fails on macOS
The workflow creates stable-named copies (without version) so these URLs always point to the latest build.
Comment on lines +46 to +53
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

rg -n 'UPDATE_CHECK_INTERVAL_MS' apps/desktop/src/main/lib/auto-updater.ts -A 2 -B 2

Repository: superset-sh/superset

Length of output: 407


Correct auto-update interval documentation from 6 hours to 1 hour.

Line 48 states the app checks for updates "every 6 hours," but the implementation in apps/desktop/src/main/lib/auto-updater.ts uses UPDATE_CHECK_INTERVAL_MS = 1000 * 60 * 60 * 1 which equals 1 hour. Update the documentation to reflect the actual interval.

🤖 Prompt for AI Agents
In apps/desktop/RELEASE.md around lines 46 to 53, the documentation wrongly
states the app checks for updates "every 6 hours" while the actual
implementation uses a 1-hour interval; update the sentence to read "every 1
hour" (or "every hour") and ensure any adjacent wording or bullet points reflect
the 1-hour interval to match UPDATE_CHECK_INTERVAL_MS in
apps/desktop/src/main/lib/auto-updater.ts.


- Ensure you're building for the correct architecture (arm64 is configured by default)
- Check that icon files exist at `src/resources/build/icons/icon.icns`
- Verify that dependencies are properly installed
## Code Signing

### Native module errors
macOS code signing uses these repository secrets:

- `node-pty` is configured as a native module in both `electron.vite.config.ts` and `electron-builder.ts`
- It's externalized during build and unpacked from ASAR
- If you add more native modules, update both configuration files

### Missing icons error

- The macOS build requires `icon.icns` in `src/resources/build/icons/`
- Ensure this file is committed to the repository
- `MAC_CERTIFICATE` / `MAC_CERTIFICATE_PASSWORD`
- `APPLE_ID` / `APPLE_ID_PASSWORD` / `APPLE_TEAM_ID`

## Local Testing

To test the build locally before releasing:

```bash
cd apps/desktop

# Clean and compile
bun run clean:dev
bun run compile:app

# Package the app
bun run package
```

The output will be in `apps/desktop/release/`.

## Building for Intel Macs (x64)

To also build for Intel Macs, update `electron-builder.ts`:

```typescript
mac: {
target: [
{
target: "default",
arch: ["arm64", "x64"], // Add x64 for Intel Macs
},
],
}
```

Note: This will increase build time significantly.
Output: `apps/desktop/release/`

## Adding Windows/Linux Builds

Currently only macOS builds are supported in CI/CD. To add Windows or Linux:
## Troubleshooting

1. Add PNG icon files to `src/resources/build/icons/` (for Linux)
2. Update the workflow matrix in `.github/workflows/release-desktop.yml`
3. Update `electron-builder.ts` configuration as needed
- **Build fails**: Check `src/resources/build/icons/icon.icns` exists
- **Native module errors**: Ensure `node-pty` is in externals in both `electron.vite.config.ts` and `electron-builder.ts`
85 changes: 61 additions & 24 deletions apps/desktop/create-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,22 @@
# Based on apps/desktop/RELEASE.md
#
# Usage:
# ./create-release.sh <version>
# ./create-release.sh <version> [--publish]
# Example: ./create-release.sh 0.0.1
# Example: ./create-release.sh 0.0.1 --publish
#
# This script will:
# 1. Verify prerequisites (clean git, GitHub CLI authenticated)
# 2. Delete existing release/tag if republishing same version
# 3. Update package.json version
# 4. Create and push a git tag to trigger the release workflow
# 5. Monitor the GitHub Actions workflow in real-time
# 6. Auto-publish the release when build completes
# 6. Leave release as draft (default) or auto-publish with --publish flag
#
# Features:
# - Supports republishing: Running with same version will clean up and rebuild
# - Auto-publishes release (no manual publish step needed)
# - Draft by default for review before publishing
# - Use --publish flag to auto-publish when build completes
#
# Requirements:
# - GitHub CLI (gh) installed and authenticated
Expand Down Expand Up @@ -51,12 +53,32 @@ error() {
exit 1
}

# Check if version argument is provided
if [ -z "$1" ]; then
error "Usage: $0 <version>\nExample: $0 0.0.1"
# Parse arguments
VERSION=""
AUTO_PUBLISH=false

for arg in "$@"; do
case $arg in
--publish)
AUTO_PUBLISH=true
;;
-*)
error "Unknown option: $arg\nUsage: $0 <version> [--publish]"
;;
*)
if [ -z "$VERSION" ]; then
VERSION="$arg"
else
error "Unexpected argument: $arg\nUsage: $0 <version> [--publish]"
fi
;;
esac
done

if [ -z "$VERSION" ]; then
error "Usage: $0 <version> [--publish]\nExample: $0 0.0.1"
fi

VERSION="$1"
TAG_NAME="desktop-v${VERSION}"
DESKTOP_DIR="apps/desktop"

Expand Down Expand Up @@ -251,23 +273,38 @@ if [ -z "$RELEASE_FOUND" ]; then
warn "Release not found yet. It may still be processing."
echo " Check releases at: https://github.com/${REPO}/releases"
else
# Publish the release
info "Publishing release..."
gh release edit "${TAG_NAME}" --draft=false
success "Release published!"

RELEASE_URL="https://github.com/${REPO}/releases/tag/${TAG_NAME}"
LATEST_URL="https://github.com/${REPO}/releases/latest"
echo ""
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN}🎉 Release Published!${NC}"
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo -e "${BLUE}Release URL:${NC} ${RELEASE_URL}"
echo -e "${BLUE}Latest URL:${NC} ${LATEST_URL}"
echo ""
echo -e "${BLUE}Direct downloads:${NC}"
echo " • ${LATEST_URL}/download/Superset-${VERSION}-arm64.dmg"
echo " • ${LATEST_URL}/download/Superset-${VERSION}-arm64-mac.zip"
echo ""

if [ "$AUTO_PUBLISH" = true ]; then
# Publish the release
info "Publishing release..."
gh release edit "${TAG_NAME}" --draft=false
success "Release published!"

echo ""
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN}🎉 Release Published!${NC}"
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo -e "${BLUE}Release URL:${NC} ${RELEASE_URL}"
echo -e "${BLUE}Latest URL:${NC} ${LATEST_URL}"
echo ""
echo -e "${BLUE}Direct download:${NC}"
echo " • ${LATEST_URL}/download/Superset-arm64.dmg"
echo ""
else
success "Draft release created!"

echo ""
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN}📝 Draft Release Ready for Review${NC}"
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo -e "${BLUE}Review URL:${NC} ${RELEASE_URL}"
echo ""
echo "To publish:"
echo " gh release edit ${TAG_NAME} --draft=false"
echo ""
fi
fi
8 changes: 6 additions & 2 deletions apps/desktop/electron-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ const config: Configuration = {
copyright: `Copyright © ${currentYear} — ${author}`,
electronVersion: pkg.devDependencies.electron.replace(/^\^/, ""),

// Disable auto-publish - handled by separate workflow step
publish: null,
// Generate latest-mac.yml for auto-update (workflow handles actual upload)
publish: {
provider: "github",
owner: "superset-sh",
repo: "superset",
},

// Directories
directories: {
Expand Down
1 change: 1 addition & 0 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"dotenv": "^17.2.3",
"electron-router-dom": "^2.1.0",
"electron-store": "^11.0.2",
"electron-updater": "6",
"execa": "^9.6.0",
"express": "^5.1.0",
"fast-glob": "^3.3.3",
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import path from "node:path";
import { app } from "electron";
import { makeAppSetup } from "lib/electron-app/factories/app/setup";
import { setupAgentHooks } from "./lib/agent-setup";
import { setupAutoUpdater } from "./lib/auto-updater";
import { initDb } from "./lib/db";
import { registerStorageHandlers } from "./lib/storage-ipcs";
import { terminalManager } from "./lib/terminal-manager";
Expand Down Expand Up @@ -43,6 +44,7 @@ registerStorageHandlers();
}

await makeAppSetup(() => MainWindow());
setupAutoUpdater();

// Clean up all terminals when app is quitting
app.on("before-quit", async () => {
Expand Down
Loading
Loading